OSDN Git Service

PR target/11089
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GNU CC.
9 ;;
10 ;; GNU CC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GNU CC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU CC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.  */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro #define NOTICE_UPDATE_CC in file i386.h handles condition code
31 ;; updates for most instructions.
32 ;;
33 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
34 ;; constraint letters.
35 ;;
36 ;; The special asm out single letter directives following a '%' are:
37 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
38 ;;     operands[1].
39 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
40 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
41 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
42 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
43 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
44 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
45 ;; 'J' Print the appropriate jump operand.
46 ;;
47 ;; 'b' Print the QImode name of the register for the indicated operand.
48 ;;     %b0 would print %al if operands[0] is reg 0.
49 ;; 'w' Likewise, print the HImode name of the register.
50 ;; 'k' Likewise, print the SImode name of the register.
51 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; 'y' Print "st(0)" instead of "st" as a register.
53
54 ;; UNSPEC usage:
55
56 (define_constants
57   [; Relocation specifiers
58    (UNSPEC_GOT                  0)
59    (UNSPEC_GOTOFF               1)
60    (UNSPEC_GOTPCREL             2)
61    (UNSPEC_GOTTPOFF             3)
62    (UNSPEC_TPOFF                4)
63    (UNSPEC_NTPOFF               5)
64    (UNSPEC_DTPOFF               6)
65    (UNSPEC_GOTNTPOFF            7)
66    (UNSPEC_INDNTPOFF            8)
67
68    ; Prologue support
69    (UNSPEC_STACK_PROBE          10)
70    (UNSPEC_STACK_ALLOC          11)
71    (UNSPEC_SET_GOT              12)
72    (UNSPEC_SSE_PROLOGUE_SAVE    13)
73
74    ; TLS support
75    (UNSPEC_TP                   15)
76    (UNSPEC_TLS_GD               16)
77    (UNSPEC_TLS_LD_BASE          17)
78
79    ; Other random patterns
80    (UNSPEC_SCAS                 20)
81    (UNSPEC_SIN                  21)
82    (UNSPEC_COS                  22)
83    (UNSPEC_FNSTSW               24)
84    (UNSPEC_SAHF                 25)
85    (UNSPEC_FSTCW                26)
86    (UNSPEC_ADD_CARRY            27)
87    (UNSPEC_FLDCW                28)
88
89    ; For SSE/MMX support:
90    (UNSPEC_FIX                  30)
91    (UNSPEC_MASKMOV              32)
92    (UNSPEC_MOVMSK               33)
93    (UNSPEC_MOVNT                34)
94    (UNSPEC_MOVA                 38)
95    (UNSPEC_MOVU                 39)
96    (UNSPEC_SHUFFLE              41)
97    (UNSPEC_RCP                  42)
98    (UNSPEC_RSQRT                43)
99    (UNSPEC_SFENCE               44)
100    (UNSPEC_NOP                  45)     ; prevents combiner cleverness
101    (UNSPEC_PAVGUSB              49)
102    (UNSPEC_PFRCP                50)
103    (UNSPEC_PFRCPIT1             51)
104    (UNSPEC_PFRCPIT2             52)
105    (UNSPEC_PFRSQRT              53)
106    (UNSPEC_PFRSQIT1             54)
107    (UNSPEC_PSHUFLW              55)
108    (UNSPEC_PSHUFHW              56)
109    (UNSPEC_MFENCE               59)
110    (UNSPEC_LFENCE               60)
111    (UNSPEC_PSADBW               61)
112
113    ; x87 Floating point
114    (UNSPEC_FPATAN               65)
115    (UNSPEC_FYL2X                66)
116
117    ; REP instruction
118    (UNSPEC_REP                  67)
119   ])
120
121 (define_constants
122   [(UNSPECV_BLOCKAGE            0)
123    (UNSPECV_EH_RETURN           13)
124    (UNSPECV_EMMS                31)
125    (UNSPECV_LDMXCSR             37)
126    (UNSPECV_STMXCSR             40)
127    (UNSPECV_FEMMS               46)
128    (UNSPECV_CLFLUSH             57)
129    (UNSPECV_ALIGN               68)
130   ])
131
132 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
133 ;; from i386.c.
134
135 ;; In C guard expressions, put expressions which may be compile-time
136 ;; constants first.  This allows for better optimization.  For
137 ;; example, write "TARGET_64BIT && reload_completed", not
138 ;; "reload_completed && TARGET_64BIT".
139
140 \f
141 ;; Processor type.  This attribute must exactly match the processor_type
142 ;; enumeration in i386.h.
143 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8"
144   (const (symbol_ref "ix86_tune")))
145
146 ;; A basic instruction type.  Refinements due to arguments to be
147 ;; provided in other attributes.
148 (define_attr "type"
149   "other,multi,
150    alu,alu1,negnot,imov,imovx,lea,
151    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
152    icmp,test,ibr,setcc,icmov,
153    push,pop,call,callv,leave,
154    str,cld,
155    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,
156    sselog,sseiadd,sseishft,sseimul,
157    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
158    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
159   (const_string "other"))
160
161 ;; Main data type used by the insn
162 (define_attr "mode"
163   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF"
164   (const_string "unknown"))
165
166 ;; The CPU unit operations uses.
167 (define_attr "unit" "integer,i387,sse,mmx,unknown"
168   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
169            (const_string "i387")
170          (eq_attr "type" "sselog,sseiadd,sseishft,sseimul,
171                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
172            (const_string "sse")
173          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
174            (const_string "mmx")
175          (eq_attr "type" "other")
176            (const_string "unknown")]
177          (const_string "integer")))
178
179 ;; The (bounding maximum) length of an instruction immediate.
180 (define_attr "length_immediate" ""
181   (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
182            (const_int 0)
183          (eq_attr "unit" "i387,sse,mmx")
184            (const_int 0)
185          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
186                           imul,icmp,push,pop")
187            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
188          (eq_attr "type" "imov,test")
189            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
190          (eq_attr "type" "call")
191            (if_then_else (match_operand 0 "constant_call_address_operand" "")
192              (const_int 4)
193              (const_int 0))
194          (eq_attr "type" "callv")
195            (if_then_else (match_operand 1 "constant_call_address_operand" "")
196              (const_int 4)
197              (const_int 0))
198          ;; We don't know the size before shorten_branches.  Expect
199          ;; the instruction to fit for better scheduling.
200          (eq_attr "type" "ibr")
201            (const_int 1)
202          ]
203          (symbol_ref "/* Update immediate_length and other attributes! */
204                       abort(),1")))
205
206 ;; The (bounding maximum) length of an instruction address.
207 (define_attr "length_address" ""
208   (cond [(eq_attr "type" "str,cld,other,multi,fxch")
209            (const_int 0)
210          (and (eq_attr "type" "call")
211               (match_operand 0 "constant_call_address_operand" ""))
212              (const_int 0)
213          (and (eq_attr "type" "callv")
214               (match_operand 1 "constant_call_address_operand" ""))
215              (const_int 0)
216          ]
217          (symbol_ref "ix86_attr_length_address_default (insn)")))
218
219 ;; Set when length prefix is used.
220 (define_attr "prefix_data16" ""
221   (if_then_else (ior (eq_attr "mode" "HI")
222                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
223     (const_int 1)
224     (const_int 0)))
225
226 ;; Set when string REP prefix is used.
227 (define_attr "prefix_rep" "" 
228   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
229     (const_int 1)
230     (const_int 0)))
231
232 ;; Set when 0f opcode prefix is used.
233 (define_attr "prefix_0f" ""
234   (if_then_else 
235     (ior (eq_attr "type" "imovx,setcc,icmov")
236          (eq_attr "unit" "sse,mmx"))
237     (const_int 1)
238     (const_int 0)))
239
240 ;; Set when 0f opcode prefix is used.
241 (define_attr "prefix_rex" ""
242   (cond [(and (eq_attr "mode" "DI")
243               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
244            (const_int 1)
245          (and (eq_attr "mode" "QI")
246               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
247                   (const_int 0)))
248            (const_int 1)
249          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
250              (const_int 0))
251            (const_int 1)
252         ]
253         (const_int 0)))
254
255 ;; Set when modrm byte is used.
256 (define_attr "modrm" ""
257   (cond [(eq_attr "type" "str,cld,leave")
258            (const_int 0)
259          (eq_attr "unit" "i387")
260            (const_int 0)
261          (and (eq_attr "type" "incdec")
262               (ior (match_operand:SI 1 "register_operand" "")
263                    (match_operand:HI 1 "register_operand" "")))
264            (const_int 0)
265          (and (eq_attr "type" "push")
266               (not (match_operand 1 "memory_operand" "")))
267            (const_int 0)
268          (and (eq_attr "type" "pop")
269               (not (match_operand 0 "memory_operand" "")))
270            (const_int 0)
271          (and (eq_attr "type" "imov")
272               (and (match_operand 0 "register_operand" "")
273                    (match_operand 1 "immediate_operand" "")))
274            (const_int 0)
275          (and (eq_attr "type" "call")
276               (match_operand 0 "constant_call_address_operand" ""))
277              (const_int 0)
278          (and (eq_attr "type" "callv")
279               (match_operand 1 "constant_call_address_operand" ""))
280              (const_int 0)
281          ]
282          (const_int 1)))
283
284 ;; The (bounding maximum) length of an instruction in bytes.
285 ;; ??? fistp is in fact fldcw/fistp/fldcw sequence.  Later we may want
286 ;; to split it and compute proper length as for other insns.
287 (define_attr "length" ""
288   (cond [(eq_attr "type" "other,multi,fistp")
289            (const_int 16)
290          (eq_attr "type" "fcmp")
291            (const_int 4)
292          (eq_attr "unit" "i387")
293            (plus (const_int 2)
294                  (plus (attr "prefix_data16")
295                        (attr "length_address")))]
296          (plus (plus (attr "modrm")
297                      (plus (attr "prefix_0f")
298                            (plus (attr "prefix_rex")
299                                  (const_int 1))))
300                (plus (attr "prefix_rep")
301                      (plus (attr "prefix_data16")
302                            (plus (attr "length_immediate")
303                                  (attr "length_address")))))))
304
305 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
306 ;; `store' if there is a simple memory reference therein, or `unknown'
307 ;; if the instruction is complex.
308
309 (define_attr "memory" "none,load,store,both,unknown"
310   (cond [(eq_attr "type" "other,multi,str")
311            (const_string "unknown")
312          (eq_attr "type" "lea,fcmov,fpspc,cld")
313            (const_string "none")
314          (eq_attr "type" "fistp,leave")
315            (const_string "both")
316          (eq_attr "type" "push")
317            (if_then_else (match_operand 1 "memory_operand" "")
318              (const_string "both")
319              (const_string "store"))
320          (eq_attr "type" "pop")
321            (if_then_else (match_operand 0 "memory_operand" "")
322              (const_string "both")
323              (const_string "load"))
324          (eq_attr "type" "setcc")
325            (if_then_else (match_operand 0 "memory_operand" "")
326              (const_string "store")
327              (const_string "none"))
328          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
329            (if_then_else (ior (match_operand 0 "memory_operand" "")
330                               (match_operand 1 "memory_operand" ""))
331              (const_string "load")
332              (const_string "none"))
333          (eq_attr "type" "ibr")
334            (if_then_else (match_operand 0 "memory_operand" "")
335              (const_string "load")
336              (const_string "none"))
337          (eq_attr "type" "call")
338            (if_then_else (match_operand 0 "constant_call_address_operand" "")
339              (const_string "none")
340              (const_string "load"))
341          (eq_attr "type" "callv")
342            (if_then_else (match_operand 1 "constant_call_address_operand" "")
343              (const_string "none")
344              (const_string "load"))
345          (and (eq_attr "type" "alu1,negnot")
346               (match_operand 1 "memory_operand" ""))
347            (const_string "both")
348          (and (match_operand 0 "memory_operand" "")
349               (match_operand 1 "memory_operand" ""))
350            (const_string "both")
351          (match_operand 0 "memory_operand" "")
352            (const_string "store")
353          (match_operand 1 "memory_operand" "")
354            (const_string "load")
355          (and (eq_attr "type"
356                  "!alu1,negnot,
357                    imov,imovx,icmp,test,
358                    fmov,fcmp,fsgn,
359                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,
360                    mmx,mmxmov,mmxcmp,mmxcvt")
361               (match_operand 2 "memory_operand" ""))
362            (const_string "load")
363          (and (eq_attr "type" "icmov")
364               (match_operand 3 "memory_operand" ""))
365            (const_string "load")
366         ]
367         (const_string "none")))
368
369 ;; Indicates if an instruction has both an immediate and a displacement.
370
371 (define_attr "imm_disp" "false,true,unknown"
372   (cond [(eq_attr "type" "other,multi")
373            (const_string "unknown")
374          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
375               (and (match_operand 0 "memory_displacement_operand" "")
376                    (match_operand 1 "immediate_operand" "")))
377            (const_string "true")
378          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
379               (and (match_operand 0 "memory_displacement_operand" "")
380                    (match_operand 2 "immediate_operand" "")))
381            (const_string "true")
382         ]
383         (const_string "false")))
384
385 ;; Indicates if an FP operation has an integer source.
386
387 (define_attr "fp_int_src" "false,true"
388   (const_string "false"))
389
390 ;; Describe a user's asm statement.
391 (define_asm_attributes
392   [(set_attr "length" "128")
393    (set_attr "type" "multi")])
394 \f
395 (include "pentium.md")
396 (include "ppro.md")
397 (include "k6.md")
398 (include "athlon.md")
399 \f
400 ;; Compare instructions.
401
402 ;; All compare insns have expanders that save the operands away without
403 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
404 ;; after the cmp) will actually emit the cmpM.
405
406 (define_expand "cmpdi"
407   [(set (reg:CC 17)
408         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
409                     (match_operand:DI 1 "x86_64_general_operand" "")))]
410   ""
411 {
412   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
413     operands[0] = force_reg (DImode, operands[0]);
414   ix86_compare_op0 = operands[0];
415   ix86_compare_op1 = operands[1];
416   DONE;
417 })
418
419 (define_expand "cmpsi"
420   [(set (reg:CC 17)
421         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
422                     (match_operand:SI 1 "general_operand" "")))]
423   ""
424 {
425   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
426     operands[0] = force_reg (SImode, operands[0]);
427   ix86_compare_op0 = operands[0];
428   ix86_compare_op1 = operands[1];
429   DONE;
430 })
431
432 (define_expand "cmphi"
433   [(set (reg:CC 17)
434         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
435                     (match_operand:HI 1 "general_operand" "")))]
436   ""
437 {
438   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
439     operands[0] = force_reg (HImode, operands[0]);
440   ix86_compare_op0 = operands[0];
441   ix86_compare_op1 = operands[1];
442   DONE;
443 })
444
445 (define_expand "cmpqi"
446   [(set (reg:CC 17)
447         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
448                     (match_operand:QI 1 "general_operand" "")))]
449   "TARGET_QIMODE_MATH"
450 {
451   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
452     operands[0] = force_reg (QImode, operands[0]);
453   ix86_compare_op0 = operands[0];
454   ix86_compare_op1 = operands[1];
455   DONE;
456 })
457
458 (define_insn "cmpdi_ccno_1_rex64"
459   [(set (reg 17)
460         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
461                  (match_operand:DI 1 "const0_operand" "n,n")))]
462   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
463   "@
464    test{q}\t{%0, %0|%0, %0}
465    cmp{q}\t{%1, %0|%0, %1}"
466   [(set_attr "type" "test,icmp")
467    (set_attr "length_immediate" "0,1")
468    (set_attr "mode" "DI")])
469
470 (define_insn "*cmpdi_minus_1_rex64"
471   [(set (reg 17)
472         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
473                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
474                  (const_int 0)))]
475   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
476   "cmp{q}\t{%1, %0|%0, %1}"
477   [(set_attr "type" "icmp")
478    (set_attr "mode" "DI")])
479
480 (define_expand "cmpdi_1_rex64"
481   [(set (reg:CC 17)
482         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
483                     (match_operand:DI 1 "general_operand" "")))]
484   "TARGET_64BIT"
485   "")
486
487 (define_insn "cmpdi_1_insn_rex64"
488   [(set (reg 17)
489         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
490                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
491   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
492   "cmp{q}\t{%1, %0|%0, %1}"
493   [(set_attr "type" "icmp")
494    (set_attr "mode" "DI")])
495
496
497 (define_insn "*cmpsi_ccno_1"
498   [(set (reg 17)
499         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
500                  (match_operand:SI 1 "const0_operand" "n,n")))]
501   "ix86_match_ccmode (insn, CCNOmode)"
502   "@
503    test{l}\t{%0, %0|%0, %0}
504    cmp{l}\t{%1, %0|%0, %1}"
505   [(set_attr "type" "test,icmp")
506    (set_attr "length_immediate" "0,1")
507    (set_attr "mode" "SI")])
508
509 (define_insn "*cmpsi_minus_1"
510   [(set (reg 17)
511         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
512                            (match_operand:SI 1 "general_operand" "ri,mr"))
513                  (const_int 0)))]
514   "ix86_match_ccmode (insn, CCGOCmode)"
515   "cmp{l}\t{%1, %0|%0, %1}"
516   [(set_attr "type" "icmp")
517    (set_attr "mode" "SI")])
518
519 (define_expand "cmpsi_1"
520   [(set (reg:CC 17)
521         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
522                     (match_operand:SI 1 "general_operand" "ri,mr")))]
523   ""
524   "")
525
526 (define_insn "*cmpsi_1_insn"
527   [(set (reg 17)
528         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
529                  (match_operand:SI 1 "general_operand" "ri,mr")))]
530   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
531     && ix86_match_ccmode (insn, CCmode)"
532   "cmp{l}\t{%1, %0|%0, %1}"
533   [(set_attr "type" "icmp")
534    (set_attr "mode" "SI")])
535
536 (define_insn "*cmphi_ccno_1"
537   [(set (reg 17)
538         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
539                  (match_operand:HI 1 "const0_operand" "n,n")))]
540   "ix86_match_ccmode (insn, CCNOmode)"
541   "@
542    test{w}\t{%0, %0|%0, %0}
543    cmp{w}\t{%1, %0|%0, %1}"
544   [(set_attr "type" "test,icmp")
545    (set_attr "length_immediate" "0,1")
546    (set_attr "mode" "HI")])
547
548 (define_insn "*cmphi_minus_1"
549   [(set (reg 17)
550         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
551                            (match_operand:HI 1 "general_operand" "ri,mr"))
552                  (const_int 0)))]
553   "ix86_match_ccmode (insn, CCGOCmode)"
554   "cmp{w}\t{%1, %0|%0, %1}"
555   [(set_attr "type" "icmp")
556    (set_attr "mode" "HI")])
557
558 (define_insn "*cmphi_1"
559   [(set (reg 17)
560         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
561                  (match_operand:HI 1 "general_operand" "ri,mr")))]
562   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
563    && ix86_match_ccmode (insn, CCmode)"
564   "cmp{w}\t{%1, %0|%0, %1}"
565   [(set_attr "type" "icmp")
566    (set_attr "mode" "HI")])
567
568 (define_insn "*cmpqi_ccno_1"
569   [(set (reg 17)
570         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
571                  (match_operand:QI 1 "const0_operand" "n,n")))]
572   "ix86_match_ccmode (insn, CCNOmode)"
573   "@
574    test{b}\t{%0, %0|%0, %0}
575    cmp{b}\t{$0, %0|%0, 0}"
576   [(set_attr "type" "test,icmp")
577    (set_attr "length_immediate" "0,1")
578    (set_attr "mode" "QI")])
579
580 (define_insn "*cmpqi_1"
581   [(set (reg 17)
582         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
583                  (match_operand:QI 1 "general_operand" "qi,mq")))]
584   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
585     && ix86_match_ccmode (insn, CCmode)"
586   "cmp{b}\t{%1, %0|%0, %1}"
587   [(set_attr "type" "icmp")
588    (set_attr "mode" "QI")])
589
590 (define_insn "*cmpqi_minus_1"
591   [(set (reg 17)
592         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
593                            (match_operand:QI 1 "general_operand" "qi,mq"))
594                  (const_int 0)))]
595   "ix86_match_ccmode (insn, CCGOCmode)"
596   "cmp{b}\t{%1, %0|%0, %1}"
597   [(set_attr "type" "icmp")
598    (set_attr "mode" "QI")])
599
600 (define_insn "*cmpqi_ext_1"
601   [(set (reg 17)
602         (compare
603           (match_operand:QI 0 "general_operand" "Qm")
604           (subreg:QI
605             (zero_extract:SI
606               (match_operand 1 "ext_register_operand" "Q")
607               (const_int 8)
608               (const_int 8)) 0)))]
609   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
610   "cmp{b}\t{%h1, %0|%0, %h1}"
611   [(set_attr "type" "icmp")
612    (set_attr "mode" "QI")])
613
614 (define_insn "*cmpqi_ext_1_rex64"
615   [(set (reg 17)
616         (compare
617           (match_operand:QI 0 "register_operand" "Q")
618           (subreg:QI
619             (zero_extract:SI
620               (match_operand 1 "ext_register_operand" "Q")
621               (const_int 8)
622               (const_int 8)) 0)))]
623   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
624   "cmp{b}\t{%h1, %0|%0, %h1}"
625   [(set_attr "type" "icmp")
626    (set_attr "mode" "QI")])
627
628 (define_insn "*cmpqi_ext_2"
629   [(set (reg 17)
630         (compare
631           (subreg:QI
632             (zero_extract:SI
633               (match_operand 0 "ext_register_operand" "Q")
634               (const_int 8)
635               (const_int 8)) 0)
636           (match_operand:QI 1 "const0_operand" "n")))]
637   "ix86_match_ccmode (insn, CCNOmode)"
638   "test{b}\t%h0, %h0"
639   [(set_attr "type" "test")
640    (set_attr "length_immediate" "0")
641    (set_attr "mode" "QI")])
642
643 (define_expand "cmpqi_ext_3"
644   [(set (reg:CC 17)
645         (compare:CC
646           (subreg:QI
647             (zero_extract:SI
648               (match_operand 0 "ext_register_operand" "")
649               (const_int 8)
650               (const_int 8)) 0)
651           (match_operand:QI 1 "general_operand" "")))]
652   ""
653   "")
654
655 (define_insn "cmpqi_ext_3_insn"
656   [(set (reg 17)
657         (compare
658           (subreg:QI
659             (zero_extract:SI
660               (match_operand 0 "ext_register_operand" "Q")
661               (const_int 8)
662               (const_int 8)) 0)
663           (match_operand:QI 1 "general_operand" "Qmn")))]
664   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
665   "cmp{b}\t{%1, %h0|%h0, %1}"
666   [(set_attr "type" "icmp")
667    (set_attr "mode" "QI")])
668
669 (define_insn "cmpqi_ext_3_insn_rex64"
670   [(set (reg 17)
671         (compare
672           (subreg:QI
673             (zero_extract:SI
674               (match_operand 0 "ext_register_operand" "Q")
675               (const_int 8)
676               (const_int 8)) 0)
677           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
678   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
679   "cmp{b}\t{%1, %h0|%h0, %1}"
680   [(set_attr "type" "icmp")
681    (set_attr "mode" "QI")])
682
683 (define_insn "*cmpqi_ext_4"
684   [(set (reg 17)
685         (compare
686           (subreg:QI
687             (zero_extract:SI
688               (match_operand 0 "ext_register_operand" "Q")
689               (const_int 8)
690               (const_int 8)) 0)
691           (subreg:QI
692             (zero_extract:SI
693               (match_operand 1 "ext_register_operand" "Q")
694               (const_int 8)
695               (const_int 8)) 0)))]
696   "ix86_match_ccmode (insn, CCmode)"
697   "cmp{b}\t{%h1, %h0|%h0, %h1}"
698   [(set_attr "type" "icmp")
699    (set_attr "mode" "QI")])
700
701 ;; These implement float point compares.
702 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
703 ;; which would allow mix and match FP modes on the compares.  Which is what
704 ;; the old patterns did, but with many more of them.
705
706 (define_expand "cmpxf"
707   [(set (reg:CC 17)
708         (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
709                     (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
710   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
711 {
712   ix86_compare_op0 = operands[0];
713   ix86_compare_op1 = operands[1];
714   DONE;
715 })
716
717 (define_expand "cmptf"
718   [(set (reg:CC 17)
719         (compare:CC (match_operand:TF 0 "cmp_fp_expander_operand" "")
720                     (match_operand:TF 1 "cmp_fp_expander_operand" "")))]
721   "TARGET_80387"
722 {
723   ix86_compare_op0 = operands[0];
724   ix86_compare_op1 = operands[1];
725   DONE;
726 })
727
728 (define_expand "cmpdf"
729   [(set (reg:CC 17)
730         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
731                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
732   "TARGET_80387 || TARGET_SSE2"
733 {
734   ix86_compare_op0 = operands[0];
735   ix86_compare_op1 = operands[1];
736   DONE;
737 })
738
739 (define_expand "cmpsf"
740   [(set (reg:CC 17)
741         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
742                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
743   "TARGET_80387 || TARGET_SSE"
744 {
745   ix86_compare_op0 = operands[0];
746   ix86_compare_op1 = operands[1];
747   DONE;
748 })
749
750 ;; FP compares, step 1:
751 ;; Set the FP condition codes.
752 ;;
753 ;; CCFPmode     compare with exceptions
754 ;; CCFPUmode    compare with no exceptions
755
756 ;; %%% It is an unfortunate fact that ftst has no non-popping variant,
757 ;; and that fp moves clobber the condition codes, and that there is
758 ;; currently no way to describe this fact to reg-stack.  So there are
759 ;; no splitters yet for this.
760
761 ;; %%% YIKES!  This scheme does not retain a strong connection between 
762 ;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
763 ;; work!  Only allow tos/mem with tos in op 0.
764 ;;
765 ;; Hmm, of course, this is what the actual _hardware_ does.  Perhaps
766 ;; things aren't as bad as they sound...
767
768 (define_insn "*cmpfp_0"
769   [(set (match_operand:HI 0 "register_operand" "=a")
770         (unspec:HI
771           [(compare:CCFP (match_operand 1 "register_operand" "f")
772                          (match_operand 2 "const0_operand" "X"))]
773           UNSPEC_FNSTSW))]
774   "TARGET_80387
775    && FLOAT_MODE_P (GET_MODE (operands[1]))
776    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
777 {
778   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
779     return "ftst\;fnstsw\t%0\;fstp\t%y0";
780   else
781     return "ftst\;fnstsw\t%0";
782 }
783   [(set_attr "type" "multi")
784    (set (attr "mode")
785      (cond [(match_operand:SF 1 "" "")
786               (const_string "SF")
787             (match_operand:DF 1 "" "")
788               (const_string "DF")
789            ]
790            (const_string "XF")))])
791
792 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
793 ;; used to manage the reg stack popping would not be preserved.
794
795 (define_insn "*cmpfp_2_sf"
796   [(set (reg:CCFP 18)
797         (compare:CCFP
798           (match_operand:SF 0 "register_operand" "f")
799           (match_operand:SF 1 "nonimmediate_operand" "fm")))]
800   "TARGET_80387"
801   "* return output_fp_compare (insn, operands, 0, 0);"
802   [(set_attr "type" "fcmp")
803    (set_attr "mode" "SF")])
804
805 (define_insn "*cmpfp_2_sf_1"
806   [(set (match_operand:HI 0 "register_operand" "=a")
807         (unspec:HI
808           [(compare:CCFP
809              (match_operand:SF 1 "register_operand" "f")
810              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
811           UNSPEC_FNSTSW))]
812   "TARGET_80387"
813   "* return output_fp_compare (insn, operands, 2, 0);"
814   [(set_attr "type" "fcmp")
815    (set_attr "mode" "SF")])
816
817 (define_insn "*cmpfp_2_df"
818   [(set (reg:CCFP 18)
819         (compare:CCFP
820           (match_operand:DF 0 "register_operand" "f")
821           (match_operand:DF 1 "nonimmediate_operand" "fm")))]
822   "TARGET_80387"
823   "* return output_fp_compare (insn, operands, 0, 0);"
824   [(set_attr "type" "fcmp")
825    (set_attr "mode" "DF")])
826
827 (define_insn "*cmpfp_2_df_1"
828   [(set (match_operand:HI 0 "register_operand" "=a")
829         (unspec:HI
830           [(compare:CCFP
831              (match_operand:DF 1 "register_operand" "f")
832              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
833           UNSPEC_FNSTSW))]
834   "TARGET_80387"
835   "* return output_fp_compare (insn, operands, 2, 0);"
836   [(set_attr "type" "multi")
837    (set_attr "mode" "DF")])
838
839 (define_insn "*cmpfp_2_xf"
840   [(set (reg:CCFP 18)
841         (compare:CCFP
842           (match_operand:XF 0 "register_operand" "f")
843           (match_operand:XF 1 "register_operand" "f")))]
844   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
845   "* return output_fp_compare (insn, operands, 0, 0);"
846   [(set_attr "type" "fcmp")
847    (set_attr "mode" "XF")])
848
849 (define_insn "*cmpfp_2_tf"
850   [(set (reg:CCFP 18)
851         (compare:CCFP
852           (match_operand:TF 0 "register_operand" "f")
853           (match_operand:TF 1 "register_operand" "f")))]
854   "TARGET_80387"
855   "* return output_fp_compare (insn, operands, 0, 0);"
856   [(set_attr "type" "fcmp")
857    (set_attr "mode" "XF")])
858
859 (define_insn "*cmpfp_2_xf_1"
860   [(set (match_operand:HI 0 "register_operand" "=a")
861         (unspec:HI
862           [(compare:CCFP
863              (match_operand:XF 1 "register_operand" "f")
864              (match_operand:XF 2 "register_operand" "f"))]
865           UNSPEC_FNSTSW))]
866   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
867   "* return output_fp_compare (insn, operands, 2, 0);"
868   [(set_attr "type" "multi")
869    (set_attr "mode" "XF")])
870
871 (define_insn "*cmpfp_2_tf_1"
872   [(set (match_operand:HI 0 "register_operand" "=a")
873         (unspec:HI
874           [(compare:CCFP
875              (match_operand:TF 1 "register_operand" "f")
876              (match_operand:TF 2 "register_operand" "f"))]
877           UNSPEC_FNSTSW))]
878   "TARGET_80387"
879   "* return output_fp_compare (insn, operands, 2, 0);"
880   [(set_attr "type" "multi")
881    (set_attr "mode" "XF")])
882
883 (define_insn "*cmpfp_2u"
884   [(set (reg:CCFPU 18)
885         (compare:CCFPU
886           (match_operand 0 "register_operand" "f")
887           (match_operand 1 "register_operand" "f")))]
888   "TARGET_80387
889    && FLOAT_MODE_P (GET_MODE (operands[0]))
890    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
891   "* return output_fp_compare (insn, operands, 0, 1);"
892   [(set_attr "type" "fcmp")
893    (set (attr "mode")
894      (cond [(match_operand:SF 1 "" "")
895               (const_string "SF")
896             (match_operand:DF 1 "" "")
897               (const_string "DF")
898            ]
899            (const_string "XF")))])
900
901 (define_insn "*cmpfp_2u_1"
902   [(set (match_operand:HI 0 "register_operand" "=a")
903         (unspec:HI
904           [(compare:CCFPU
905              (match_operand 1 "register_operand" "f")
906              (match_operand 2 "register_operand" "f"))]
907           UNSPEC_FNSTSW))]
908   "TARGET_80387
909    && FLOAT_MODE_P (GET_MODE (operands[1]))
910    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
911   "* return output_fp_compare (insn, operands, 2, 1);"
912   [(set_attr "type" "multi")
913    (set (attr "mode")
914      (cond [(match_operand:SF 1 "" "")
915               (const_string "SF")
916             (match_operand:DF 1 "" "")
917               (const_string "DF")
918            ]
919            (const_string "XF")))])
920
921 ;; Patterns to match the SImode-in-memory ficom instructions.
922 ;;
923 ;; %%% Play games with accepting gp registers, as otherwise we have to
924 ;; force them to memory during rtl generation, which is no good.  We
925 ;; can get rid of this once we teach reload to do memory input reloads 
926 ;; via pushes.
927
928 (define_insn "*ficom_1"
929   [(set (reg:CCFP 18)
930         (compare:CCFP
931           (match_operand 0 "register_operand" "f,f")
932           (float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
933   "0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
934    && GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
935   "#")
936
937 ;; Split the not-really-implemented gp register case into a
938 ;; push-op-pop sequence.
939 ;;
940 ;; %%% This is most efficient, but am I gonna get in trouble
941 ;; for separating cc0_setter and cc0_user?
942
943 (define_split
944   [(set (reg:CCFP 18)
945         (compare:CCFP
946           (match_operand:SF 0 "register_operand" "")
947           (float (match_operand:SI 1 "register_operand" ""))))]
948   "0 && TARGET_80387 && reload_completed"
949   [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 1))
950    (set (reg:CCFP 18) (compare:CCFP (match_dup 0) (match_dup 2)))
951    (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
952               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
953   "operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
954    operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
955
956 ;; FP compares, step 2
957 ;; Move the fpsw to ax.
958
959 (define_insn "*x86_fnstsw_1"
960   [(set (match_operand:HI 0 "register_operand" "=a")
961         (unspec:HI [(reg 18)] UNSPEC_FNSTSW))]
962   "TARGET_80387"
963   "fnstsw\t%0"
964   [(set_attr "length" "2")
965    (set_attr "mode" "SI")
966    (set_attr "unit" "i387")
967    (set_attr "ppro_uops" "few")])
968
969 ;; FP compares, step 3
970 ;; Get ax into flags, general case.
971
972 (define_insn "x86_sahf_1"
973   [(set (reg:CC 17)
974         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
975   "!TARGET_64BIT"
976   "sahf"
977   [(set_attr "length" "1")
978    (set_attr "athlon_decode" "vector")
979    (set_attr "mode" "SI")
980    (set_attr "ppro_uops" "one")])
981
982 ;; Pentium Pro can do steps 1 through 3 in one go.
983
984 (define_insn "*cmpfp_i"
985   [(set (reg:CCFP 17)
986         (compare:CCFP (match_operand 0 "register_operand" "f")
987                       (match_operand 1 "register_operand" "f")))]
988   "TARGET_80387 && TARGET_CMOVE
989    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
990    && FLOAT_MODE_P (GET_MODE (operands[0]))
991    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
992   "* return output_fp_compare (insn, operands, 1, 0);"
993   [(set_attr "type" "fcmp")
994    (set (attr "mode")
995      (cond [(match_operand:SF 1 "" "")
996               (const_string "SF")
997             (match_operand:DF 1 "" "")
998               (const_string "DF")
999            ]
1000            (const_string "XF")))
1001    (set_attr "athlon_decode" "vector")])
1002
1003 (define_insn "*cmpfp_i_sse"
1004   [(set (reg:CCFP 17)
1005         (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
1006                       (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1007   "TARGET_80387
1008    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1009    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1010   "* return output_fp_compare (insn, operands, 1, 0);"
1011   [(set_attr "type" "fcmp,ssecomi")
1012    (set (attr "mode")
1013      (if_then_else (match_operand:SF 1 "" "")
1014         (const_string "SF")
1015         (const_string "DF")))
1016    (set_attr "athlon_decode" "vector")])
1017
1018 (define_insn "*cmpfp_i_sse_only"
1019   [(set (reg:CCFP 17)
1020         (compare:CCFP (match_operand 0 "register_operand" "x")
1021                       (match_operand 1 "nonimmediate_operand" "xm")))]
1022   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1023    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
1024   "* return output_fp_compare (insn, operands, 1, 0);"
1025   [(set_attr "type" "ssecomi")
1026    (set (attr "mode")
1027      (if_then_else (match_operand:SF 1 "" "")
1028         (const_string "SF")
1029         (const_string "DF")))
1030    (set_attr "athlon_decode" "vector")])
1031
1032 (define_insn "*cmpfp_iu"
1033   [(set (reg:CCFPU 17)
1034         (compare:CCFPU (match_operand 0 "register_operand" "f")
1035                        (match_operand 1 "register_operand" "f")))]
1036   "TARGET_80387 && TARGET_CMOVE
1037    && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1038    && FLOAT_MODE_P (GET_MODE (operands[0]))
1039    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1040   "* return output_fp_compare (insn, operands, 1, 1);"
1041   [(set_attr "type" "fcmp")
1042    (set (attr "mode")
1043      (cond [(match_operand:SF 1 "" "")
1044               (const_string "SF")
1045             (match_operand:DF 1 "" "")
1046               (const_string "DF")
1047            ]
1048            (const_string "XF")))
1049    (set_attr "athlon_decode" "vector")])
1050
1051 (define_insn "*cmpfp_iu_sse"
1052   [(set (reg:CCFPU 17)
1053         (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
1054                        (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1055   "TARGET_80387
1056    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1057    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1058   "* return output_fp_compare (insn, operands, 1, 1);"
1059   [(set_attr "type" "fcmp,ssecomi")
1060    (set (attr "mode")
1061      (if_then_else (match_operand:SF 1 "" "")
1062         (const_string "SF")
1063         (const_string "DF")))
1064    (set_attr "athlon_decode" "vector")])
1065
1066 (define_insn "*cmpfp_iu_sse_only"
1067   [(set (reg:CCFPU 17)
1068         (compare:CCFPU (match_operand 0 "register_operand" "x")
1069                        (match_operand 1 "nonimmediate_operand" "xm")))]
1070   "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1071    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1072   "* return output_fp_compare (insn, operands, 1, 1);"
1073   [(set_attr "type" "ssecomi")
1074    (set (attr "mode")
1075      (if_then_else (match_operand:SF 1 "" "")
1076         (const_string "SF")
1077         (const_string "DF")))
1078    (set_attr "athlon_decode" "vector")])
1079 \f
1080 ;; Move instructions.
1081
1082 ;; General case of fullword move.
1083
1084 (define_expand "movsi"
1085   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1086         (match_operand:SI 1 "general_operand" ""))]
1087   ""
1088   "ix86_expand_move (SImode, operands); DONE;")
1089
1090 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1091 ;; general_operand.
1092 ;;
1093 ;; %%% We don't use a post-inc memory reference because x86 is not a 
1094 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1095 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1096 ;; targets without our curiosities, and it is just as easy to represent
1097 ;; this differently.
1098
1099 (define_insn "*pushsi2"
1100   [(set (match_operand:SI 0 "push_operand" "=<")
1101         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1102   "!TARGET_64BIT"
1103   "push{l}\t%1"
1104   [(set_attr "type" "push")
1105    (set_attr "mode" "SI")])
1106
1107 ;; For 64BIT abi we always round up to 8 bytes.
1108 (define_insn "*pushsi2_rex64"
1109   [(set (match_operand:SI 0 "push_operand" "=X")
1110         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1111   "TARGET_64BIT"
1112   "push{q}\t%q1"
1113   [(set_attr "type" "push")
1114    (set_attr "mode" "SI")])
1115
1116 (define_insn "*pushsi2_prologue"
1117   [(set (match_operand:SI 0 "push_operand" "=<")
1118         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1119    (clobber (mem:BLK (scratch)))]
1120   "!TARGET_64BIT"
1121   "push{l}\t%1"
1122   [(set_attr "type" "push")
1123    (set_attr "mode" "SI")])
1124
1125 (define_insn "*popsi1_epilogue"
1126   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1127         (mem:SI (reg:SI 7)))
1128    (set (reg:SI 7)
1129         (plus:SI (reg:SI 7) (const_int 4)))
1130    (clobber (mem:BLK (scratch)))]
1131   "!TARGET_64BIT"
1132   "pop{l}\t%0"
1133   [(set_attr "type" "pop")
1134    (set_attr "mode" "SI")])
1135
1136 (define_insn "popsi1"
1137   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1138         (mem:SI (reg:SI 7)))
1139    (set (reg:SI 7)
1140         (plus:SI (reg:SI 7) (const_int 4)))]
1141   "!TARGET_64BIT"
1142   "pop{l}\t%0"
1143   [(set_attr "type" "pop")
1144    (set_attr "mode" "SI")])
1145
1146 (define_insn "*movsi_xor"
1147   [(set (match_operand:SI 0 "register_operand" "=r")
1148         (match_operand:SI 1 "const0_operand" "i"))
1149    (clobber (reg:CC 17))]
1150   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1151   "xor{l}\t{%0, %0|%0, %0}"
1152   [(set_attr "type" "alu1")
1153    (set_attr "mode" "SI")
1154    (set_attr "length_immediate" "0")])
1155
1156 (define_insn "*movsi_or"
1157   [(set (match_operand:SI 0 "register_operand" "=r")
1158         (match_operand:SI 1 "immediate_operand" "i"))
1159    (clobber (reg:CC 17))]
1160   "reload_completed && GET_CODE (operands[1]) == CONST_INT
1161    && INTVAL (operands[1]) == -1
1162    && (TARGET_PENTIUM || optimize_size)"
1163 {
1164   operands[1] = constm1_rtx;
1165   return "or{l}\t{%1, %0|%0, %1}";
1166 }
1167   [(set_attr "type" "alu1")
1168    (set_attr "mode" "SI")
1169    (set_attr "length_immediate" "1")])
1170
1171 (define_insn "*movsi_1"
1172   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!rm,!*y,!*Y,!rm,!*Y")
1173         (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,rm,*Y,*Y,rm"))]
1174   "(TARGET_INTER_UNIT_MOVES || optimize_size)
1175    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1176 {
1177   switch (get_attr_type (insn))
1178     {
1179     case TYPE_SSEMOV:
1180       if (get_attr_mode (insn) == MODE_TI)
1181         return "movdqa\t{%1, %0|%0, %1}";
1182       return "movd\t{%1, %0|%0, %1}";
1183
1184     case TYPE_MMXMOV:
1185       if (get_attr_mode (insn) == MODE_DI)
1186         return "movq\t{%1, %0|%0, %1}";
1187       return "movd\t{%1, %0|%0, %1}";
1188
1189     case TYPE_LEA:
1190       return "lea{l}\t{%1, %0|%0, %1}";
1191
1192     default:
1193       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1194         abort();
1195       return "mov{l}\t{%1, %0|%0, %1}";
1196     }
1197 }
1198   [(set (attr "type")
1199      (cond [(eq_attr "alternative" "2,3,4")
1200               (const_string "mmxmov")
1201             (eq_attr "alternative" "5,6,7")
1202               (const_string "ssemov")
1203             (and (ne (symbol_ref "flag_pic") (const_int 0))
1204                  (match_operand:SI 1 "symbolic_operand" ""))
1205               (const_string "lea")
1206            ]
1207            (const_string "imov")))
1208    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1209
1210 (define_insn "*movsi_1_nointernunit"
1211   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m,!*y,!m,!*y,!*Y,!m,!*Y")
1212         (match_operand:SI 1 "general_operand" "rinm,rin,*y,*y,m,*Y,*Y,m"))]
1213   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
1214    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1215 {
1216   switch (get_attr_type (insn))
1217     {
1218     case TYPE_SSEMOV:
1219       if (get_attr_mode (insn) == MODE_TI)
1220         return "movdqa\t{%1, %0|%0, %1}";
1221       return "movd\t{%1, %0|%0, %1}";
1222
1223     case TYPE_MMXMOV:
1224       if (get_attr_mode (insn) == MODE_DI)
1225         return "movq\t{%1, %0|%0, %1}";
1226       return "movd\t{%1, %0|%0, %1}";
1227
1228     case TYPE_LEA:
1229       return "lea{l}\t{%1, %0|%0, %1}";
1230
1231     default:
1232       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1233         abort();
1234       return "mov{l}\t{%1, %0|%0, %1}";
1235     }
1236 }
1237   [(set (attr "type")
1238      (cond [(eq_attr "alternative" "2,3,4")
1239               (const_string "mmxmov")
1240             (eq_attr "alternative" "5,6,7")
1241               (const_string "ssemov")
1242             (and (ne (symbol_ref "flag_pic") (const_int 0))
1243                  (match_operand:SI 1 "symbolic_operand" ""))
1244               (const_string "lea")
1245            ]
1246            (const_string "imov")))
1247    (set_attr "mode" "SI,SI,DI,SI,SI,TI,SI,SI")])
1248
1249 ;; Stores and loads of ax to arbitrary constant address.
1250 ;; We fake an second form of instruction to force reload to load address
1251 ;; into register when rax is not available
1252 (define_insn "*movabssi_1_rex64"
1253   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1254         (match_operand:SI 1 "nonmemory_operand" "a,er,i"))]
1255   "TARGET_64BIT"
1256   "@
1257    movabs{l}\t{%1, %P0|%P0, %1}
1258    mov{l}\t{%1, %a0|%a0, %1}
1259    movabs{l}\t{%1, %a0|%a0, %1}"
1260   [(set_attr "type" "imov")
1261    (set_attr "modrm" "0,*,*")
1262    (set_attr "length_address" "8,0,0")
1263    (set_attr "length_immediate" "0,*,*")
1264    (set_attr "memory" "store")
1265    (set_attr "mode" "SI")])
1266
1267 (define_insn "*movabssi_2_rex64"
1268   [(set (match_operand:SI 0 "register_operand" "=a,r")
1269         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1270   "TARGET_64BIT"
1271   "@
1272    movabs{l}\t{%P1, %0|%0, %P1}
1273    mov{l}\t{%a1, %0|%0, %a1}"
1274   [(set_attr "type" "imov")
1275    (set_attr "modrm" "0,*")
1276    (set_attr "length_address" "8,0")
1277    (set_attr "length_immediate" "0")
1278    (set_attr "memory" "load")
1279    (set_attr "mode" "SI")])
1280
1281 (define_insn "*swapsi"
1282   [(set (match_operand:SI 0 "register_operand" "+r")
1283         (match_operand:SI 1 "register_operand" "+r"))
1284    (set (match_dup 1)
1285         (match_dup 0))]
1286   ""
1287   "xchg{l}\t%1, %0"
1288   [(set_attr "type" "imov")
1289    (set_attr "pent_pair" "np")
1290    (set_attr "athlon_decode" "vector")
1291    (set_attr "mode" "SI")
1292    (set_attr "modrm" "0")
1293    (set_attr "ppro_uops" "few")])
1294
1295 (define_expand "movhi"
1296   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1297         (match_operand:HI 1 "general_operand" ""))]
1298   ""
1299   "ix86_expand_move (HImode, operands); DONE;")
1300
1301 (define_insn "*pushhi2"
1302   [(set (match_operand:HI 0 "push_operand" "=<,<")
1303         (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1304   "!TARGET_64BIT"
1305   "@
1306    push{w}\t{|WORD PTR }%1
1307    push{w}\t%1"
1308   [(set_attr "type" "push")
1309    (set_attr "mode" "HI")])
1310
1311 ;; For 64BIT abi we always round up to 8 bytes.
1312 (define_insn "*pushhi2_rex64"
1313   [(set (match_operand:HI 0 "push_operand" "=X")
1314         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1315   "TARGET_64BIT"
1316   "push{q}\t%q1"
1317   [(set_attr "type" "push")
1318    (set_attr "mode" "QI")])
1319
1320 (define_insn "*movhi_1"
1321   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1322         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1323   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1324 {
1325   switch (get_attr_type (insn))
1326     {
1327     case TYPE_IMOVX:
1328       /* movzwl is faster than movw on p2 due to partial word stalls,
1329          though not as fast as an aligned movl.  */
1330       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1331     default:
1332       if (get_attr_mode (insn) == MODE_SI)
1333         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1334       else
1335         return "mov{w}\t{%1, %0|%0, %1}";
1336     }
1337 }
1338   [(set (attr "type")
1339      (cond [(and (eq_attr "alternative" "0")
1340                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1341                           (const_int 0))
1342                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1343                           (const_int 0))))
1344               (const_string "imov")
1345             (and (eq_attr "alternative" "1,2")
1346                  (match_operand:HI 1 "aligned_operand" ""))
1347               (const_string "imov")
1348             (and (ne (symbol_ref "TARGET_MOVX")
1349                      (const_int 0))
1350                  (eq_attr "alternative" "0,2"))
1351               (const_string "imovx")
1352            ]
1353            (const_string "imov")))
1354     (set (attr "mode")
1355       (cond [(eq_attr "type" "imovx")
1356                (const_string "SI")
1357              (and (eq_attr "alternative" "1,2")
1358                   (match_operand:HI 1 "aligned_operand" ""))
1359                (const_string "SI")
1360              (and (eq_attr "alternative" "0")
1361                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1362                            (const_int 0))
1363                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1364                            (const_int 0))))
1365                (const_string "SI")
1366             ]
1367             (const_string "HI")))])
1368
1369 ;; Stores and loads of ax to arbitrary constant address.
1370 ;; We fake an second form of instruction to force reload to load address
1371 ;; into register when rax is not available
1372 (define_insn "*movabshi_1_rex64"
1373   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1374         (match_operand:HI 1 "nonmemory_operand" "a,er,i"))]
1375   "TARGET_64BIT"
1376   "@
1377    movabs{w}\t{%1, %P0|%P0, %1}
1378    mov{w}\t{%1, %a0|%a0, %1}
1379    movabs{w}\t{%1, %a0|%a0, %1}"
1380   [(set_attr "type" "imov")
1381    (set_attr "modrm" "0,*,*")
1382    (set_attr "length_address" "8,0,0")
1383    (set_attr "length_immediate" "0,*,*")
1384    (set_attr "memory" "store")
1385    (set_attr "mode" "HI")])
1386
1387 (define_insn "*movabshi_2_rex64"
1388   [(set (match_operand:HI 0 "register_operand" "=a,r")
1389         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1390   "TARGET_64BIT"
1391   "@
1392    movabs{w}\t{%P1, %0|%0, %P1}
1393    mov{w}\t{%a1, %0|%0, %a1}"
1394   [(set_attr "type" "imov")
1395    (set_attr "modrm" "0,*")
1396    (set_attr "length_address" "8,0")
1397    (set_attr "length_immediate" "0")
1398    (set_attr "memory" "load")
1399    (set_attr "mode" "HI")])
1400
1401 (define_insn "*swaphi_1"
1402   [(set (match_operand:HI 0 "register_operand" "+r")
1403         (match_operand:HI 1 "register_operand" "+r"))
1404    (set (match_dup 1)
1405         (match_dup 0))]
1406   "TARGET_PARTIAL_REG_STALL"
1407   "xchg{w}\t%1, %0"
1408   [(set_attr "type" "imov")
1409    (set_attr "pent_pair" "np")
1410    (set_attr "mode" "HI")
1411    (set_attr "modrm" "0")
1412    (set_attr "ppro_uops" "few")])
1413
1414 (define_insn "*swaphi_2"
1415   [(set (match_operand:HI 0 "register_operand" "+r")
1416         (match_operand:HI 1 "register_operand" "+r"))
1417    (set (match_dup 1)
1418         (match_dup 0))]
1419   "! TARGET_PARTIAL_REG_STALL"
1420   "xchg{l}\t%k1, %k0"
1421   [(set_attr "type" "imov")
1422    (set_attr "pent_pair" "np")
1423    (set_attr "mode" "SI")
1424    (set_attr "modrm" "0")
1425    (set_attr "ppro_uops" "few")])
1426
1427 (define_expand "movstricthi"
1428   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1429         (match_operand:HI 1 "general_operand" ""))]
1430   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1431 {
1432   /* Don't generate memory->memory moves, go through a register */
1433   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1434     operands[1] = force_reg (HImode, operands[1]);
1435 })
1436
1437 (define_insn "*movstricthi_1"
1438   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1439         (match_operand:HI 1 "general_operand" "rn,m"))]
1440   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1441    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1442   "mov{w}\t{%1, %0|%0, %1}"
1443   [(set_attr "type" "imov")
1444    (set_attr "mode" "HI")])
1445
1446 (define_insn "*movstricthi_xor"
1447   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1448         (match_operand:HI 1 "const0_operand" "i"))
1449    (clobber (reg:CC 17))]
1450   "reload_completed
1451    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1452   "xor{w}\t{%0, %0|%0, %0}"
1453   [(set_attr "type" "alu1")
1454    (set_attr "mode" "HI")
1455    (set_attr "length_immediate" "0")])
1456
1457 (define_expand "movqi"
1458   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1459         (match_operand:QI 1 "general_operand" ""))]
1460   ""
1461   "ix86_expand_move (QImode, operands); DONE;")
1462
1463 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1464 ;; "push a byte".  But actually we use pushw, which has the effect
1465 ;; of rounding the amount pushed up to a halfword.
1466
1467 (define_insn "*pushqi2"
1468   [(set (match_operand:QI 0 "push_operand" "=X,X")
1469         (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1470   "!TARGET_64BIT"
1471   "@
1472    push{w}\t{|word ptr }%1
1473    push{w}\t%w1"
1474   [(set_attr "type" "push")
1475    (set_attr "mode" "HI")])
1476
1477 ;; For 64BIT abi we always round up to 8 bytes.
1478 (define_insn "*pushqi2_rex64"
1479   [(set (match_operand:QI 0 "push_operand" "=X")
1480         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1481   "TARGET_64BIT"
1482   "push{q}\t%q1"
1483   [(set_attr "type" "push")
1484    (set_attr "mode" "QI")])
1485
1486 ;; Situation is quite tricky about when to choose full sized (SImode) move
1487 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1488 ;; partial register dependency machines (such as AMD Athlon), where QImode
1489 ;; moves issue extra dependency and for partial register stalls machines
1490 ;; that don't use QImode patterns (and QImode move cause stall on the next
1491 ;; instruction).
1492 ;;
1493 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1494 ;; register stall machines with, where we use QImode instructions, since
1495 ;; partial register stall can be caused there.  Then we use movzx.
1496 (define_insn "*movqi_1"
1497   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1498         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1499   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1500 {
1501   switch (get_attr_type (insn))
1502     {
1503     case TYPE_IMOVX:
1504       if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1505         abort ();
1506       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1507     default:
1508       if (get_attr_mode (insn) == MODE_SI)
1509         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1510       else
1511         return "mov{b}\t{%1, %0|%0, %1}";
1512     }
1513 }
1514   [(set (attr "type")
1515      (cond [(and (eq_attr "alternative" "3")
1516                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1517                           (const_int 0))
1518                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1519                           (const_int 0))))
1520               (const_string "imov")
1521             (eq_attr "alternative" "3,5")
1522               (const_string "imovx")
1523             (and (ne (symbol_ref "TARGET_MOVX")
1524                      (const_int 0))
1525                  (eq_attr "alternative" "2"))
1526               (const_string "imovx")
1527            ]
1528            (const_string "imov")))
1529    (set (attr "mode")
1530       (cond [(eq_attr "alternative" "3,4,5")
1531                (const_string "SI")
1532              (eq_attr "alternative" "6")
1533                (const_string "QI")
1534              (eq_attr "type" "imovx")
1535                (const_string "SI")
1536              (and (eq_attr "type" "imov")
1537                   (and (eq_attr "alternative" "0,1,2")
1538                        (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1539                            (const_int 0))))
1540                (const_string "SI")
1541              ;; Avoid partial register stalls when not using QImode arithmetic
1542              (and (eq_attr "type" "imov")
1543                   (and (eq_attr "alternative" "0,1,2")
1544                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1545                                 (const_int 0))
1546                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1547                                 (const_int 0)))))
1548                (const_string "SI")
1549            ]
1550            (const_string "QI")))])
1551
1552 (define_expand "reload_outqi"
1553   [(parallel [(match_operand:QI 0 "" "=m")
1554               (match_operand:QI 1 "register_operand" "r")
1555               (match_operand:QI 2 "register_operand" "=&q")])]
1556   ""
1557 {
1558   rtx op0, op1, op2;
1559   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1560
1561   if (reg_overlap_mentioned_p (op2, op0))
1562     abort ();
1563   if (! q_regs_operand (op1, QImode))
1564     {
1565       emit_insn (gen_movqi (op2, op1));
1566       op1 = op2;
1567     }
1568   emit_insn (gen_movqi (op0, op1));
1569   DONE;
1570 })
1571
1572 (define_insn "*swapqi"
1573   [(set (match_operand:QI 0 "register_operand" "+r")
1574         (match_operand:QI 1 "register_operand" "+r"))
1575    (set (match_dup 1)
1576         (match_dup 0))]
1577   ""
1578   "xchg{b}\t%1, %0"
1579   [(set_attr "type" "imov")
1580    (set_attr "pent_pair" "np")
1581    (set_attr "mode" "QI")
1582    (set_attr "modrm" "0")
1583    (set_attr "ppro_uops" "few")])
1584
1585 (define_expand "movstrictqi"
1586   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1587         (match_operand:QI 1 "general_operand" ""))]
1588   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1589 {
1590   /* Don't generate memory->memory moves, go through a register.  */
1591   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1592     operands[1] = force_reg (QImode, operands[1]);
1593 })
1594
1595 (define_insn "*movstrictqi_1"
1596   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1597         (match_operand:QI 1 "general_operand" "*qn,m"))]
1598   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1599    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1600   "mov{b}\t{%1, %0|%0, %1}"
1601   [(set_attr "type" "imov")
1602    (set_attr "mode" "QI")])
1603
1604 (define_insn "*movstrictqi_xor"
1605   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1606         (match_operand:QI 1 "const0_operand" "i"))
1607    (clobber (reg:CC 17))]
1608   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1609   "xor{b}\t{%0, %0|%0, %0}"
1610   [(set_attr "type" "alu1")
1611    (set_attr "mode" "QI")
1612    (set_attr "length_immediate" "0")])
1613
1614 (define_insn "*movsi_extv_1"
1615   [(set (match_operand:SI 0 "register_operand" "=R")
1616         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1617                          (const_int 8)
1618                          (const_int 8)))]
1619   ""
1620   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1621   [(set_attr "type" "imovx")
1622    (set_attr "mode" "SI")])
1623
1624 (define_insn "*movhi_extv_1"
1625   [(set (match_operand:HI 0 "register_operand" "=R")
1626         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1627                          (const_int 8)
1628                          (const_int 8)))]
1629   ""
1630   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1631   [(set_attr "type" "imovx")
1632    (set_attr "mode" "SI")])
1633
1634 (define_insn "*movqi_extv_1"
1635   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1636         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1637                          (const_int 8)
1638                          (const_int 8)))]
1639   "!TARGET_64BIT"
1640 {
1641   switch (get_attr_type (insn))
1642     {
1643     case TYPE_IMOVX:
1644       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1645     default:
1646       return "mov{b}\t{%h1, %0|%0, %h1}";
1647     }
1648 }
1649   [(set (attr "type")
1650      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1651                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1652                              (ne (symbol_ref "TARGET_MOVX")
1653                                  (const_int 0))))
1654         (const_string "imovx")
1655         (const_string "imov")))
1656    (set (attr "mode")
1657      (if_then_else (eq_attr "type" "imovx")
1658         (const_string "SI")
1659         (const_string "QI")))])
1660
1661 (define_insn "*movqi_extv_1_rex64"
1662   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1663         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1664                          (const_int 8)
1665                          (const_int 8)))]
1666   "TARGET_64BIT"
1667 {
1668   switch (get_attr_type (insn))
1669     {
1670     case TYPE_IMOVX:
1671       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1672     default:
1673       return "mov{b}\t{%h1, %0|%0, %h1}";
1674     }
1675 }
1676   [(set (attr "type")
1677      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1678                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1679                              (ne (symbol_ref "TARGET_MOVX")
1680                                  (const_int 0))))
1681         (const_string "imovx")
1682         (const_string "imov")))
1683    (set (attr "mode")
1684      (if_then_else (eq_attr "type" "imovx")
1685         (const_string "SI")
1686         (const_string "QI")))])
1687
1688 ;; Stores and loads of ax to arbitrary constant address.
1689 ;; We fake an second form of instruction to force reload to load address
1690 ;; into register when rax is not available
1691 (define_insn "*movabsqi_1_rex64"
1692   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
1693         (match_operand:QI 1 "nonmemory_operand" "a,er,i"))]
1694   "TARGET_64BIT"
1695   "@
1696    movabs{b}\t{%1, %P0|%P0, %1}
1697    mov{b}\t{%1, %a0|%a0, %1}
1698    movabs{b}\t{%1, %a0|%a0, %1}"
1699   [(set_attr "type" "imov")
1700    (set_attr "modrm" "0,*,*")
1701    (set_attr "length_address" "8,0,0")
1702    (set_attr "length_immediate" "0,*,*")
1703    (set_attr "memory" "store")
1704    (set_attr "mode" "QI")])
1705
1706 (define_insn "*movabsqi_2_rex64"
1707   [(set (match_operand:QI 0 "register_operand" "=a,r")
1708         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1709   "TARGET_64BIT"
1710   "@
1711    movabs{b}\t{%P1, %0|%0, %P1}
1712    mov{b}\t{%a1, %0|%0, %a1}"
1713   [(set_attr "type" "imov")
1714    (set_attr "modrm" "0,*")
1715    (set_attr "length_address" "8,0")
1716    (set_attr "length_immediate" "0")
1717    (set_attr "memory" "load")
1718    (set_attr "mode" "QI")])
1719
1720 (define_insn "*movsi_extzv_1"
1721   [(set (match_operand:SI 0 "register_operand" "=R")
1722         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1723                          (const_int 8)
1724                          (const_int 8)))]
1725   ""
1726   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1727   [(set_attr "type" "imovx")
1728    (set_attr "mode" "SI")])
1729
1730 (define_insn "*movqi_extzv_2"
1731   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1732         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1733                                     (const_int 8)
1734                                     (const_int 8)) 0))]
1735   "!TARGET_64BIT"
1736 {
1737   switch (get_attr_type (insn))
1738     {
1739     case TYPE_IMOVX:
1740       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1741     default:
1742       return "mov{b}\t{%h1, %0|%0, %h1}";
1743     }
1744 }
1745   [(set (attr "type")
1746      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1747                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1748                              (ne (symbol_ref "TARGET_MOVX")
1749                                  (const_int 0))))
1750         (const_string "imovx")
1751         (const_string "imov")))
1752    (set (attr "mode")
1753      (if_then_else (eq_attr "type" "imovx")
1754         (const_string "SI")
1755         (const_string "QI")))])
1756
1757 (define_insn "*movqi_extzv_2_rex64"
1758   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1759         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1760                                     (const_int 8)
1761                                     (const_int 8)) 0))]
1762   "TARGET_64BIT"
1763 {
1764   switch (get_attr_type (insn))
1765     {
1766     case TYPE_IMOVX:
1767       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1768     default:
1769       return "mov{b}\t{%h1, %0|%0, %h1}";
1770     }
1771 }
1772   [(set (attr "type")
1773      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1774                         (ne (symbol_ref "TARGET_MOVX")
1775                             (const_int 0)))
1776         (const_string "imovx")
1777         (const_string "imov")))
1778    (set (attr "mode")
1779      (if_then_else (eq_attr "type" "imovx")
1780         (const_string "SI")
1781         (const_string "QI")))])
1782
1783 (define_insn "movsi_insv_1"
1784   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1785                          (const_int 8)
1786                          (const_int 8))
1787         (match_operand:SI 1 "general_operand" "Qmn"))]
1788   "!TARGET_64BIT"
1789   "mov{b}\t{%b1, %h0|%h0, %b1}"
1790   [(set_attr "type" "imov")
1791    (set_attr "mode" "QI")])
1792
1793 (define_insn "*movsi_insv_1_rex64"
1794   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1795                          (const_int 8)
1796                          (const_int 8))
1797         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1798   "TARGET_64BIT"
1799   "mov{b}\t{%b1, %h0|%h0, %b1}"
1800   [(set_attr "type" "imov")
1801    (set_attr "mode" "QI")])
1802
1803 (define_insn "*movqi_insv_2"
1804   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1805                          (const_int 8)
1806                          (const_int 8))
1807         (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1808                              (const_int 8))
1809                 (const_int 255)))]
1810   ""
1811   "mov{b}\t{%h1, %h0|%h0, %h1}"
1812   [(set_attr "type" "imov")
1813    (set_attr "mode" "QI")])
1814
1815 (define_expand "movdi"
1816   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1817         (match_operand:DI 1 "general_operand" ""))]
1818   ""
1819   "ix86_expand_move (DImode, operands); DONE;")
1820
1821 (define_insn "*pushdi"
1822   [(set (match_operand:DI 0 "push_operand" "=<")
1823         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1824   "!TARGET_64BIT"
1825   "#")
1826
1827 (define_insn "pushdi2_rex64"
1828   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1829         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1830   "TARGET_64BIT"
1831   "@
1832    push{q}\t%1
1833    #"
1834   [(set_attr "type" "push,multi")
1835    (set_attr "mode" "DI")])
1836
1837 ;; Convert impossible pushes of immediate to existing instructions.
1838 ;; First try to get scratch register and go through it.  In case this
1839 ;; fails, push sign extended lower part first and then overwrite
1840 ;; upper part by 32bit move.
1841 (define_peephole2
1842   [(match_scratch:DI 2 "r")
1843    (set (match_operand:DI 0 "push_operand" "")
1844         (match_operand:DI 1 "immediate_operand" ""))]
1845   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1846    && !x86_64_immediate_operand (operands[1], DImode)"
1847   [(set (match_dup 2) (match_dup 1))
1848    (set (match_dup 0) (match_dup 2))]
1849   "")
1850
1851 ;; We need to define this as both peepholer and splitter for case
1852 ;; peephole2 pass is not run.
1853 (define_peephole2
1854   [(set (match_operand:DI 0 "push_operand" "")
1855         (match_operand:DI 1 "immediate_operand" ""))]
1856   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1857    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1858   [(set (match_dup 0) (match_dup 1))
1859    (set (match_dup 2) (match_dup 3))]
1860   "split_di (operands + 1, 1, operands + 2, operands + 3);
1861    operands[1] = gen_lowpart (DImode, operands[2]);
1862    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1863                                                     GEN_INT (4)));
1864   ")
1865
1866 (define_split
1867   [(set (match_operand:DI 0 "push_operand" "")
1868         (match_operand:DI 1 "immediate_operand" ""))]
1869   "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
1870    && !symbolic_operand (operands[1], DImode)
1871    && !x86_64_immediate_operand (operands[1], DImode)"
1872   [(set (match_dup 0) (match_dup 1))
1873    (set (match_dup 2) (match_dup 3))]
1874   "split_di (operands + 1, 1, operands + 2, operands + 3);
1875    operands[1] = gen_lowpart (DImode, operands[2]);
1876    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1877                                                     GEN_INT (4)));
1878   ")
1879
1880 (define_insn "*pushdi2_prologue_rex64"
1881   [(set (match_operand:DI 0 "push_operand" "=<")
1882         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1883    (clobber (mem:BLK (scratch)))]
1884   "TARGET_64BIT"
1885   "push{q}\t%1"
1886   [(set_attr "type" "push")
1887    (set_attr "mode" "DI")])
1888
1889 (define_insn "*popdi1_epilogue_rex64"
1890   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1891         (mem:DI (reg:DI 7)))
1892    (set (reg:DI 7)
1893         (plus:DI (reg:DI 7) (const_int 8)))
1894    (clobber (mem:BLK (scratch)))]
1895   "TARGET_64BIT"
1896   "pop{q}\t%0"
1897   [(set_attr "type" "pop")
1898    (set_attr "mode" "DI")])
1899
1900 (define_insn "popdi1"
1901   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1902         (mem:DI (reg:DI 7)))
1903    (set (reg:DI 7)
1904         (plus:DI (reg:DI 7) (const_int 8)))]
1905   "TARGET_64BIT"
1906   "pop{q}\t%0"
1907   [(set_attr "type" "pop")
1908    (set_attr "mode" "DI")])
1909
1910 (define_insn "*movdi_xor_rex64"
1911   [(set (match_operand:DI 0 "register_operand" "=r")
1912         (match_operand:DI 1 "const0_operand" "i"))
1913    (clobber (reg:CC 17))]
1914   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1915    && reload_completed"
1916   "xor{l}\t{%k0, %k0|%k0, %k0}"
1917   [(set_attr "type" "alu1")
1918    (set_attr "mode" "SI")
1919    (set_attr "length_immediate" "0")])
1920
1921 (define_insn "*movdi_or_rex64"
1922   [(set (match_operand:DI 0 "register_operand" "=r")
1923         (match_operand:DI 1 "const_int_operand" "i"))
1924    (clobber (reg:CC 17))]
1925   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1926    && reload_completed
1927    && GET_CODE (operands[1]) == CONST_INT
1928    && INTVAL (operands[1]) == -1"
1929 {
1930   operands[1] = constm1_rtx;
1931   return "or{q}\t{%1, %0|%0, %1}";
1932 }
1933   [(set_attr "type" "alu1")
1934    (set_attr "mode" "DI")
1935    (set_attr "length_immediate" "1")])
1936
1937 (define_insn "*movdi_2"
1938   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,!m*y,!*y,!m,!*Y,!*Y")
1939         (match_operand:DI 1 "general_operand" "riFo,riF,*y,m,*Y,*Y,m"))]
1940   "!TARGET_64BIT
1941    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1942   "@
1943    #
1944    #
1945    movq\t{%1, %0|%0, %1}
1946    movq\t{%1, %0|%0, %1}
1947    movq\t{%1, %0|%0, %1}
1948    movdqa\t{%1, %0|%0, %1}
1949    movq\t{%1, %0|%0, %1}"
1950   [(set_attr "type" "*,*,mmx,mmx,ssemov,ssemov,ssemov")
1951    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI")])
1952
1953 (define_split
1954   [(set (match_operand:DI 0 "push_operand" "")
1955         (match_operand:DI 1 "general_operand" ""))]
1956   "!TARGET_64BIT && reload_completed
1957    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1958   [(const_int 0)]
1959   "ix86_split_long_move (operands); DONE;")
1960
1961 ;; %%% This multiword shite has got to go.
1962 (define_split
1963   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1964         (match_operand:DI 1 "general_operand" ""))]
1965   "!TARGET_64BIT && reload_completed
1966    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1967    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1968   [(const_int 0)]
1969   "ix86_split_long_move (operands); DONE;")
1970
1971 (define_insn "*movdi_1_rex64"
1972   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!rm,!*y,!*Y,!rm,!*Y")
1973         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,rm,*Y,*Y,rm"))]
1974   "TARGET_64BIT
1975    && (TARGET_INTER_UNIT_MOVES || optimize_size)
1976    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1977 {
1978   switch (get_attr_type (insn))
1979     {
1980     case TYPE_SSEMOV:
1981       if (get_attr_mode (insn) == MODE_TI)
1982           return "movdqa\t{%1, %0|%0, %1}";
1983       /* FALLTHRU */
1984     case TYPE_MMXMOV:
1985       /* Moves from and into integer register is done using movd opcode with
1986          REX prefix.  */
1987       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1988           return "movd\t{%1, %0|%0, %1}";
1989       return "movq\t{%1, %0|%0, %1}";
1990     case TYPE_MULTI:
1991       return "#";
1992     case TYPE_LEA:
1993       return "lea{q}\t{%a1, %0|%0, %a1}";
1994     default:
1995       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1996         abort ();
1997       if (get_attr_mode (insn) == MODE_SI)
1998         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1999       else if (which_alternative == 2)
2000         return "movabs{q}\t{%1, %0|%0, %1}";
2001       else
2002         return "mov{q}\t{%1, %0|%0, %1}";
2003     }
2004 }
2005   [(set (attr "type")
2006      (cond [(eq_attr "alternative" "5,6,7")
2007               (const_string "mmxmov")
2008             (eq_attr "alternative" "8,9,10")
2009               (const_string "ssemov")
2010             (eq_attr "alternative" "4")
2011               (const_string "multi")
2012             (and (ne (symbol_ref "flag_pic") (const_int 0))
2013                  (match_operand:DI 1 "symbolic_operand" ""))
2014               (const_string "lea")
2015            ]
2016            (const_string "imov")))
2017    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2018    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2019    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2020
2021 (define_insn "*movdi_1_rex64_nointerunit"
2022   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,mr,!mr,!*y,!m,!*y,!*Y,!m,!*Y")
2023         (match_operand:DI 1 "general_operand" "Z,rem,i,re,n,*y,*y,m,*Y,*Y,m"))]
2024   "TARGET_64BIT
2025    && (!TARGET_INTER_UNIT_MOVES && !optimize_size)
2026    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2027 {
2028   switch (get_attr_type (insn))
2029     {
2030     case TYPE_SSEMOV:
2031       if (get_attr_mode (insn) == MODE_TI)
2032           return "movdqa\t{%1, %0|%0, %1}";
2033       /* FALLTHRU */
2034     case TYPE_MMXMOV:
2035       return "movq\t{%1, %0|%0, %1}";
2036     case TYPE_MULTI:
2037       return "#";
2038     case TYPE_LEA:
2039       return "lea{q}\t{%a1, %0|%0, %a1}";
2040     default:
2041       if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
2042         abort ();
2043       if (get_attr_mode (insn) == MODE_SI)
2044         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2045       else if (which_alternative == 2)
2046         return "movabs{q}\t{%1, %0|%0, %1}";
2047       else
2048         return "mov{q}\t{%1, %0|%0, %1}";
2049     }
2050 }
2051   [(set (attr "type")
2052      (cond [(eq_attr "alternative" "5,6,7")
2053               (const_string "mmxmov")
2054             (eq_attr "alternative" "8,9,10")
2055               (const_string "ssemov")
2056             (eq_attr "alternative" "4")
2057               (const_string "multi")
2058             (and (ne (symbol_ref "flag_pic") (const_int 0))
2059                  (match_operand:DI 1 "symbolic_operand" ""))
2060               (const_string "lea")
2061            ]
2062            (const_string "imov")))
2063    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*")
2064    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*")
2065    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,TI,DI,DI")])
2066
2067 ;; Stores and loads of ax to arbitrary constant address.
2068 ;; We fake an second form of instruction to force reload to load address
2069 ;; into register when rax is not available
2070 (define_insn "*movabsdi_1_rex64"
2071   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r,r"))
2072         (match_operand:DI 1 "nonmemory_operand" "a,er,i"))]
2073   "TARGET_64BIT"
2074   "@
2075    movabs{q}\t{%1, %P0|%P0, %1}
2076    mov{q}\t{%1, %a0|%a0, %1}
2077    movabs{q}\t{%1, %a0|%a0, %1}"
2078   [(set_attr "type" "imov")
2079    (set_attr "modrm" "0,*,*")
2080    (set_attr "length_address" "8,0,0")
2081    (set_attr "length_immediate" "0,*,*")
2082    (set_attr "memory" "store")
2083    (set_attr "mode" "DI")])
2084
2085 (define_insn "*movabsdi_2_rex64"
2086   [(set (match_operand:DI 0 "register_operand" "=a,r")
2087         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2088   "TARGET_64BIT"
2089   "@
2090    movabs{q}\t{%P1, %0|%0, %P1}
2091    mov{q}\t{%a1, %0|%0, %a1}"
2092   [(set_attr "type" "imov")
2093    (set_attr "modrm" "0,*")
2094    (set_attr "length_address" "8,0")
2095    (set_attr "length_immediate" "0")
2096    (set_attr "memory" "load")
2097    (set_attr "mode" "DI")])
2098
2099 ;; Convert impossible stores of immediate to existing instructions.
2100 ;; First try to get scratch register and go through it.  In case this
2101 ;; fails, move by 32bit parts.
2102 (define_peephole2
2103   [(match_scratch:DI 2 "r")
2104    (set (match_operand:DI 0 "memory_operand" "")
2105         (match_operand:DI 1 "immediate_operand" ""))]
2106   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2107    && !x86_64_immediate_operand (operands[1], DImode)"
2108   [(set (match_dup 2) (match_dup 1))
2109    (set (match_dup 0) (match_dup 2))]
2110   "")
2111
2112 ;; We need to define this as both peepholer and splitter for case
2113 ;; peephole2 pass is not run.
2114 (define_peephole2
2115   [(set (match_operand:DI 0 "memory_operand" "")
2116         (match_operand:DI 1 "immediate_operand" ""))]
2117   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2118    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2119   [(set (match_dup 2) (match_dup 3))
2120    (set (match_dup 4) (match_dup 5))]
2121   "split_di (operands, 2, operands + 2, operands + 4);")
2122
2123 (define_split
2124   [(set (match_operand:DI 0 "memory_operand" "")
2125         (match_operand:DI 1 "immediate_operand" ""))]
2126   "TARGET_64BIT && (flow2_completed || (reload_completed && !flag_peephole2))
2127    && !symbolic_operand (operands[1], DImode)
2128    && !x86_64_immediate_operand (operands[1], DImode)"
2129   [(set (match_dup 2) (match_dup 3))
2130    (set (match_dup 4) (match_dup 5))]
2131   "split_di (operands, 2, operands + 2, operands + 4);")
2132
2133 (define_insn "*swapdi_rex64"
2134   [(set (match_operand:DI 0 "register_operand" "+r")
2135         (match_operand:DI 1 "register_operand" "+r"))
2136    (set (match_dup 1)
2137         (match_dup 0))]
2138   "TARGET_64BIT"
2139   "xchg{q}\t%1, %0"
2140   [(set_attr "type" "imov")
2141    (set_attr "pent_pair" "np")
2142    (set_attr "athlon_decode" "vector")
2143    (set_attr "mode" "DI")
2144    (set_attr "modrm" "0")
2145    (set_attr "ppro_uops" "few")])
2146
2147   
2148 (define_expand "movsf"
2149   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2150         (match_operand:SF 1 "general_operand" ""))]
2151   ""
2152   "ix86_expand_move (SFmode, operands); DONE;")
2153
2154 (define_insn "*pushsf"
2155   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2156         (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2157   "!TARGET_64BIT"
2158 {
2159   switch (which_alternative)
2160     {
2161     case 1:
2162       return "push{l}\t%1";
2163
2164     default:
2165       /* This insn should be already splitted before reg-stack.  */
2166       abort ();
2167     }
2168 }
2169   [(set_attr "type" "multi,push,multi")
2170    (set_attr "mode" "SF,SI,SF")])
2171
2172 (define_insn "*pushsf_rex64"
2173   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2174         (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2175   "TARGET_64BIT"
2176 {
2177   switch (which_alternative)
2178     {
2179     case 1:
2180       return "push{q}\t%q1";
2181
2182     default:
2183       /* This insn should be already splitted before reg-stack.  */
2184       abort ();
2185     }
2186 }
2187   [(set_attr "type" "multi,push,multi")
2188    (set_attr "mode" "SF,DI,SF")])
2189
2190 (define_split
2191   [(set (match_operand:SF 0 "push_operand" "")
2192         (match_operand:SF 1 "memory_operand" ""))]
2193   "reload_completed
2194    && GET_CODE (operands[1]) == MEM
2195    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2196    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2197   [(set (match_dup 0)
2198         (match_dup 1))]
2199   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2200
2201
2202 ;; %%% Kill this when call knows how to work this out.
2203 (define_split
2204   [(set (match_operand:SF 0 "push_operand" "")
2205         (match_operand:SF 1 "any_fp_register_operand" ""))]
2206   "!TARGET_64BIT"
2207   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
2208    (set (mem:SF (reg:SI 7)) (match_dup 1))])
2209
2210 (define_split
2211   [(set (match_operand:SF 0 "push_operand" "")
2212         (match_operand:SF 1 "any_fp_register_operand" ""))]
2213   "TARGET_64BIT"
2214   [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2215    (set (mem:SF (reg:DI 7)) (match_dup 1))])
2216
2217 (define_insn "*movsf_1"
2218   [(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")
2219         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,rm,*y,*y"))]
2220   "(TARGET_INTER_UNIT_MOVES || optimize_size)
2221    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2222    && (reload_in_progress || reload_completed
2223        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2224        || GET_CODE (operands[1]) != CONST_DOUBLE
2225        || memory_operand (operands[0], SFmode))" 
2226 {
2227   switch (which_alternative)
2228     {
2229     case 0:
2230       if (REG_P (operands[1])
2231           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2232         return "fstp\t%y0";
2233       else if (STACK_TOP_P (operands[0]))
2234         return "fld%z1\t%y1";
2235       else
2236         return "fst\t%y0";
2237
2238     case 1:
2239       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2240         return "fstp%z0\t%y0";
2241       else
2242         return "fst%z0\t%y0";
2243
2244     case 2:
2245       return standard_80387_constant_opcode (operands[1]);
2246
2247     case 3:
2248     case 4:
2249       return "mov{l}\t{%1, %0|%0, %1}";
2250     case 5:
2251       if (get_attr_mode (insn) == MODE_TI)
2252         return "pxor\t%0, %0";
2253       else
2254         return "xorps\t%0, %0";
2255     case 6:
2256       if (get_attr_mode (insn) == MODE_V4SF)
2257         return "movaps\t{%1, %0|%0, %1}";
2258       else
2259         return "movss\t{%1, %0|%0, %1}";
2260     case 7:
2261     case 8:
2262       return "movss\t{%1, %0|%0, %1}";
2263
2264     case 9:
2265     case 10:
2266       return "movd\t{%1, %0|%0, %1}";
2267
2268     case 11:
2269       return "movq\t{%1, %0|%0, %1}";
2270
2271     default:
2272       abort();
2273     }
2274 }
2275   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2276    (set (attr "mode")
2277         (cond [(eq_attr "alternative" "3,4,9,10")
2278                  (const_string "SI")
2279                (eq_attr "alternative" "5")
2280                  (if_then_else
2281                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2282                                  (const_int 0))
2283                              (ne (symbol_ref "TARGET_SSE2")
2284                                  (const_int 0)))
2285                         (eq (symbol_ref "optimize_size")
2286                             (const_int 0)))
2287                    (const_string "TI")
2288                    (const_string "V4SF"))
2289                /* For architectures resolving dependencies on
2290                   whole SSE registers use APS move to break dependency
2291                   chains, otherwise use short move to avoid extra work. 
2292
2293                   Do the same for architectures resolving dependencies on
2294                   the parts.  While in DF mode it is better to always handle
2295                   just register parts, the SF mode is different due to lack
2296                   of instructions to load just part of the register.  It is
2297                   better to maintain the whole registers in single format
2298                   to avoid problems on using packed logical operations.  */
2299                (eq_attr "alternative" "6")
2300                  (if_then_else
2301                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2302                             (const_int 0))
2303                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2304                             (const_int 0)))
2305                    (const_string "V4SF")
2306                    (const_string "SF"))
2307                (eq_attr "alternative" "11")
2308                  (const_string "DI")]
2309                (const_string "SF")))])
2310
2311 (define_insn "*movsf_1_nointerunit"
2312   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#xr,m,f#xr,r#xf,m,x#rf,x#rf,x#rf,m,!*y,!m,!*y")
2313         (match_operand:SF 1 "general_operand" "fm#rx,f#rx,G,rmF#fx,Fr#fx,C,x,xm#rf,x#rf,m,*y,*y"))]
2314   "(!TARGET_INTER_UNIT_MOVES && !optimize_size)
2315    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2316    && (reload_in_progress || reload_completed
2317        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2318        || GET_CODE (operands[1]) != CONST_DOUBLE
2319        || memory_operand (operands[0], SFmode))" 
2320 {
2321   switch (which_alternative)
2322     {
2323     case 0:
2324       if (REG_P (operands[1])
2325           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2326         {
2327           if (REGNO (operands[0]) == FIRST_STACK_REG
2328               && TARGET_USE_FFREEP)
2329             return "ffreep\t%y0";
2330           return "fstp\t%y0";
2331         }
2332       else if (STACK_TOP_P (operands[0]))
2333         return "fld%z1\t%y1";
2334       else
2335         return "fst\t%y0";
2336
2337     case 1:
2338       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2339         return "fstp%z0\t%y0";
2340       else
2341         return "fst%z0\t%y0";
2342
2343     case 2:
2344       return standard_80387_constant_opcode (operands[1]);
2345
2346     case 3:
2347     case 4:
2348       return "mov{l}\t{%1, %0|%0, %1}";
2349     case 5:
2350       if (get_attr_mode (insn) == MODE_TI)
2351         return "pxor\t%0, %0";
2352       else
2353         return "xorps\t%0, %0";
2354     case 6:
2355       if (get_attr_mode (insn) == MODE_V4SF)
2356         return "movaps\t{%1, %0|%0, %1}";
2357       else
2358         return "movss\t{%1, %0|%0, %1}";
2359     case 7:
2360     case 8:
2361       return "movss\t{%1, %0|%0, %1}";
2362
2363     case 9:
2364     case 10:
2365       return "movd\t{%1, %0|%0, %1}";
2366
2367     case 11:
2368       return "movq\t{%1, %0|%0, %1}";
2369
2370     default:
2371       abort();
2372     }
2373 }
2374   [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2375    (set (attr "mode")
2376         (cond [(eq_attr "alternative" "3,4,9,10")
2377                  (const_string "SI")
2378                (eq_attr "alternative" "5")
2379                  (if_then_else
2380                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2381                                  (const_int 0))
2382                              (ne (symbol_ref "TARGET_SSE2")
2383                                  (const_int 0)))
2384                         (eq (symbol_ref "optimize_size")
2385                             (const_int 0)))
2386                    (const_string "TI")
2387                    (const_string "V4SF"))
2388                /* For architectures resolving dependencies on
2389                   whole SSE registers use APS move to break dependency
2390                   chains, otherwise use short move to avoid extra work. 
2391
2392                   Do the same for architectures resolving dependencies on
2393                   the parts.  While in DF mode it is better to always handle
2394                   just register parts, the SF mode is different due to lack
2395                   of instructions to load just part of the register.  It is
2396                   better to maintain the whole registers in single format
2397                   to avoid problems on using packed logical operations.  */
2398                (eq_attr "alternative" "6")
2399                  (if_then_else
2400                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2401                             (const_int 0))
2402                         (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2403                             (const_int 0)))
2404                    (const_string "V4SF")
2405                    (const_string "SF"))
2406                (eq_attr "alternative" "11")
2407                  (const_string "DI")]
2408                (const_string "SF")))])
2409
2410 (define_insn "*swapsf"
2411   [(set (match_operand:SF 0 "register_operand" "+f")
2412         (match_operand:SF 1 "register_operand" "+f"))
2413    (set (match_dup 1)
2414         (match_dup 0))]
2415   "reload_completed || !TARGET_SSE"
2416 {
2417   if (STACK_TOP_P (operands[0]))
2418     return "fxch\t%1";
2419   else
2420     return "fxch\t%0";
2421 }
2422   [(set_attr "type" "fxch")
2423    (set_attr "mode" "SF")])
2424
2425 (define_expand "movdf"
2426   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2427         (match_operand:DF 1 "general_operand" ""))]
2428   ""
2429   "ix86_expand_move (DFmode, operands); DONE;")
2430
2431 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2432 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2433 ;; On the average, pushdf using integers can be still shorter.  Allow this
2434 ;; pattern for optimize_size too.
2435
2436 (define_insn "*pushdf_nointeger"
2437   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2438         (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2439   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2440 {
2441   /* This insn should be already splitted before reg-stack.  */
2442   abort ();
2443 }
2444   [(set_attr "type" "multi")
2445    (set_attr "mode" "DF,SI,SI,DF")])
2446
2447 (define_insn "*pushdf_integer"
2448   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2449         (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2450   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2451 {
2452   /* This insn should be already splitted before reg-stack.  */
2453   abort ();
2454 }
2455   [(set_attr "type" "multi")
2456    (set_attr "mode" "DF,SI,DF")])
2457
2458 ;; %%% Kill this when call knows how to work this out.
2459 (define_split
2460   [(set (match_operand:DF 0 "push_operand" "")
2461         (match_operand:DF 1 "any_fp_register_operand" ""))]
2462   "!TARGET_64BIT && reload_completed"
2463   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
2464    (set (mem:DF (reg:SI 7)) (match_dup 1))]
2465   "")
2466
2467 (define_split
2468   [(set (match_operand:DF 0 "push_operand" "")
2469         (match_operand:DF 1 "any_fp_register_operand" ""))]
2470   "TARGET_64BIT && reload_completed"
2471   [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
2472    (set (mem:DF (reg:DI 7)) (match_dup 1))]
2473   "")
2474
2475 (define_split
2476   [(set (match_operand:DF 0 "push_operand" "")
2477         (match_operand:DF 1 "general_operand" ""))]
2478   "reload_completed"
2479   [(const_int 0)]
2480   "ix86_split_long_move (operands); DONE;")
2481
2482 ;; Moving is usually shorter when only FP registers are used. This separate
2483 ;; movdf pattern avoids the use of integer registers for FP operations
2484 ;; when optimizing for size.
2485
2486 (define_insn "*movdf_nointeger"
2487   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m,f#Y,*r,o,Y#f,Y#f,Y#f,m")
2488         (match_operand:DF 1 "general_operand" "fm#Y,f#Y,G,*roF,F*r,C,Y#f,YHm#f,Y#f"))]
2489   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2490    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2491    && (reload_in_progress || reload_completed
2492        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2493        || GET_CODE (operands[1]) != CONST_DOUBLE
2494        || memory_operand (operands[0], DFmode))" 
2495 {
2496   switch (which_alternative)
2497     {
2498     case 0:
2499       if (REG_P (operands[1])
2500           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2501         {
2502           if (REGNO (operands[0]) == FIRST_STACK_REG
2503               && TARGET_USE_FFREEP)
2504             return "ffreep\t%y0";
2505           return "fstp\t%y0";
2506         }
2507       else if (STACK_TOP_P (operands[0]))
2508         return "fld%z1\t%y1";
2509       else
2510         return "fst\t%y0";
2511
2512     case 1:
2513       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2514         return "fstp%z0\t%y0";
2515       else
2516         return "fst%z0\t%y0";
2517
2518     case 2:
2519       return standard_80387_constant_opcode (operands[1]);
2520
2521     case 3:
2522     case 4:
2523       return "#";
2524     case 5:
2525       switch (get_attr_mode (insn))
2526         {
2527         case MODE_V4SF:
2528           return "xorps\t%0, %0";
2529         case MODE_V2DF:
2530           return "xorpd\t%0, %0";
2531         case MODE_TI:
2532           return "pxor\t%0, %0";
2533         default:
2534           abort ();
2535         }
2536     case 6:
2537       switch (get_attr_mode (insn))
2538         {
2539         case MODE_V4SF:
2540           return "movaps\t{%1, %0|%0, %1}";
2541         case MODE_V2DF:
2542           return "movapd\t{%1, %0|%0, %1}";
2543         case MODE_DF:
2544           return "movsd\t{%1, %0|%0, %1}";
2545         default:
2546           abort ();
2547         }
2548     case 7:
2549       if (get_attr_mode (insn) == MODE_V2DF)
2550         return "movlpd\t{%1, %0|%0, %1}";
2551       else
2552         return "movsd\t{%1, %0|%0, %1}";
2553     case 8:
2554       return "movsd\t{%1, %0|%0, %1}";
2555
2556     default:
2557       abort();
2558     }
2559 }
2560   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2561    (set (attr "mode")
2562         (cond [(eq_attr "alternative" "3,4")
2563                  (const_string "SI")
2564                /* xorps is one byte shorter.  */
2565                (eq_attr "alternative" "5")
2566                  (cond [(ne (symbol_ref "optimize_size")
2567                             (const_int 0))
2568                           (const_string "V4SF")
2569                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2570                             (const_int 0))
2571                           (const_string "TI")]
2572                        (const_string "V2DF"))
2573                /* For architectures resolving dependencies on
2574                   whole SSE registers use APD move to break dependency
2575                   chains, otherwise use short move to avoid extra work.
2576
2577                   movaps encodes one byte shorter.  */
2578                (eq_attr "alternative" "6")
2579                  (cond
2580                   [(ne (symbol_ref "optimize_size")
2581                        (const_int 0))
2582                      (const_string "V4SF")
2583                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2584                        (const_int 0))
2585                      (const_string "V2DF")]
2586                    (const_string "DF"))
2587                /* For architectures resolving dependencies on register
2588                   parts we may avoid extra work to zero out upper part
2589                   of register.  */
2590                (eq_attr "alternative" "7")
2591                  (if_then_else
2592                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2593                        (const_int 0))
2594                    (const_string "V2DF")
2595                    (const_string "DF"))]
2596                (const_string "DF")))])
2597
2598 (define_insn "*movdf_integer"
2599   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Yr,m,f#Yr,r#Yf,o,Y#rf,Y#rf,Y#rf,m")
2600         (match_operand:DF 1 "general_operand" "fm#Yr,f#Yr,G,roF#Yf,Fr#Yf,C,Y#rf,Ym#rf,Y#rf"))]
2601   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2602    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2603    && (reload_in_progress || reload_completed
2604        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2605        || GET_CODE (operands[1]) != CONST_DOUBLE
2606        || memory_operand (operands[0], DFmode))" 
2607 {
2608   switch (which_alternative)
2609     {
2610     case 0:
2611       if (REG_P (operands[1])
2612           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2613         {
2614           if (REGNO (operands[0]) == FIRST_STACK_REG
2615               && TARGET_USE_FFREEP)
2616             return "ffreep\t%y0";
2617           return "fstp\t%y0";
2618         }
2619       else if (STACK_TOP_P (operands[0]))
2620         return "fld%z1\t%y1";
2621       else
2622         return "fst\t%y0";
2623
2624     case 1:
2625       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2626         return "fstp%z0\t%y0";
2627       else
2628         return "fst%z0\t%y0";
2629
2630     case 2:
2631       return standard_80387_constant_opcode (operands[1]);
2632
2633     case 3:
2634     case 4:
2635       return "#";
2636
2637     case 5:
2638       switch (get_attr_mode (insn))
2639         {
2640         case MODE_V4SF:
2641           return "xorps\t%0, %0";
2642         case MODE_V2DF:
2643           return "xorpd\t%0, %0";
2644         case MODE_TI:
2645           return "pxor\t%0, %0";
2646         default:
2647           abort ();
2648         }
2649     case 6:
2650       switch (get_attr_mode (insn))
2651         {
2652         case MODE_V4SF:
2653           return "movaps\t{%1, %0|%0, %1}";
2654         case MODE_V2DF:
2655           return "movapd\t{%1, %0|%0, %1}";
2656         case MODE_DF:
2657           return "movsd\t{%1, %0|%0, %1}";
2658         default:
2659           abort ();
2660         }
2661     case 7:
2662       if (get_attr_mode (insn) == MODE_V2DF)
2663         return "movlpd\t{%1, %0|%0, %1}";
2664       else
2665         return "movsd\t{%1, %0|%0, %1}";
2666     case 8:
2667       return "movsd\t{%1, %0|%0, %1}";
2668
2669     default:
2670       abort();
2671     }
2672 }
2673   [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2674    (set (attr "mode")
2675         (cond [(eq_attr "alternative" "3,4")
2676                  (const_string "SI")
2677                /* xorps is one byte shorter.  */
2678                (eq_attr "alternative" "5")
2679                  (cond [(ne (symbol_ref "optimize_size")
2680                             (const_int 0))
2681                           (const_string "V4SF")
2682                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2683                             (const_int 0))
2684                           (const_string "TI")]
2685                        (const_string "V2DF"))
2686                /* For architectures resolving dependencies on
2687                   whole SSE registers use APD move to break dependency
2688                   chains, otherwise use short move to avoid extra work.  
2689
2690                   movaps encodes one byte shorter.  */
2691                (eq_attr "alternative" "6")
2692                  (cond
2693                   [(ne (symbol_ref "optimize_size")
2694                        (const_int 0))
2695                      (const_string "V4SF")
2696                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2697                        (const_int 0))
2698                      (const_string "V2DF")]
2699                    (const_string "DF"))
2700                /* For architectures resolving dependencies on register
2701                   parts we may avoid extra work to zero out upper part
2702                   of register.  */
2703                (eq_attr "alternative" "7")
2704                  (if_then_else
2705                    (ne (symbol_ref "TARGET_SSE_PARTIAL_REGS")
2706                        (const_int 0))
2707                    (const_string "V2DF")
2708                    (const_string "DF"))]
2709                (const_string "DF")))])
2710
2711 (define_split
2712   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2713         (match_operand:DF 1 "general_operand" ""))]
2714   "reload_completed
2715    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2716    && ! (ANY_FP_REG_P (operands[0]) || 
2717          (GET_CODE (operands[0]) == SUBREG
2718           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2719    && ! (ANY_FP_REG_P (operands[1]) || 
2720          (GET_CODE (operands[1]) == SUBREG
2721           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2722   [(const_int 0)]
2723   "ix86_split_long_move (operands); DONE;")
2724
2725 (define_insn "*swapdf"
2726   [(set (match_operand:DF 0 "register_operand" "+f")
2727         (match_operand:DF 1 "register_operand" "+f"))
2728    (set (match_dup 1)
2729         (match_dup 0))]
2730   "reload_completed || !TARGET_SSE2"
2731 {
2732   if (STACK_TOP_P (operands[0]))
2733     return "fxch\t%1";
2734   else
2735     return "fxch\t%0";
2736 }
2737   [(set_attr "type" "fxch")
2738    (set_attr "mode" "DF")])
2739
2740 (define_expand "movxf"
2741   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2742         (match_operand:XF 1 "general_operand" ""))]
2743   "!TARGET_128BIT_LONG_DOUBLE"
2744   "ix86_expand_move (XFmode, operands); DONE;")
2745
2746 (define_expand "movtf"
2747   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2748         (match_operand:TF 1 "general_operand" ""))]
2749   ""
2750   "ix86_expand_move (TFmode, operands); DONE;")
2751
2752 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2753 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2754 ;; Pushing using integer instructions is longer except for constants
2755 ;; and direct memory references.
2756 ;; (assuming that any given constant is pushed only once, but this ought to be
2757 ;;  handled elsewhere).
2758
2759 (define_insn "*pushxf_nointeger"
2760   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2761         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2762   "!TARGET_128BIT_LONG_DOUBLE && optimize_size"
2763 {
2764   /* This insn should be already splitted before reg-stack.  */
2765   abort ();
2766 }
2767   [(set_attr "type" "multi")
2768    (set_attr "mode" "XF,SI,SI")])
2769
2770 (define_insn "*pushtf_nointeger"
2771   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2772         (match_operand:TF 1 "general_no_elim_operand" "f,Fo,*r"))]
2773   "optimize_size"
2774 {
2775   /* This insn should be already splitted before reg-stack.  */
2776   abort ();
2777 }
2778   [(set_attr "type" "multi")
2779    (set_attr "mode" "XF,SI,SI")])
2780
2781 (define_insn "*pushxf_integer"
2782   [(set (match_operand:XF 0 "push_operand" "=<,<")
2783         (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2784   "!TARGET_128BIT_LONG_DOUBLE && !optimize_size"
2785 {
2786   /* This insn should be already splitted before reg-stack.  */
2787   abort ();
2788 }
2789   [(set_attr "type" "multi")
2790    (set_attr "mode" "XF,SI")])
2791
2792 (define_insn "*pushtf_integer"
2793   [(set (match_operand:TF 0 "push_operand" "=<,<")
2794         (match_operand:TF 1 "general_no_elim_operand" "f#r,rFo#f"))]
2795   "!optimize_size"
2796 {
2797   /* This insn should be already splitted before reg-stack.  */
2798   abort ();
2799 }
2800   [(set_attr "type" "multi")
2801    (set_attr "mode" "XF,SI")])
2802
2803 (define_split
2804   [(set (match_operand 0 "push_operand" "")
2805         (match_operand 1 "general_operand" ""))]
2806   "reload_completed
2807    && (GET_MODE (operands[0]) == XFmode
2808        || GET_MODE (operands[0]) == TFmode
2809        || GET_MODE (operands[0]) == DFmode)
2810    && !ANY_FP_REG_P (operands[1])"
2811   [(const_int 0)]
2812   "ix86_split_long_move (operands); DONE;")
2813
2814 (define_split
2815   [(set (match_operand:XF 0 "push_operand" "")
2816         (match_operand:XF 1 "any_fp_register_operand" ""))]
2817   "!TARGET_128BIT_LONG_DOUBLE"
2818   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
2819    (set (mem:XF (reg:SI 7)) (match_dup 1))])
2820
2821 (define_split
2822   [(set (match_operand:TF 0 "push_operand" "")
2823         (match_operand:TF 1 "any_fp_register_operand" ""))]
2824   "!TARGET_64BIT"
2825   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
2826    (set (mem:TF (reg:SI 7)) (match_dup 1))])
2827
2828 (define_split
2829   [(set (match_operand:TF 0 "push_operand" "")
2830         (match_operand:TF 1 "any_fp_register_operand" ""))]
2831   "TARGET_64BIT"
2832   [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
2833    (set (mem:TF (reg:DI 7)) (match_dup 1))])
2834
2835 ;; Do not use integer registers when optimizing for size
2836 (define_insn "*movxf_nointeger"
2837   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2838         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2839   "!TARGET_128BIT_LONG_DOUBLE
2840    && optimize_size
2841    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2842    && (reload_in_progress || reload_completed
2843        || GET_CODE (operands[1]) != CONST_DOUBLE
2844        || memory_operand (operands[0], XFmode))" 
2845 {
2846   switch (which_alternative)
2847     {
2848     case 0:
2849       if (REG_P (operands[1])
2850           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2851         {
2852           if (REGNO (operands[0]) == FIRST_STACK_REG
2853               && TARGET_USE_FFREEP)
2854             return "ffreep\t%y0";
2855           return "fstp\t%y0";
2856         }
2857       else if (STACK_TOP_P (operands[0]))
2858         return "fld%z1\t%y1";
2859       else
2860         return "fst\t%y0";
2861
2862     case 1:
2863       /* There is no non-popping store to memory for XFmode.  So if
2864          we need one, follow the store with a load.  */
2865       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2866         return "fstp%z0\t%y0\;fld%z0\t%y0";
2867       else
2868         return "fstp%z0\t%y0";
2869
2870     case 2:
2871       return standard_80387_constant_opcode (operands[1]);
2872
2873     case 3: case 4:
2874       return "#";
2875     }
2876   abort();
2877 }
2878   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2879    (set_attr "mode" "XF,XF,XF,SI,SI")])
2880
2881 (define_insn "*movtf_nointeger"
2882   [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2883         (match_operand:TF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2884   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2885    && optimize_size
2886    && (reload_in_progress || reload_completed
2887        || GET_CODE (operands[1]) != CONST_DOUBLE
2888        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2889        || memory_operand (operands[0], TFmode))" 
2890 {
2891   switch (which_alternative)
2892     {
2893     case 0:
2894       if (REG_P (operands[1])
2895           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2896         {
2897           if (REGNO (operands[0]) == FIRST_STACK_REG
2898               && TARGET_USE_FFREEP)
2899             return "ffreep\t%y0";
2900           return "fstp\t%y0";
2901         }
2902       else if (STACK_TOP_P (operands[0]))
2903         return "fld%z1\t%y1";
2904       else
2905         return "fst\t%y0";
2906
2907     case 1:
2908       /* There is no non-popping store to memory for XFmode.  So if
2909          we need one, follow the store with a load.  */
2910       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2911         return "fstp%z0\t%y0\;fld%z0\t%y0";
2912       else
2913         return "fstp%z0\t%y0";
2914
2915     case 2:
2916       return standard_80387_constant_opcode (operands[1]);
2917
2918     case 3: case 4:
2919       return "#";
2920     }
2921   abort();
2922 }
2923   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2924    (set_attr "mode" "XF,XF,XF,SI,SI")])
2925
2926 (define_insn "*movxf_integer"
2927   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2928         (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2929   "!TARGET_128BIT_LONG_DOUBLE
2930    && !optimize_size
2931    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2932    && (reload_in_progress || reload_completed
2933        || GET_CODE (operands[1]) != CONST_DOUBLE
2934        || memory_operand (operands[0], XFmode))" 
2935 {
2936   switch (which_alternative)
2937     {
2938     case 0:
2939       if (REG_P (operands[1])
2940           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2941         {
2942           if (REGNO (operands[0]) == FIRST_STACK_REG
2943               && TARGET_USE_FFREEP)
2944             return "ffreep\t%y0";
2945           return "fstp\t%y0";
2946         }
2947       else if (STACK_TOP_P (operands[0]))
2948         return "fld%z1\t%y1";
2949       else
2950         return "fst\t%y0";
2951
2952     case 1:
2953       /* There is no non-popping store to memory for XFmode.  So if
2954          we need one, follow the store with a load.  */
2955       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2956         return "fstp%z0\t%y0\;fld%z0\t%y0";
2957       else
2958         return "fstp%z0\t%y0";
2959
2960     case 2:
2961       return standard_80387_constant_opcode (operands[1]);
2962
2963     case 3: case 4:
2964       return "#";
2965     }
2966   abort();
2967 }
2968   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2969    (set_attr "mode" "XF,XF,XF,SI,SI")])
2970
2971 (define_insn "*movtf_integer"
2972   [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2973         (match_operand:TF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2974   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2975    && !optimize_size
2976    && (reload_in_progress || reload_completed
2977        || GET_CODE (operands[1]) != CONST_DOUBLE
2978        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2979        || memory_operand (operands[0], TFmode))" 
2980 {
2981   switch (which_alternative)
2982     {
2983     case 0:
2984       if (REG_P (operands[1])
2985           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2986         {
2987           if (REGNO (operands[0]) == FIRST_STACK_REG
2988               && TARGET_USE_FFREEP)
2989             return "ffreep\t%y0";
2990           return "fstp\t%y0";
2991         }
2992       else if (STACK_TOP_P (operands[0]))
2993         return "fld%z1\t%y1";
2994       else
2995         return "fst\t%y0";
2996
2997     case 1:
2998       /* There is no non-popping store to memory for XFmode.  So if
2999          we need one, follow the store with a load.  */
3000       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3001         return "fstp%z0\t%y0\;fld%z0\t%y0";
3002       else
3003         return "fstp%z0\t%y0";
3004
3005     case 2:
3006       return standard_80387_constant_opcode (operands[1]);
3007
3008     case 3: case 4:
3009       return "#";
3010     }
3011   abort();
3012 }
3013   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3014    (set_attr "mode" "XF,XF,XF,SI,SI")])
3015
3016 (define_split
3017   [(set (match_operand 0 "nonimmediate_operand" "")
3018         (match_operand 1 "general_operand" ""))]
3019   "reload_completed
3020    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
3021    && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
3022    && ! (ANY_FP_REG_P (operands[0]) || 
3023          (GET_CODE (operands[0]) == SUBREG
3024           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3025    && ! (ANY_FP_REG_P (operands[1]) || 
3026          (GET_CODE (operands[1]) == SUBREG
3027           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3028   [(const_int 0)]
3029   "ix86_split_long_move (operands); DONE;")
3030
3031 (define_split
3032   [(set (match_operand 0 "register_operand" "")
3033         (match_operand 1 "memory_operand" ""))]
3034   "reload_completed
3035    && GET_CODE (operands[1]) == MEM
3036    && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode
3037        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
3038    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
3039    && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
3040    && (!(SSE_REG_P (operands[0]) || 
3041          (GET_CODE (operands[0]) == SUBREG
3042           && SSE_REG_P (SUBREG_REG (operands[0]))))
3043        || standard_sse_constant_p (get_pool_constant (XEXP (operands[1], 0))))
3044    && (!(FP_REG_P (operands[0]) || 
3045          (GET_CODE (operands[0]) == SUBREG
3046           && FP_REG_P (SUBREG_REG (operands[0]))))
3047        || standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0))))"
3048   [(set (match_dup 0)
3049         (match_dup 1))]
3050   "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
3051
3052 (define_insn "swapxf"
3053   [(set (match_operand:XF 0 "register_operand" "+f")
3054         (match_operand:XF 1 "register_operand" "+f"))
3055    (set (match_dup 1)
3056         (match_dup 0))]
3057   ""
3058 {
3059   if (STACK_TOP_P (operands[0]))
3060     return "fxch\t%1";
3061   else
3062     return "fxch\t%0";
3063 }
3064   [(set_attr "type" "fxch")
3065    (set_attr "mode" "XF")])
3066
3067 (define_insn "swaptf"
3068   [(set (match_operand:TF 0 "register_operand" "+f")
3069         (match_operand:TF 1 "register_operand" "+f"))
3070    (set (match_dup 1)
3071         (match_dup 0))]
3072   ""
3073 {
3074   if (STACK_TOP_P (operands[0]))
3075     return "fxch\t%1";
3076   else
3077     return "fxch\t%0";
3078 }
3079   [(set_attr "type" "fxch")
3080    (set_attr "mode" "XF")])
3081 \f
3082 ;; Zero extension instructions
3083
3084 (define_expand "zero_extendhisi2"
3085   [(set (match_operand:SI 0 "register_operand" "")
3086      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3087   ""
3088 {
3089   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3090     {
3091       operands[1] = force_reg (HImode, operands[1]);
3092       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3093       DONE;
3094     }
3095 })
3096
3097 (define_insn "zero_extendhisi2_and"
3098   [(set (match_operand:SI 0 "register_operand" "=r")
3099      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3100    (clobber (reg:CC 17))]
3101   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3102   "#"
3103   [(set_attr "type" "alu1")
3104    (set_attr "mode" "SI")])
3105
3106 (define_split
3107   [(set (match_operand:SI 0 "register_operand" "")
3108         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3109    (clobber (reg:CC 17))]
3110   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3111   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3112               (clobber (reg:CC 17))])]
3113   "")
3114
3115 (define_insn "*zero_extendhisi2_movzwl"
3116   [(set (match_operand:SI 0 "register_operand" "=r")
3117      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3118   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3119   "movz{wl|x}\t{%1, %0|%0, %1}"
3120   [(set_attr "type" "imovx")
3121    (set_attr "mode" "SI")])
3122
3123 (define_expand "zero_extendqihi2"
3124   [(parallel
3125     [(set (match_operand:HI 0 "register_operand" "")
3126        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3127      (clobber (reg:CC 17))])]
3128   ""
3129   "")
3130
3131 (define_insn "*zero_extendqihi2_and"
3132   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3133      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3134    (clobber (reg:CC 17))]
3135   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3136   "#"
3137   [(set_attr "type" "alu1")
3138    (set_attr "mode" "HI")])
3139
3140 (define_insn "*zero_extendqihi2_movzbw_and"
3141   [(set (match_operand:HI 0 "register_operand" "=r,r")
3142      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3143    (clobber (reg:CC 17))]
3144   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3145   "#"
3146   [(set_attr "type" "imovx,alu1")
3147    (set_attr "mode" "HI")])
3148
3149 (define_insn "*zero_extendqihi2_movzbw"
3150   [(set (match_operand:HI 0 "register_operand" "=r")
3151      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3152   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3153   "movz{bw|x}\t{%1, %0|%0, %1}"
3154   [(set_attr "type" "imovx")
3155    (set_attr "mode" "HI")])
3156
3157 ;; For the movzbw case strip only the clobber
3158 (define_split
3159   [(set (match_operand:HI 0 "register_operand" "")
3160         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3161    (clobber (reg:CC 17))]
3162   "reload_completed 
3163    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3164    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3165   [(set (match_operand:HI 0 "register_operand" "")
3166         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3167
3168 ;; When source and destination does not overlap, clear destination
3169 ;; first and then do the movb
3170 (define_split
3171   [(set (match_operand:HI 0 "register_operand" "")
3172         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3173    (clobber (reg:CC 17))]
3174   "reload_completed
3175    && ANY_QI_REG_P (operands[0])
3176    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3177    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3178   [(set (match_dup 0) (const_int 0))
3179    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3180   "operands[2] = gen_lowpart (QImode, operands[0]);")
3181
3182 ;; Rest is handled by single and.
3183 (define_split
3184   [(set (match_operand:HI 0 "register_operand" "")
3185         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3186    (clobber (reg:CC 17))]
3187   "reload_completed
3188    && true_regnum (operands[0]) == true_regnum (operands[1])"
3189   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3190               (clobber (reg:CC 17))])]
3191   "")
3192
3193 (define_expand "zero_extendqisi2"
3194   [(parallel
3195     [(set (match_operand:SI 0 "register_operand" "")
3196        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3197      (clobber (reg:CC 17))])]
3198   ""
3199   "")
3200
3201 (define_insn "*zero_extendqisi2_and"
3202   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3203      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3204    (clobber (reg:CC 17))]
3205   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3206   "#"
3207   [(set_attr "type" "alu1")
3208    (set_attr "mode" "SI")])
3209
3210 (define_insn "*zero_extendqisi2_movzbw_and"
3211   [(set (match_operand:SI 0 "register_operand" "=r,r")
3212      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3213    (clobber (reg:CC 17))]
3214   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3215   "#"
3216   [(set_attr "type" "imovx,alu1")
3217    (set_attr "mode" "SI")])
3218
3219 (define_insn "*zero_extendqisi2_movzbw"
3220   [(set (match_operand:SI 0 "register_operand" "=r")
3221      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3222   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3223   "movz{bl|x}\t{%1, %0|%0, %1}"
3224   [(set_attr "type" "imovx")
3225    (set_attr "mode" "SI")])
3226
3227 ;; For the movzbl case strip only the clobber
3228 (define_split
3229   [(set (match_operand:SI 0 "register_operand" "")
3230         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3231    (clobber (reg:CC 17))]
3232   "reload_completed 
3233    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3234    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3235   [(set (match_dup 0)
3236         (zero_extend:SI (match_dup 1)))])
3237
3238 ;; When source and destination does not overlap, clear destination
3239 ;; first and then do the movb
3240 (define_split
3241   [(set (match_operand:SI 0 "register_operand" "")
3242         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3243    (clobber (reg:CC 17))]
3244   "reload_completed
3245    && ANY_QI_REG_P (operands[0])
3246    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3247    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3248    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3249   [(set (match_dup 0) (const_int 0))
3250    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3251   "operands[2] = gen_lowpart (QImode, operands[0]);")
3252
3253 ;; Rest is handled by single and.
3254 (define_split
3255   [(set (match_operand:SI 0 "register_operand" "")
3256         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3257    (clobber (reg:CC 17))]
3258   "reload_completed
3259    && true_regnum (operands[0]) == true_regnum (operands[1])"
3260   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3261               (clobber (reg:CC 17))])]
3262   "")
3263
3264 ;; %%% Kill me once multi-word ops are sane.
3265 (define_expand "zero_extendsidi2"
3266   [(set (match_operand:DI 0 "register_operand" "=r")
3267      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3268   ""
3269   "if (!TARGET_64BIT)
3270      {
3271        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3272        DONE;
3273      }
3274   ")
3275
3276 (define_insn "zero_extendsidi2_32"
3277   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
3278         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r")))
3279    (clobber (reg:CC 17))]
3280   "!TARGET_64BIT"
3281   "#"
3282   [(set_attr "mode" "SI")])
3283
3284 (define_insn "zero_extendsidi2_rex64"
3285   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
3286      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0")))]
3287   "TARGET_64BIT"
3288   "@
3289    mov\t{%k1, %k0|%k0, %k1}
3290    #"
3291   [(set_attr "type" "imovx,imov")
3292    (set_attr "mode" "SI,DI")])
3293
3294 (define_split
3295   [(set (match_operand:DI 0 "memory_operand" "")
3296      (zero_extend:DI (match_dup 0)))]
3297   "TARGET_64BIT"
3298   [(set (match_dup 4) (const_int 0))]
3299   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3300
3301 (define_split 
3302   [(set (match_operand:DI 0 "register_operand" "")
3303         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3304    (clobber (reg:CC 17))]
3305   "!TARGET_64BIT && reload_completed
3306    && true_regnum (operands[0]) == true_regnum (operands[1])"
3307   [(set (match_dup 4) (const_int 0))]
3308   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3309
3310 (define_split 
3311   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3312         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3313    (clobber (reg:CC 17))]
3314   "!TARGET_64BIT && reload_completed"
3315   [(set (match_dup 3) (match_dup 1))
3316    (set (match_dup 4) (const_int 0))]
3317   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3318
3319 (define_insn "zero_extendhidi2"
3320   [(set (match_operand:DI 0 "register_operand" "=r,r")
3321      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3322   "TARGET_64BIT"
3323   "@
3324    movz{wl|x}\t{%1, %k0|%k0, %1} 
3325    movz{wq|x}\t{%1, %0|%0, %1}"
3326   [(set_attr "type" "imovx")
3327    (set_attr "mode" "SI,DI")])
3328
3329 (define_insn "zero_extendqidi2"
3330   [(set (match_operand:DI 0 "register_operand" "=r,r")
3331      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3332   "TARGET_64BIT"
3333   "@
3334    movz{bl|x}\t{%1, %k0|%k0, %1} 
3335    movz{bq|x}\t{%1, %0|%0, %1}"
3336   [(set_attr "type" "imovx")
3337    (set_attr "mode" "SI,DI")])
3338 \f
3339 ;; Sign extension instructions
3340
3341 (define_expand "extendsidi2"
3342   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3343                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3344               (clobber (reg:CC 17))
3345               (clobber (match_scratch:SI 2 ""))])]
3346   ""
3347 {
3348   if (TARGET_64BIT)
3349     {
3350       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3351       DONE;
3352     }
3353 })
3354
3355 (define_insn "*extendsidi2_1"
3356   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3357         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3358    (clobber (reg:CC 17))
3359    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3360   "!TARGET_64BIT"
3361   "#")
3362
3363 (define_insn "extendsidi2_rex64"
3364   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3365         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3366   "TARGET_64BIT"
3367   "@
3368    {cltq|cdqe}
3369    movs{lq|x}\t{%1,%0|%0, %1}"
3370   [(set_attr "type" "imovx")
3371    (set_attr "mode" "DI")
3372    (set_attr "prefix_0f" "0")
3373    (set_attr "modrm" "0,1")])
3374
3375 (define_insn "extendhidi2"
3376   [(set (match_operand:DI 0 "register_operand" "=r")
3377         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3378   "TARGET_64BIT"
3379   "movs{wq|x}\t{%1,%0|%0, %1}"
3380   [(set_attr "type" "imovx")
3381    (set_attr "mode" "DI")])
3382
3383 (define_insn "extendqidi2"
3384   [(set (match_operand:DI 0 "register_operand" "=r")
3385         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3386   "TARGET_64BIT"
3387   "movs{bq|x}\t{%1,%0|%0, %1}"
3388    [(set_attr "type" "imovx")
3389     (set_attr "mode" "DI")])
3390
3391 ;; Extend to memory case when source register does die.
3392 (define_split 
3393   [(set (match_operand:DI 0 "memory_operand" "")
3394         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3395    (clobber (reg:CC 17))
3396    (clobber (match_operand:SI 2 "register_operand" ""))]
3397   "(reload_completed
3398     && dead_or_set_p (insn, operands[1])
3399     && !reg_mentioned_p (operands[1], operands[0]))"
3400   [(set (match_dup 3) (match_dup 1))
3401    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3402               (clobber (reg:CC 17))])
3403    (set (match_dup 4) (match_dup 1))]
3404   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3405
3406 ;; Extend to memory case when source register does not die.
3407 (define_split 
3408   [(set (match_operand:DI 0 "memory_operand" "")
3409         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3410    (clobber (reg:CC 17))
3411    (clobber (match_operand:SI 2 "register_operand" ""))]
3412   "reload_completed"
3413   [(const_int 0)]
3414 {
3415   split_di (&operands[0], 1, &operands[3], &operands[4]);
3416
3417   emit_move_insn (operands[3], operands[1]);
3418
3419   /* Generate a cltd if possible and doing so it profitable.  */
3420   if (true_regnum (operands[1]) == 0
3421       && true_regnum (operands[2]) == 1
3422       && (optimize_size || TARGET_USE_CLTD))
3423     {
3424       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3425     }
3426   else
3427     {
3428       emit_move_insn (operands[2], operands[1]);
3429       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3430     }
3431   emit_move_insn (operands[4], operands[2]);
3432   DONE;
3433 })
3434
3435 ;; Extend to register case.  Optimize case where source and destination
3436 ;; registers match and cases where we can use cltd.
3437 (define_split 
3438   [(set (match_operand:DI 0 "register_operand" "")
3439         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3440    (clobber (reg:CC 17))
3441    (clobber (match_scratch:SI 2 ""))]
3442   "reload_completed"
3443   [(const_int 0)]
3444 {
3445   split_di (&operands[0], 1, &operands[3], &operands[4]);
3446
3447   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3448     emit_move_insn (operands[3], operands[1]);
3449
3450   /* Generate a cltd if possible and doing so it profitable.  */
3451   if (true_regnum (operands[3]) == 0
3452       && (optimize_size || TARGET_USE_CLTD))
3453     {
3454       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3455       DONE;
3456     }
3457
3458   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3459     emit_move_insn (operands[4], operands[1]);
3460
3461   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3462   DONE;
3463 })
3464
3465 (define_insn "extendhisi2"
3466   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3467         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3468   ""
3469 {
3470   switch (get_attr_prefix_0f (insn))
3471     {
3472     case 0:
3473       return "{cwtl|cwde}";
3474     default:
3475       return "movs{wl|x}\t{%1,%0|%0, %1}";
3476     }
3477 }
3478   [(set_attr "type" "imovx")
3479    (set_attr "mode" "SI")
3480    (set (attr "prefix_0f")
3481      ;; movsx is short decodable while cwtl is vector decoded.
3482      (if_then_else (and (eq_attr "cpu" "!k6")
3483                         (eq_attr "alternative" "0"))
3484         (const_string "0")
3485         (const_string "1")))
3486    (set (attr "modrm")
3487      (if_then_else (eq_attr "prefix_0f" "0")
3488         (const_string "0")
3489         (const_string "1")))])
3490
3491 (define_insn "*extendhisi2_zext"
3492   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3493         (zero_extend:DI
3494           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3495   "TARGET_64BIT"
3496 {
3497   switch (get_attr_prefix_0f (insn))
3498     {
3499     case 0:
3500       return "{cwtl|cwde}";
3501     default:
3502       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3503     }
3504 }
3505   [(set_attr "type" "imovx")
3506    (set_attr "mode" "SI")
3507    (set (attr "prefix_0f")
3508      ;; movsx is short decodable while cwtl is vector decoded.
3509      (if_then_else (and (eq_attr "cpu" "!k6")
3510                         (eq_attr "alternative" "0"))
3511         (const_string "0")
3512         (const_string "1")))
3513    (set (attr "modrm")
3514      (if_then_else (eq_attr "prefix_0f" "0")
3515         (const_string "0")
3516         (const_string "1")))])
3517
3518 (define_insn "extendqihi2"
3519   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3520         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3521   ""
3522 {
3523   switch (get_attr_prefix_0f (insn))
3524     {
3525     case 0:
3526       return "{cbtw|cbw}";
3527     default:
3528       return "movs{bw|x}\t{%1,%0|%0, %1}";
3529     }
3530 }
3531   [(set_attr "type" "imovx")
3532    (set_attr "mode" "HI")
3533    (set (attr "prefix_0f")
3534      ;; movsx is short decodable while cwtl is vector decoded.
3535      (if_then_else (and (eq_attr "cpu" "!k6")
3536                         (eq_attr "alternative" "0"))
3537         (const_string "0")
3538         (const_string "1")))
3539    (set (attr "modrm")
3540      (if_then_else (eq_attr "prefix_0f" "0")
3541         (const_string "0")
3542         (const_string "1")))])
3543
3544 (define_insn "extendqisi2"
3545   [(set (match_operand:SI 0 "register_operand" "=r")
3546         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3547   ""
3548   "movs{bl|x}\t{%1,%0|%0, %1}"
3549    [(set_attr "type" "imovx")
3550     (set_attr "mode" "SI")])
3551
3552 (define_insn "*extendqisi2_zext"
3553   [(set (match_operand:DI 0 "register_operand" "=r")
3554         (zero_extend:DI
3555           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3556   "TARGET_64BIT"
3557   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3558    [(set_attr "type" "imovx")
3559     (set_attr "mode" "SI")])
3560 \f
3561 ;; Conversions between float and double.
3562
3563 ;; These are all no-ops in the model used for the 80387.  So just
3564 ;; emit moves.
3565
3566 ;; %%% Kill these when call knows how to work out a DFmode push earlier. 
3567 (define_insn "*dummy_extendsfdf2"
3568   [(set (match_operand:DF 0 "push_operand" "=<")
3569         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3570   "0"
3571   "#")
3572
3573 (define_split
3574   [(set (match_operand:DF 0 "push_operand" "")
3575         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3576   "!TARGET_64BIT"
3577   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
3578    (set (mem:DF (reg:SI 7)) (float_extend:DF (match_dup 1)))])
3579
3580 (define_split
3581   [(set (match_operand:DF 0 "push_operand" "")
3582         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3583   "TARGET_64BIT"
3584   [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
3585    (set (mem:DF (reg:DI 7)) (float_extend:DF (match_dup 1)))])
3586
3587 (define_insn "*dummy_extendsfxf2"
3588   [(set (match_operand:XF 0 "push_operand" "=<")
3589         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3590   "0"
3591   "#")
3592
3593 (define_split
3594   [(set (match_operand:XF 0 "push_operand" "")
3595         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3596   "!TARGET_128BIT_LONG_DOUBLE"
3597   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3598    (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3599
3600 (define_insn "*dummy_extendsftf2"
3601   [(set (match_operand:TF 0 "push_operand" "=<")
3602         (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3603   "0"
3604   "#")
3605
3606 (define_split
3607   [(set (match_operand:TF 0 "push_operand" "")
3608         (float_extend:TF (match_operand:SF 1 "fp_register_operand" "")))]
3609   "!TARGET_64BIT"
3610   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3611    (set (mem:TF (reg:SI 7)) (float_extend:TF (match_dup 1)))])
3612
3613 (define_split
3614   [(set (match_operand:TF 0 "push_operand" "")
3615         (float_extend:TF (match_operand:SF 1 "fp_register_operand" "")))]
3616   "TARGET_64BIT"
3617   [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3618    (set (mem:DF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
3619
3620 (define_insn "*dummy_extenddfxf2"
3621   [(set (match_operand:XF 0 "push_operand" "=<")
3622         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "f")))]
3623   "0"
3624   "#")
3625
3626 (define_split
3627   [(set (match_operand:XF 0 "push_operand" "")
3628         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3629   "!TARGET_128BIT_LONG_DOUBLE"
3630   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
3631    (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3632
3633 (define_insn "*dummy_extenddftf2"
3634   [(set (match_operand:TF 0 "push_operand" "=<")
3635         (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f")))]
3636   "0"
3637   "#")
3638
3639 (define_split
3640   [(set (match_operand:TF 0 "push_operand" "")
3641         (float_extend:TF (match_operand:DF 1 "fp_register_operand" "")))]
3642   "!TARGET_64BIT"
3643   [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
3644    (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
3645
3646 (define_split
3647   [(set (match_operand:TF 0 "push_operand" "")
3648         (float_extend:TF (match_operand:DF 1 "fp_register_operand" "")))]
3649   "TARGET_64BIT"
3650   [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
3651    (set (mem:TF (reg:DI 7)) (float_extend:TF (match_dup 1)))])
3652
3653 (define_expand "extendsfdf2"
3654   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3655         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3656   "TARGET_80387 || TARGET_SSE2"
3657 {
3658   /* ??? Needed for compress_float_constant since all fp constants
3659      are LEGITIMATE_CONSTANT_P.  */
3660   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3661     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3662   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3663     operands[1] = force_reg (SFmode, operands[1]);
3664 })
3665
3666 (define_insn "*extendsfdf2_1"
3667   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f")
3668         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3669   "(TARGET_80387 || TARGET_SSE2)
3670    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3671 {
3672   switch (which_alternative)
3673     {
3674     case 0:
3675       if (REG_P (operands[1])
3676           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3677         return "fstp\t%y0";
3678       else if (STACK_TOP_P (operands[0]))
3679         return "fld%z1\t%y1";
3680       else
3681         return "fst\t%y0";
3682
3683     case 1:
3684       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3685         return "fstp%z0\t%y0";
3686
3687       else
3688         return "fst%z0\t%y0";
3689     case 2:
3690       return "cvtss2sd\t{%1, %0|%0, %1}";
3691
3692     default:
3693       abort ();
3694     }
3695 }
3696   [(set_attr "type" "fmov,fmov,ssecvt")
3697    (set_attr "mode" "SF,XF,DF")])
3698
3699 (define_insn "*extendsfdf2_1_sse_only"
3700   [(set (match_operand:DF 0 "register_operand" "=Y")
3701         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3702   "!TARGET_80387 && TARGET_SSE2
3703    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3704   "cvtss2sd\t{%1, %0|%0, %1}"
3705   [(set_attr "type" "ssecvt")
3706    (set_attr "mode" "DF")])
3707
3708 (define_expand "extendsfxf2"
3709   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3710         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3711   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
3712 {
3713   /* ??? Needed for compress_float_constant since all fp constants
3714      are LEGITIMATE_CONSTANT_P.  */
3715   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3716     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3717   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3718     operands[1] = force_reg (SFmode, operands[1]);
3719 })
3720
3721 (define_insn "*extendsfxf2_1"
3722   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3723         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3724   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
3725    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3726 {
3727   switch (which_alternative)
3728     {
3729     case 0:
3730       if (REG_P (operands[1])
3731           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3732         return "fstp\t%y0";
3733       else if (STACK_TOP_P (operands[0]))
3734         return "fld%z1\t%y1";
3735       else
3736         return "fst\t%y0";
3737
3738     case 1:
3739       /* There is no non-popping store to memory for XFmode.  So if
3740          we need one, follow the store with a load.  */
3741       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3742         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3743       else
3744         return "fstp%z0\t%y0";
3745
3746     default:
3747       abort ();
3748     }
3749 }
3750   [(set_attr "type" "fmov")
3751    (set_attr "mode" "SF,XF")])
3752
3753 (define_expand "extendsftf2"
3754   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3755         (float_extend:TF (match_operand:SF 1 "general_operand" "")))]
3756   "TARGET_80387"
3757 {
3758   /* ??? Needed for compress_float_constant since all fp constants
3759      are LEGITIMATE_CONSTANT_P.  */
3760   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3761     operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3762   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3763     operands[1] = force_reg (SFmode, operands[1]);
3764 })
3765
3766 (define_insn "*extendsftf2_1"
3767   [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
3768         (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3769   "TARGET_80387
3770    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3771 {
3772   switch (which_alternative)
3773     {
3774     case 0:
3775       if (REG_P (operands[1])
3776           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3777         return "fstp\t%y0";
3778       else if (STACK_TOP_P (operands[0]))
3779         return "fld%z1\t%y1";
3780       else
3781         return "fst\t%y0";
3782
3783     case 1:
3784       /* There is no non-popping store to memory for XFmode.  So if
3785          we need one, follow the store with a load.  */
3786       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3787         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3788       else
3789         return "fstp%z0\t%y0";
3790
3791     default:
3792       abort ();
3793     }
3794 }
3795   [(set_attr "type" "fmov")
3796    (set_attr "mode" "SF,XF")])
3797
3798 (define_expand "extenddfxf2"
3799   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3800         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3801   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
3802 {
3803   /* ??? Needed for compress_float_constant since all fp constants
3804      are LEGITIMATE_CONSTANT_P.  */
3805   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3806     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3807   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3808     operands[1] = force_reg (DFmode, operands[1]);
3809 })
3810
3811 (define_insn "*extenddfxf2_1"
3812   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3813         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3814   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
3815    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3816 {
3817   switch (which_alternative)
3818     {
3819     case 0:
3820       if (REG_P (operands[1])
3821           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3822         return "fstp\t%y0";
3823       else if (STACK_TOP_P (operands[0]))
3824         return "fld%z1\t%y1";
3825       else
3826         return "fst\t%y0";
3827
3828     case 1:
3829       /* There is no non-popping store to memory for XFmode.  So if
3830          we need one, follow the store with a load.  */
3831       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3832         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3833       else
3834         return "fstp%z0\t%y0";
3835
3836     default:
3837       abort ();
3838     }
3839 }
3840   [(set_attr "type" "fmov")
3841    (set_attr "mode" "DF,XF")])
3842
3843 (define_expand "extenddftf2"
3844   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3845         (float_extend:TF (match_operand:DF 1 "general_operand" "")))]
3846   "TARGET_80387"
3847 {
3848   /* ??? Needed for compress_float_constant since all fp constants
3849      are LEGITIMATE_CONSTANT_P.  */
3850   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3851     operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3852   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3853     operands[1] = force_reg (DFmode, operands[1]);
3854 })
3855
3856 (define_insn "*extenddftf2_1"
3857   [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
3858         (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3859   "TARGET_80387
3860    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3861 {
3862   switch (which_alternative)
3863     {
3864     case 0:
3865       if (REG_P (operands[1])
3866           && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3867         return "fstp\t%y0";
3868       else if (STACK_TOP_P (operands[0]))
3869         return "fld%z1\t%y1";
3870       else
3871         return "fst\t%y0";
3872
3873     case 1:
3874       /* There is no non-popping store to memory for XFmode.  So if
3875          we need one, follow the store with a load.  */
3876       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3877         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3878       else
3879         return "fstp%z0\t%y0";
3880
3881     default:
3882       abort ();
3883     }
3884 }
3885   [(set_attr "type" "fmov")
3886    (set_attr "mode" "DF,XF")])
3887
3888 ;; %%% This seems bad bad news.
3889 ;; This cannot output into an f-reg because there is no way to be sure
3890 ;; of truncating in that case.  Otherwise this is just like a simple move
3891 ;; insn.  So we pretend we can output to a reg in order to get better
3892 ;; register preferencing, but we really use a stack slot.
3893
3894 (define_expand "truncdfsf2"
3895   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3896                    (float_truncate:SF
3897                     (match_operand:DF 1 "register_operand" "")))
3898               (clobber (match_dup 2))])]
3899   "TARGET_80387 || TARGET_SSE2"
3900   "
3901    if (TARGET_80387)
3902      operands[2] = assign_386_stack_local (SFmode, 0);
3903    else
3904      {
3905         emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
3906         DONE;
3907      }
3908 ")
3909
3910 (define_insn "*truncdfsf2_1"
3911   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3912         (float_truncate:SF
3913          (match_operand:DF 1 "register_operand" "f,f,f,f")))
3914    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3915   "TARGET_80387 && !TARGET_SSE2"
3916 {
3917   switch (which_alternative)
3918     {
3919     case 0:
3920       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3921         return "fstp%z0\t%y0";
3922       else
3923         return "fst%z0\t%y0";
3924     default:
3925       abort ();
3926     }
3927 }
3928   [(set_attr "type" "fmov,multi,multi,multi")
3929    (set_attr "mode" "SF,SF,SF,SF")])
3930
3931 (define_insn "*truncdfsf2_1_sse"
3932   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m#fxr,?f#xr,?r#fx,?x#fr,Y#fr")
3933         (float_truncate:SF
3934          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3935    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3936   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3937 {
3938   switch (which_alternative)
3939     {
3940     case 0:
3941       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3942         return "fstp%z0\t%y0";
3943       else
3944         return "fst%z0\t%y0";
3945     case 4:
3946       return "#";
3947     default:
3948       abort ();
3949     }
3950 }
3951   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3952    (set_attr "mode" "SF,SF,SF,SF,DF")])
3953
3954 (define_insn "*truncdfsf2_1_sse_nooverlap"
3955   [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,&Y")
3956         (float_truncate:SF
3957          (match_operand:DF 1 "nonimmediate_operand" "f#Y,f#Y,f#Y,f#Y,mY#f")))
3958    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
3959   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
3960 {
3961   switch (which_alternative)
3962     {
3963     case 0:
3964       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3965         return "fstp%z0\t%y0";
3966       else
3967         return "fst%z0\t%y0";
3968     case 4:
3969       return "#";
3970     default:
3971       abort ();
3972     }
3973 }
3974   [(set_attr "type" "fmov,multi,multi,multi,ssecvt")
3975    (set_attr "mode" "SF,SF,SF,SF,DF")])
3976
3977 (define_insn "*truncdfsf2_2"
3978   [(set (match_operand:SF 0 "nonimmediate_operand" "=Y,Y,!m")
3979         (float_truncate:SF
3980          (match_operand:DF 1 "nonimmediate_operand" "Y,mY,f#Y")))]
3981   "TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
3982    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3983 {
3984   switch (which_alternative)
3985     {
3986     case 0:
3987     case 1:
3988       return "cvtsd2ss\t{%1, %0|%0, %1}";
3989     case 2:
3990       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3991         return "fstp%z0\t%y0";
3992       else
3993         return "fst%z0\t%y0";
3994     default:
3995       abort ();
3996     }
3997 }
3998   [(set_attr "type" "ssecvt,ssecvt,fmov")
3999    (set_attr "athlon_decode" "vector,double,*")
4000    (set_attr "mode" "SF,SF,SF")])
4001
4002 (define_insn "*truncdfsf2_2_nooverlap"
4003   [(set (match_operand:SF 0 "nonimmediate_operand" "=&Y,!m")
4004         (float_truncate:SF
4005          (match_operand:DF 1 "nonimmediate_operand" "mY,f")))]
4006   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS
4007    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
4008 {
4009   switch (which_alternative)
4010     {
4011     case 0:
4012       return "#";
4013     case 1:
4014       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4015         return "fstp%z0\t%y0";
4016       else
4017         return "fst%z0\t%y0";
4018     default:
4019       abort ();
4020     }
4021 }
4022   [(set_attr "type" "ssecvt,fmov")
4023    (set_attr "mode" "DF,SF")])
4024
4025 (define_insn "*truncdfsf2_3"
4026   [(set (match_operand:SF 0 "memory_operand" "=m")
4027         (float_truncate:SF
4028          (match_operand:DF 1 "register_operand" "f")))]
4029   "TARGET_80387"
4030 {
4031   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4032     return "fstp%z0\t%y0";
4033   else
4034     return "fst%z0\t%y0";
4035 }
4036   [(set_attr "type" "fmov")
4037    (set_attr "mode" "SF")])
4038
4039 (define_insn "truncdfsf2_sse_only"
4040   [(set (match_operand:SF 0 "register_operand" "=Y,Y")
4041         (float_truncate:SF
4042          (match_operand:DF 1 "nonimmediate_operand" "Y,mY")))]
4043   "!TARGET_80387 && TARGET_SSE2 && !TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
4044   "cvtsd2ss\t{%1, %0|%0, %1}"
4045   [(set_attr "type" "ssecvt")
4046    (set_attr "athlon_decode" "vector,double")
4047    (set_attr "mode" "SF")])
4048
4049 (define_insn "*truncdfsf2_sse_only_nooverlap"
4050   [(set (match_operand:SF 0 "register_operand" "=&Y")
4051         (float_truncate:SF
4052          (match_operand:DF 1 "nonimmediate_operand" "mY")))]
4053   "!TARGET_80387 && TARGET_SSE2 && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
4054   "#"
4055   [(set_attr "type" "ssecvt")
4056    (set_attr "mode" "DF")])
4057
4058 (define_split
4059   [(set (match_operand:SF 0 "memory_operand" "")
4060         (float_truncate:SF
4061          (match_operand:DF 1 "register_operand" "")))
4062    (clobber (match_operand:SF 2 "memory_operand" ""))]
4063   "TARGET_80387"
4064   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4065   "")
4066
4067 ; Avoid possible reformatting penalty on the destination by first
4068 ; zeroing it out
4069 (define_split
4070   [(set (match_operand:SF 0 "register_operand" "")
4071         (float_truncate:SF
4072          (match_operand:DF 1 "nonimmediate_operand" "")))
4073    (clobber (match_operand 2 "" ""))]
4074   "TARGET_80387 && reload_completed
4075    && SSE_REG_P (operands[0])
4076    && !STACK_REG_P (operands[1])"
4077   [(const_int 0)]
4078 {
4079   rtx src, dest;
4080   if (!TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS)
4081     emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
4082   else
4083     {
4084       dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4085       src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4086       /* simplify_gen_subreg refuses to widen memory references.  */
4087       if (GET_CODE (src) == SUBREG)
4088         alter_subreg (&src);
4089       if (reg_overlap_mentioned_p (operands[0], operands[1]))
4090         abort ();
4091       emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4092       emit_insn (gen_cvtsd2ss (dest, dest, src));
4093     }
4094   DONE;
4095 })
4096
4097 (define_split
4098   [(set (match_operand:SF 0 "register_operand" "")
4099         (float_truncate:SF
4100          (match_operand:DF 1 "nonimmediate_operand" "")))]
4101   "TARGET_80387 && reload_completed
4102    && SSE_REG_P (operands[0]) && TARGET_SSE_PARTIAL_REGS_FOR_CVTSD2SS"
4103   [(const_int 0)]
4104 {
4105   rtx src, dest;
4106   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4107   src = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4108   /* simplify_gen_subreg refuses to widen memory references.  */
4109   if (GET_CODE (src) == SUBREG)
4110     alter_subreg (&src);
4111   if (reg_overlap_mentioned_p (operands[0], operands[1]))
4112     abort ();
4113   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4114   emit_insn (gen_cvtsd2ss (dest, dest, src));
4115   DONE;
4116 })
4117
4118 (define_split
4119   [(set (match_operand:SF 0 "register_operand" "")
4120         (float_truncate:SF
4121          (match_operand:DF 1 "fp_register_operand" "")))
4122    (clobber (match_operand:SF 2 "memory_operand" ""))]
4123   "TARGET_80387 && reload_completed"
4124   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4125    (set (match_dup 0) (match_dup 2))]
4126   "")
4127
4128 (define_expand "truncxfsf2"
4129   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4130                    (float_truncate:SF
4131                     (match_operand:XF 1 "register_operand" "")))
4132               (clobber (match_dup 2))])]
4133   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4134   "operands[2] = assign_386_stack_local (SFmode, 0);")
4135
4136 (define_insn "*truncxfsf2_1"
4137   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4138         (float_truncate:SF
4139          (match_operand:XF 1 "register_operand" "f,f,f,f")))
4140    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4141   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4142 {
4143   switch (which_alternative)
4144     {
4145     case 0:
4146       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4147         return "fstp%z0\t%y0";
4148       else
4149         return "fst%z0\t%y0";
4150     default:
4151       abort();
4152     }
4153 }
4154   [(set_attr "type" "fmov,multi,multi,multi")
4155    (set_attr "mode" "SF")])
4156
4157 (define_insn "*truncxfsf2_2"
4158   [(set (match_operand:SF 0 "memory_operand" "=m")
4159         (float_truncate:SF
4160          (match_operand:XF 1 "register_operand" "f")))]
4161   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4162 {
4163   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4164     return "fstp%z0\t%y0";
4165   else
4166     return "fst%z0\t%y0";
4167 }
4168   [(set_attr "type" "fmov")
4169    (set_attr "mode" "SF")])
4170
4171 (define_split
4172   [(set (match_operand:SF 0 "memory_operand" "")
4173         (float_truncate:SF
4174          (match_operand:XF 1 "register_operand" "")))
4175    (clobber (match_operand:SF 2 "memory_operand" ""))]
4176   "TARGET_80387"
4177   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4178   "")
4179
4180 (define_split
4181   [(set (match_operand:SF 0 "register_operand" "")
4182         (float_truncate:SF
4183          (match_operand:XF 1 "register_operand" "")))
4184    (clobber (match_operand:SF 2 "memory_operand" ""))]
4185   "TARGET_80387 && reload_completed"
4186   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4187    (set (match_dup 0) (match_dup 2))]
4188   "")
4189
4190 (define_expand "trunctfsf2"
4191   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4192                    (float_truncate:SF
4193                     (match_operand:TF 1 "register_operand" "")))
4194               (clobber (match_dup 2))])]
4195   "TARGET_80387"
4196   "operands[2] = assign_386_stack_local (SFmode, 0);")
4197
4198 (define_insn "*trunctfsf2_1"
4199   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
4200         (float_truncate:SF
4201          (match_operand:TF 1 "register_operand" "f,f,f,f")))
4202    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4203   "TARGET_80387"
4204 {
4205   switch (which_alternative)
4206     {
4207     case 0:
4208       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4209         return "fstp%z0\t%y0";
4210       else
4211         return "fst%z0\t%y0";
4212     default:
4213       abort();
4214     }
4215 }
4216   [(set_attr "type" "fmov,multi,multi,multi")
4217    (set_attr "mode" "SF")])
4218
4219 (define_insn "*trunctfsf2_2"
4220   [(set (match_operand:SF 0 "memory_operand" "=m")
4221         (float_truncate:SF
4222          (match_operand:TF 1 "register_operand" "f")))]
4223   "TARGET_80387"
4224 {
4225   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4226     return "fstp%z0\t%y0";
4227   else
4228     return "fst%z0\t%y0";
4229 }
4230   [(set_attr "type" "fmov")
4231    (set_attr "mode" "SF")])
4232
4233 (define_split
4234   [(set (match_operand:SF 0 "memory_operand" "")
4235         (float_truncate:SF
4236          (match_operand:TF 1 "register_operand" "")))
4237    (clobber (match_operand:SF 2 "memory_operand" ""))]
4238   "TARGET_80387"
4239   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4240   "")
4241
4242 (define_split
4243   [(set (match_operand:SF 0 "register_operand" "")
4244         (float_truncate:SF
4245          (match_operand:TF 1 "register_operand" "")))
4246    (clobber (match_operand:SF 2 "memory_operand" ""))]
4247   "TARGET_80387 && reload_completed"
4248   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4249    (set (match_dup 0) (match_dup 2))]
4250   "")
4251
4252
4253 (define_expand "truncxfdf2"
4254   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4255                    (float_truncate:DF
4256                     (match_operand:XF 1 "register_operand" "")))
4257               (clobber (match_dup 2))])]
4258   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4259   "operands[2] = assign_386_stack_local (DFmode, 0);")
4260
4261 (define_insn "*truncxfdf2_1"
4262   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4263         (float_truncate:DF
4264          (match_operand:XF 1 "register_operand" "f,f,f,f")))
4265    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4266   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4267 {
4268   switch (which_alternative)
4269     {
4270     case 0:
4271       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4272         return "fstp%z0\t%y0";
4273       else
4274         return "fst%z0\t%y0";
4275     default:
4276       abort();
4277     }
4278   abort ();
4279 }
4280   [(set_attr "type" "fmov,multi,multi,multi")
4281    (set_attr "mode" "DF")])
4282
4283 (define_insn "*truncxfdf2_2"
4284   [(set (match_operand:DF 0 "memory_operand" "=m")
4285         (float_truncate:DF
4286           (match_operand:XF 1 "register_operand" "f")))]
4287   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4288 {
4289   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4290     return "fstp%z0\t%y0";
4291   else
4292     return "fst%z0\t%y0";
4293 }
4294   [(set_attr "type" "fmov")
4295    (set_attr "mode" "DF")])
4296
4297 (define_split
4298   [(set (match_operand:DF 0 "memory_operand" "")
4299         (float_truncate:DF
4300          (match_operand:XF 1 "register_operand" "")))
4301    (clobber (match_operand:DF 2 "memory_operand" ""))]
4302   "TARGET_80387"
4303   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4304   "")
4305
4306 (define_split
4307   [(set (match_operand:DF 0 "register_operand" "")
4308         (float_truncate:DF
4309          (match_operand:XF 1 "register_operand" "")))
4310    (clobber (match_operand:DF 2 "memory_operand" ""))]
4311   "TARGET_80387 && reload_completed"
4312   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4313    (set (match_dup 0) (match_dup 2))]
4314   "")
4315
4316 (define_expand "trunctfdf2"
4317   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4318                    (float_truncate:DF
4319                     (match_operand:TF 1 "register_operand" "")))
4320               (clobber (match_dup 2))])]
4321   "TARGET_80387"
4322   "operands[2] = assign_386_stack_local (DFmode, 0);")
4323
4324 (define_insn "*trunctfdf2_1"
4325   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
4326         (float_truncate:DF
4327          (match_operand:TF 1 "register_operand" "f,f,f,f")))
4328    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4329   "TARGET_80387"
4330 {
4331   switch (which_alternative)
4332     {
4333     case 0:
4334       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4335         return "fstp%z0\t%y0";
4336       else
4337         return "fst%z0\t%y0";
4338     default:
4339       abort();
4340     }
4341   abort ();
4342 }
4343   [(set_attr "type" "fmov,multi,multi,multi")
4344    (set_attr "mode" "DF")])
4345
4346         (define_insn "*trunctfdf2_2"
4347   [(set (match_operand:DF 0 "memory_operand" "=m")
4348         (float_truncate:DF
4349           (match_operand:TF 1 "register_operand" "f")))]
4350   "TARGET_80387"
4351 {
4352   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4353     return "fstp%z0\t%y0";
4354   else
4355     return "fst%z0\t%y0";
4356 }
4357   [(set_attr "type" "fmov")
4358    (set_attr "mode" "DF")])
4359
4360 (define_split
4361   [(set (match_operand:DF 0 "memory_operand" "")
4362         (float_truncate:DF
4363          (match_operand:TF 1 "register_operand" "")))
4364    (clobber (match_operand:DF 2 "memory_operand" ""))]
4365   "TARGET_80387"
4366   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4367   "")
4368
4369 (define_split
4370   [(set (match_operand:DF 0 "register_operand" "")
4371         (float_truncate:DF
4372          (match_operand:TF 1 "register_operand" "")))
4373    (clobber (match_operand:DF 2 "memory_operand" ""))]
4374   "TARGET_80387 && reload_completed"
4375   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4376    (set (match_dup 0) (match_dup 2))]
4377   "")
4378
4379 \f
4380 ;; %%% Break up all these bad boys.
4381
4382 ;; Signed conversion to DImode.
4383
4384 (define_expand "fix_truncxfdi2"
4385   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4386         (fix:DI (match_operand:XF 1 "register_operand" "")))]
4387   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4388   "")
4389
4390 (define_expand "fix_trunctfdi2"
4391   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4392         (fix:DI (match_operand:TF 1 "register_operand" "")))]
4393   "TARGET_80387"
4394   "")
4395
4396 (define_expand "fix_truncdfdi2"
4397   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4398         (fix:DI (match_operand:DF 1 "register_operand" "")))]
4399   "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
4400 {
4401   if (TARGET_64BIT && TARGET_SSE2)
4402    {
4403      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4404      emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
4405      if (out != operands[0])
4406         emit_move_insn (operands[0], out);
4407      DONE;
4408    }
4409 })
4410
4411 (define_expand "fix_truncsfdi2"
4412   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4413         (fix:DI (match_operand:SF 1 "register_operand" "")))]
4414   "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
4415 {
4416   if (TARGET_SSE && TARGET_64BIT)
4417    {
4418      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4419      emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
4420      if (out != operands[0])
4421         emit_move_insn (operands[0], out);
4422      DONE;
4423    }
4424 })
4425
4426 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4427 ;; of the machinery.
4428 (define_insn_and_split "*fix_truncdi_1"
4429   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4430         (fix:DI (match_operand 1 "register_operand" "f,f")))]
4431   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4432    && !reload_completed && !reload_in_progress
4433    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4434   "#"
4435   "&& 1"
4436   [(const_int 0)]
4437 {
4438   ix86_optimize_mode_switching = 1;
4439   operands[2] = assign_386_stack_local (HImode, 1);
4440   operands[3] = assign_386_stack_local (HImode, 2);
4441   if (memory_operand (operands[0], VOIDmode))
4442     emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
4443                                        operands[2], operands[3]));
4444   else
4445     {
4446       operands[4] = assign_386_stack_local (DImode, 0);
4447       emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
4448                                            operands[2], operands[3],
4449                                            operands[4]));
4450     }
4451   DONE;
4452 }
4453   [(set_attr "type" "fistp")
4454    (set_attr "mode" "DI")])
4455
4456 (define_insn "fix_truncdi_nomemory"
4457   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4458         (fix:DI (match_operand 1 "register_operand" "f,f")))
4459    (use (match_operand:HI 2 "memory_operand" "m,m"))
4460    (use (match_operand:HI 3 "memory_operand" "m,m"))
4461    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4462    (clobber (match_scratch:DF 5 "=&1f,&1f"))]
4463   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4464    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4465   "#"
4466   [(set_attr "type" "fistp")
4467    (set_attr "mode" "DI")])
4468
4469 (define_insn "fix_truncdi_memory"
4470   [(set (match_operand:DI 0 "memory_operand" "=m")
4471         (fix:DI (match_operand 1 "register_operand" "f")))
4472    (use (match_operand:HI 2 "memory_operand" "m"))
4473    (use (match_operand:HI 3 "memory_operand" "m"))
4474    (clobber (match_scratch:DF 4 "=&1f"))]
4475   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4476    && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
4477   "* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
4478   [(set_attr "type" "fistp")
4479    (set_attr "mode" "DI")])
4480
4481 (define_split 
4482   [(set (match_operand:DI 0 "register_operand" "")
4483         (fix:DI (match_operand 1 "register_operand" "")))
4484    (use (match_operand:HI 2 "memory_operand" ""))
4485    (use (match_operand:HI 3 "memory_operand" ""))
4486    (clobber (match_operand:DI 4 "memory_operand" ""))
4487    (clobber (match_scratch 5 ""))]
4488   "reload_completed"
4489   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4490               (use (match_dup 2))
4491               (use (match_dup 3))
4492               (clobber (match_dup 5))])
4493    (set (match_dup 0) (match_dup 4))]
4494   "")
4495
4496 (define_split 
4497   [(set (match_operand:DI 0 "memory_operand" "")
4498         (fix:DI (match_operand 1 "register_operand" "")))
4499    (use (match_operand:HI 2 "memory_operand" ""))
4500    (use (match_operand:HI 3 "memory_operand" ""))
4501    (clobber (match_operand:DI 4 "memory_operand" ""))
4502    (clobber (match_scratch 5 ""))]
4503   "reload_completed"
4504   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4505               (use (match_dup 2))
4506               (use (match_dup 3))
4507               (clobber (match_dup 5))])]
4508   "")
4509
4510 ;; When SSE available, it is always faster to use it!
4511 (define_insn "fix_truncsfdi_sse"
4512   [(set (match_operand:DI 0 "register_operand" "=r,r")
4513         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4514   "TARGET_64BIT && TARGET_SSE"
4515   "cvttss2si{q}\t{%1, %0|%0, %1}"
4516   [(set_attr "type" "sseicvt")
4517    (set_attr "mode" "SF")
4518    (set_attr "athlon_decode" "double,vector")])
4519
4520 ;; Avoid vector decoded form of the instruction.
4521 (define_peephole2
4522   [(match_scratch:SF 2 "x")
4523    (set (match_operand:DI 0 "register_operand" "")
4524         (fix:DI (match_operand:SF 1 "memory_operand" "")))]
4525   "TARGET_K8 && !optimize_size"
4526   [(set (match_dup 2) (match_dup 1))
4527    (set (match_dup 0) (fix:DI (match_dup 2)))]
4528   "")
4529
4530 (define_insn "fix_truncdfdi_sse"
4531   [(set (match_operand:DI 0 "register_operand" "=r,r")
4532         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4533   "TARGET_64BIT && TARGET_SSE2"
4534   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4535   [(set_attr "type" "sseicvt,sseicvt")
4536    (set_attr "mode" "DF")
4537    (set_attr "athlon_decode" "double,vector")])
4538
4539 ;; Avoid vector decoded form of the instruction.
4540 (define_peephole2
4541   [(match_scratch:DF 2 "Y")
4542    (set (match_operand:DI 0 "register_operand" "")
4543         (fix:DI (match_operand:DF 1 "memory_operand" "")))]
4544   "TARGET_K8 && !optimize_size"
4545   [(set (match_dup 2) (match_dup 1))
4546    (set (match_dup 0) (fix:DI (match_dup 2)))]
4547   "")
4548
4549 ;; Signed conversion to SImode.
4550
4551 (define_expand "fix_truncxfsi2"
4552   [(set (match_operand:SI 0 "nonimmediate_operand" "")
4553         (fix:SI (match_operand:XF 1 "register_operand" "")))]
4554   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4555   "")
4556
4557 (define_expand "fix_trunctfsi2"
4558   [(set (match_operand:SI 0 "nonimmediate_operand" "")
4559         (fix:SI (match_operand:TF 1 "register_operand" "")))]
4560   "TARGET_80387"
4561   "")
4562
4563 (define_expand "fix_truncdfsi2"
4564   [(set (match_operand:SI 0 "nonimmediate_operand" "")
4565         (fix:SI (match_operand:DF 1 "register_operand" "")))]
4566   "TARGET_80387 || TARGET_SSE2"
4567 {
4568   if (TARGET_SSE2)
4569    {
4570      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4571      emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
4572      if (out != operands[0])
4573         emit_move_insn (operands[0], out);
4574      DONE;
4575    }
4576 })
4577
4578 (define_expand "fix_truncsfsi2"
4579   [(set (match_operand:SI 0 "nonimmediate_operand" "")
4580         (fix:SI (match_operand:SF 1 "register_operand" "")))]
4581   "TARGET_80387 || TARGET_SSE"
4582 {
4583   if (TARGET_SSE)
4584    {
4585      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4586      emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
4587      if (out != operands[0])
4588         emit_move_insn (operands[0], out);
4589      DONE;
4590    }
4591 })
4592
4593 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4594 ;; of the machinery.
4595 (define_insn_and_split "*fix_truncsi_1"
4596   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4597         (fix:SI (match_operand 1 "register_operand" "f,f")))]
4598   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4599    && !reload_completed && !reload_in_progress
4600    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4601   "#"
4602   "&& 1"
4603   [(const_int 0)]
4604 {
4605   ix86_optimize_mode_switching = 1;
4606   operands[2] = assign_386_stack_local (HImode, 1);
4607   operands[3] = assign_386_stack_local (HImode, 2);
4608   if (memory_operand (operands[0], VOIDmode))
4609     emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
4610                                        operands[2], operands[3]));
4611   else
4612     {
4613       operands[4] = assign_386_stack_local (SImode, 0);
4614       emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
4615                                            operands[2], operands[3],
4616                                            operands[4]));
4617     }
4618   DONE;
4619 }
4620   [(set_attr "type" "fistp")
4621    (set_attr "mode" "SI")])
4622
4623 (define_insn "fix_truncsi_nomemory"
4624   [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
4625         (fix:SI (match_operand 1 "register_operand" "f,f")))
4626    (use (match_operand:HI 2 "memory_operand" "m,m"))
4627    (use (match_operand:HI 3 "memory_operand" "m,m"))
4628    (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
4629   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4630    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4631   "#"
4632   [(set_attr "type" "fistp")
4633    (set_attr "mode" "SI")])
4634
4635 (define_insn "fix_truncsi_memory"
4636   [(set (match_operand:SI 0 "memory_operand" "=m")
4637         (fix:SI (match_operand 1 "register_operand" "f")))
4638    (use (match_operand:HI 2 "memory_operand" "m"))
4639    (use (match_operand:HI 3 "memory_operand" "m"))]
4640   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4641    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4642   "* return output_fix_trunc (insn, operands);"
4643   [(set_attr "type" "fistp")
4644    (set_attr "mode" "SI")])
4645
4646 ;; When SSE available, it is always faster to use it!
4647 (define_insn "fix_truncsfsi_sse"
4648   [(set (match_operand:SI 0 "register_operand" "=r,r")
4649         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4650   "TARGET_SSE"
4651   "cvttss2si\t{%1, %0|%0, %1}"
4652   [(set_attr "type" "sseicvt")
4653    (set_attr "mode" "DF")
4654    (set_attr "athlon_decode" "double,vector")])
4655
4656 ;; Avoid vector decoded form of the instruction.
4657 (define_peephole2
4658   [(match_scratch:SF 2 "x")
4659    (set (match_operand:SI 0 "register_operand" "")
4660         (fix:SI (match_operand:SF 1 "memory_operand" "")))]
4661   "TARGET_K8 && !optimize_size"
4662   [(set (match_dup 2) (match_dup 1))
4663    (set (match_dup 0) (fix:SI (match_dup 2)))]
4664   "")
4665
4666 (define_insn "fix_truncdfsi_sse"
4667   [(set (match_operand:SI 0 "register_operand" "=r,r")
4668         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4669   "TARGET_SSE2"
4670   "cvttsd2si\t{%1, %0|%0, %1}"
4671   [(set_attr "type" "sseicvt")
4672    (set_attr "mode" "DF")
4673    (set_attr "athlon_decode" "double,vector")])
4674
4675 ;; Avoid vector decoded form of the instruction.
4676 (define_peephole2
4677   [(match_scratch:DF 2 "Y")
4678    (set (match_operand:SI 0 "register_operand" "")
4679         (fix:SI (match_operand:DF 1 "memory_operand" "")))]
4680   "TARGET_K8 && !optimize_size"
4681   [(set (match_dup 2) (match_dup 1))
4682    (set (match_dup 0) (fix:SI (match_dup 2)))]
4683   "")
4684
4685 (define_split 
4686   [(set (match_operand:SI 0 "register_operand" "")
4687         (fix:SI (match_operand 1 "register_operand" "")))
4688    (use (match_operand:HI 2 "memory_operand" ""))
4689    (use (match_operand:HI 3 "memory_operand" ""))
4690    (clobber (match_operand:SI 4 "memory_operand" ""))]
4691   "reload_completed"
4692   [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
4693               (use (match_dup 2))
4694               (use (match_dup 3))])
4695    (set (match_dup 0) (match_dup 4))]
4696   "")
4697
4698 (define_split 
4699   [(set (match_operand:SI 0 "memory_operand" "")
4700         (fix:SI (match_operand 1 "register_operand" "")))
4701    (use (match_operand:HI 2 "memory_operand" ""))
4702    (use (match_operand:HI 3 "memory_operand" ""))
4703    (clobber (match_operand:SI 4 "memory_operand" ""))]
4704   "reload_completed"
4705   [(parallel [(set (match_dup 0) (fix:SI (match_dup 1)))
4706               (use (match_dup 2))
4707               (use (match_dup 3))])]
4708   "")
4709
4710 ;; Signed conversion to HImode.
4711
4712 (define_expand "fix_truncxfhi2"
4713   [(set (match_operand:HI 0 "nonimmediate_operand" "")
4714         (fix:HI (match_operand:XF 1 "register_operand" "")))]
4715   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
4716   "")
4717
4718 (define_expand "fix_trunctfhi2"
4719   [(set (match_operand:HI 0 "nonimmediate_operand" "")
4720         (fix:HI (match_operand:TF 1 "register_operand" "")))]
4721   "TARGET_80387"
4722   "")
4723
4724 (define_expand "fix_truncdfhi2"
4725   [(set (match_operand:HI 0 "nonimmediate_operand" "")
4726         (fix:HI (match_operand:DF 1 "register_operand" "")))]
4727   "TARGET_80387 && !TARGET_SSE2"
4728   "")
4729
4730 (define_expand "fix_truncsfhi2"
4731   [(set (match_operand:HI 0 "nonimmediate_operand" "")
4732         (fix:HI (match_operand:SF 1 "register_operand" "")))]
4733   "TARGET_80387 && !TARGET_SSE"
4734   "")
4735
4736 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4737 ;; of the machinery.
4738 (define_insn_and_split "*fix_trunchi_1"
4739   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4740         (fix:HI (match_operand 1 "register_operand" "f,f")))]
4741   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4742    && !reload_completed && !reload_in_progress
4743    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4744   "#"
4745   ""
4746   [(const_int 0)]
4747 {
4748   ix86_optimize_mode_switching = 1;
4749   operands[2] = assign_386_stack_local (HImode, 1);
4750   operands[3] = assign_386_stack_local (HImode, 2);
4751   if (memory_operand (operands[0], VOIDmode))
4752     emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
4753                                        operands[2], operands[3]));
4754   else
4755     {
4756       operands[4] = assign_386_stack_local (HImode, 0);
4757       emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
4758                                            operands[2], operands[3],
4759                                            operands[4]));
4760     }
4761   DONE;
4762 }
4763   [(set_attr "type" "fistp")
4764    (set_attr "mode" "HI")])
4765
4766 (define_insn "fix_trunchi_nomemory"
4767   [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
4768         (fix:HI (match_operand 1 "register_operand" "f,f")))
4769    (use (match_operand:HI 2 "memory_operand" "m,m"))
4770    (use (match_operand:HI 3 "memory_operand" "m,m"))
4771    (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
4772   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4773    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4774   "#"
4775   [(set_attr "type" "fistp")
4776    (set_attr "mode" "HI")])
4777
4778 (define_insn "fix_trunchi_memory"
4779   [(set (match_operand:HI 0 "memory_operand" "=m")
4780         (fix:HI (match_operand 1 "register_operand" "f")))
4781    (use (match_operand:HI 2 "memory_operand" "m"))
4782    (use (match_operand:HI 3 "memory_operand" "m"))]
4783   "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
4784    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4785   "* return output_fix_trunc (insn, operands);"
4786   [(set_attr "type" "fistp")
4787    (set_attr "mode" "HI")])
4788
4789 (define_split 
4790   [(set (match_operand:HI 0 "memory_operand" "")
4791         (fix:HI (match_operand 1 "register_operand" "")))
4792    (use (match_operand:HI 2 "memory_operand" ""))
4793    (use (match_operand:HI 3 "memory_operand" ""))
4794    (clobber (match_operand:HI 4 "memory_operand" ""))]
4795   "reload_completed"
4796   [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
4797               (use (match_dup 2))
4798               (use (match_dup 3))])]
4799   "")
4800
4801 (define_split 
4802   [(set (match_operand:HI 0 "register_operand" "")
4803         (fix:HI (match_operand 1 "register_operand" "")))
4804    (use (match_operand:HI 2 "memory_operand" ""))
4805    (use (match_operand:HI 3 "memory_operand" ""))
4806    (clobber (match_operand:HI 4 "memory_operand" ""))]
4807   "reload_completed"
4808   [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
4809               (use (match_dup 2))
4810               (use (match_dup 3))
4811               (clobber (match_dup 4))])
4812    (set (match_dup 0) (match_dup 4))]
4813   "")
4814
4815 ;; %% Not used yet.
4816 (define_insn "x86_fnstcw_1"
4817   [(set (match_operand:HI 0 "memory_operand" "=m")
4818         (unspec:HI [(reg:HI 18)] UNSPEC_FSTCW))]
4819   "TARGET_80387"
4820   "fnstcw\t%0"
4821   [(set_attr "length" "2")
4822    (set_attr "mode" "HI")
4823    (set_attr "unit" "i387")
4824    (set_attr "ppro_uops" "few")])
4825
4826 (define_insn "x86_fldcw_1"
4827   [(set (reg:HI 18)
4828         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4829   "TARGET_80387"
4830   "fldcw\t%0"
4831   [(set_attr "length" "2")
4832    (set_attr "mode" "HI")
4833    (set_attr "unit" "i387")
4834    (set_attr "athlon_decode" "vector")
4835    (set_attr "ppro_uops" "few")])
4836 \f
4837 ;; Conversion between fixed point and floating point.
4838
4839 ;; Even though we only accept memory inputs, the backend _really_
4840 ;; wants to be able to do this between registers.
4841
4842 (define_expand "floathisf2"
4843   [(set (match_operand:SF 0 "register_operand" "")
4844         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4845   "TARGET_SSE || TARGET_80387"
4846 {
4847   if (TARGET_SSE && TARGET_SSE_MATH)
4848     {
4849       emit_insn (gen_floatsisf2 (operands[0],
4850                                  convert_to_mode (SImode, operands[1], 0)));
4851       DONE;
4852     }
4853 })
4854
4855 (define_insn "*floathisf2_1"
4856   [(set (match_operand:SF 0 "register_operand" "=f,f")
4857         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4858   "TARGET_80387 && (!TARGET_SSE || !TARGET_SSE_MATH)"
4859   "@
4860    fild%z1\t%1
4861    #"
4862   [(set_attr "type" "fmov,multi")
4863    (set_attr "mode" "SF")
4864    (set_attr "fp_int_src" "true")])
4865
4866 (define_expand "floatsisf2"
4867   [(set (match_operand:SF 0 "register_operand" "")
4868         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4869   "TARGET_SSE || TARGET_80387"
4870   "")
4871
4872 (define_insn "*floatsisf2_i387"
4873   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4874         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4875   "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4876   "@
4877    fild%z1\t%1
4878    #
4879    cvtsi2ss\t{%1, %0|%0, %1}
4880    cvtsi2ss\t{%1, %0|%0, %1}"
4881   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4882    (set_attr "mode" "SF")
4883    (set_attr "athlon_decode" "*,*,vector,double")
4884    (set_attr "fp_int_src" "true")])
4885
4886 (define_insn "*floatsisf2_sse"
4887   [(set (match_operand:SF 0 "register_operand" "=x,x")
4888         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4889   "TARGET_SSE"
4890   "cvtsi2ss\t{%1, %0|%0, %1}"
4891   [(set_attr "type" "sseicvt")
4892    (set_attr "mode" "SF")
4893    (set_attr "athlon_decode" "vector,double")
4894    (set_attr "fp_int_src" "true")])
4895
4896 ; Avoid possible reformatting penalty on the destination by first
4897 ; zeroing it out
4898 (define_split
4899   [(set (match_operand:SF 0 "register_operand" "")
4900         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4901   "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4902    && SSE_REG_P (operands[0])"
4903   [(const_int 0)]
4904 {
4905   rtx dest;
4906   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4907   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4908   emit_insn (gen_cvtsi2ss (dest, dest, operands[1]));
4909   DONE;
4910 })
4911
4912 (define_expand "floatdisf2"
4913   [(set (match_operand:SF 0 "register_operand" "")
4914         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4915   "(TARGET_64BIT && TARGET_SSE) || TARGET_80387"
4916   "")
4917
4918 (define_insn "*floatdisf2_i387_only"
4919   [(set (match_operand:SF 0 "register_operand" "=f,?f")
4920         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
4921   "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
4922   "@
4923    fild%z1\t%1
4924    #"
4925   [(set_attr "type" "fmov,multi")
4926    (set_attr "mode" "SF")
4927    (set_attr "fp_int_src" "true")])
4928
4929 (define_insn "*floatdisf2_i387"
4930   [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4931         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4932   "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
4933   "@
4934    fild%z1\t%1
4935    #
4936    cvtsi2ss{q}\t{%1, %0|%0, %1}
4937    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4938   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4939    (set_attr "mode" "SF")
4940    (set_attr "athlon_decode" "*,*,vector,double")
4941    (set_attr "fp_int_src" "true")])
4942
4943 (define_insn "*floatdisf2_sse"
4944   [(set (match_operand:SF 0 "register_operand" "=x,x")
4945         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4946   "TARGET_64BIT && TARGET_SSE"
4947   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4948   [(set_attr "type" "sseicvt")
4949    (set_attr "mode" "SF")
4950    (set_attr "athlon_decode" "vector,double")
4951    (set_attr "fp_int_src" "true")])
4952
4953 ; Avoid possible reformatting penalty on the destination by first
4954 ; zeroing it out
4955 (define_split
4956   [(set (match_operand:SF 0 "register_operand" "")
4957         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4958   "TARGET_80387 && reload_completed && TARGET_SSE_PARTIAL_REGS
4959    && SSE_REG_P (operands[0])"
4960   [(const_int 0)]
4961 {
4962   rtx dest;
4963   dest = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4964   emit_insn (gen_sse_clrv4sf (dest, CONST0_RTX (V4SFmode)));
4965   emit_insn (gen_cvtsi2ssq (dest, dest, operands[1]));
4966   DONE;
4967 })
4968
4969 (define_expand "floathidf2"
4970   [(set (match_operand:DF 0 "register_operand" "")
4971         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4972   "TARGET_SSE2 || TARGET_80387"
4973 {
4974   if (TARGET_SSE && TARGET_SSE_MATH)
4975     {
4976       emit_insn (gen_floatsidf2 (operands[0],
4977                                  convert_to_mode (SImode, operands[1], 0)));
4978       DONE;
4979     }
4980 })
4981
4982 (define_insn "*floathidf2_1"
4983   [(set (match_operand:DF 0 "register_operand" "=f,f")
4984         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
4985   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
4986   "@
4987    fild%z1\t%1
4988    #"
4989   [(set_attr "type" "fmov,multi")
4990    (set_attr "mode" "DF")
4991    (set_attr "fp_int_src" "true")])
4992
4993 (define_expand "floatsidf2"
4994   [(set (match_operand:DF 0 "register_operand" "")
4995         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4996   "TARGET_80387 || TARGET_SSE2"
4997   "")
4998
4999 (define_insn "*floatsidf2_i387"
5000   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
5001         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
5002   "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
5003   "@
5004    fild%z1\t%1
5005    #
5006    cvtsi2sd\t{%1, %0|%0, %1}
5007    cvtsi2sd\t{%1, %0|%0, %1}"
5008   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5009    (set_attr "mode" "DF")
5010    (set_attr "athlon_decode" "*,*,double,direct")
5011    (set_attr "fp_int_src" "true")])
5012
5013 (define_insn "*floatsidf2_sse"
5014   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
5015         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
5016   "TARGET_SSE2"
5017   "cvtsi2sd\t{%1, %0|%0, %1}"
5018   [(set_attr "type" "sseicvt")
5019    (set_attr "mode" "DF")
5020    (set_attr "athlon_decode" "double,direct")
5021    (set_attr "fp_int_src" "true")])
5022
5023 (define_expand "floatdidf2"
5024   [(set (match_operand:DF 0 "register_operand" "")
5025         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
5026   "(TARGET_64BIT && TARGET_SSE2) || TARGET_80387"
5027   "")
5028
5029 (define_insn "*floatdidf2_i387_only"
5030   [(set (match_operand:DF 0 "register_operand" "=f,?f")
5031         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5032   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT)"
5033   "@
5034    fild%z1\t%1
5035    #"
5036   [(set_attr "type" "fmov,multi")
5037    (set_attr "mode" "DF")
5038    (set_attr "fp_int_src" "true")])
5039
5040 (define_insn "*floatdidf2_i387"
5041   [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
5042         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
5043   "TARGET_64BIT && TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
5044   "@
5045    fild%z1\t%1
5046    #
5047    cvtsi2sd{q}\t{%1, %0|%0, %1}
5048    cvtsi2sd{q}\t{%1, %0|%0, %1}"
5049   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5050    (set_attr "mode" "DF")
5051    (set_attr "athlon_decode" "*,*,double,direct")
5052    (set_attr "fp_int_src" "true")])
5053
5054 (define_insn "*floatdidf2_sse"
5055   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
5056         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
5057   "TARGET_SSE2"
5058   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
5059   [(set_attr "type" "sseicvt")
5060    (set_attr "mode" "DF")
5061    (set_attr "athlon_decode" "double,direct")
5062    (set_attr "fp_int_src" "true")])
5063
5064 (define_insn "floathixf2"
5065   [(set (match_operand:XF 0 "register_operand" "=f,f")
5066         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5067   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
5068   "@
5069    fild%z1\t%1
5070    #"
5071   [(set_attr "type" "fmov,multi")
5072    (set_attr "mode" "XF")
5073    (set_attr "fp_int_src" "true")])
5074
5075 (define_insn "floathitf2"
5076   [(set (match_operand:TF 0 "register_operand" "=f,f")
5077         (float:TF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
5078   "TARGET_80387"
5079   "@
5080    fild%z1\t%1
5081    #"
5082   [(set_attr "type" "fmov,multi")
5083    (set_attr "mode" "XF")
5084    (set_attr "fp_int_src" "true")])
5085
5086 (define_insn "floatsixf2"
5087   [(set (match_operand:XF 0 "register_operand" "=f,f")
5088         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
5089   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
5090   "@
5091    fild%z1\t%1
5092    #"
5093   [(set_attr "type" "fmov,multi")
5094    (set_attr "mode" "XF")
5095    (set_attr "fp_int_src" "true")])
5096
5097 (define_insn "floatsitf2"
5098   [(set (match_operand:TF 0 "register_operand" "=f,f")
5099         (float:TF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
5100   "TARGET_80387"
5101   "@
5102    fild%z1\t%1
5103    #"
5104   [(set_attr "type" "fmov,multi")
5105    (set_attr "mode" "XF")
5106    (set_attr "fp_int_src" "true")])
5107
5108 (define_insn "floatdixf2"
5109   [(set (match_operand:XF 0 "register_operand" "=f,f")
5110         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5111   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
5112   "@
5113    fild%z1\t%1
5114    #"
5115   [(set_attr "type" "fmov,multi")
5116    (set_attr "mode" "XF")
5117    (set_attr "fp_int_src" "true")])
5118
5119 (define_insn "floatditf2"
5120   [(set (match_operand:TF 0 "register_operand" "=f,f")
5121         (float:TF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
5122   "TARGET_80387"
5123   "@
5124    fild%z1\t%1
5125    #"
5126   [(set_attr "type" "fmov,multi")
5127    (set_attr "mode" "XF")
5128    (set_attr "fp_int_src" "true")])
5129
5130 ;; %%% Kill these when reload knows how to do it.
5131 (define_split
5132   [(set (match_operand 0 "fp_register_operand" "")
5133         (float (match_operand 1 "register_operand" "")))]
5134   "reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
5135   [(const_int 0)]
5136 {
5137   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5138   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5139   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5140   ix86_free_from_memory (GET_MODE (operands[1]));
5141   DONE;
5142 })
5143
5144 (define_expand "floatunssisf2"
5145   [(use (match_operand:SF 0 "register_operand" ""))
5146    (use (match_operand:SI 1 "register_operand" ""))]
5147   "TARGET_SSE && TARGET_SSE_MATH && !TARGET_64BIT"
5148   "x86_emit_floatuns (operands); DONE;")
5149
5150 (define_expand "floatunsdisf2"
5151   [(use (match_operand:SF 0 "register_operand" ""))
5152    (use (match_operand:DI 1 "register_operand" ""))]
5153   "TARGET_SSE && TARGET_SSE_MATH && TARGET_64BIT"
5154   "x86_emit_floatuns (operands); DONE;")
5155
5156 (define_expand "floatunsdidf2"
5157   [(use (match_operand:DF 0 "register_operand" ""))
5158    (use (match_operand:DI 1 "register_operand" ""))]
5159   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_64BIT"
5160   "x86_emit_floatuns (operands); DONE;")
5161 \f
5162 ;; Add instructions
5163
5164 ;; %%% splits for addsidi3
5165 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5166 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5167 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5168
5169 (define_expand "adddi3"
5170   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5171         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5172                  (match_operand:DI 2 "x86_64_general_operand" "")))
5173    (clobber (reg:CC 17))]
5174   ""
5175   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5176
5177 (define_insn "*adddi3_1"
5178   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5179         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5180                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5181    (clobber (reg:CC 17))]
5182   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5183   "#")
5184
5185 (define_split
5186   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5187         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5188                  (match_operand:DI 2 "general_operand" "")))
5189    (clobber (reg:CC 17))]
5190   "!TARGET_64BIT && reload_completed"
5191   [(parallel [(set (reg:CC 17) (unspec:CC [(match_dup 1) (match_dup 2)]
5192                                           UNSPEC_ADD_CARRY))
5193               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5194    (parallel [(set (match_dup 3)
5195                    (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
5196                                      (match_dup 4))
5197                             (match_dup 5)))
5198               (clobber (reg:CC 17))])]
5199   "split_di (operands+0, 1, operands+0, operands+3);
5200    split_di (operands+1, 1, operands+1, operands+4);
5201    split_di (operands+2, 1, operands+2, operands+5);")
5202
5203 (define_insn "adddi3_carry_rex64"
5204   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5205           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5206                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5207                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5208    (clobber (reg:CC 17))]
5209   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5210   "adc{q}\t{%2, %0|%0, %2}"
5211   [(set_attr "type" "alu")
5212    (set_attr "pent_pair" "pu")
5213    (set_attr "mode" "DI")
5214    (set_attr "ppro_uops" "few")])
5215
5216 (define_insn "*adddi3_cc_rex64"
5217   [(set (reg:CC 17)
5218         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5219                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5220                    UNSPEC_ADD_CARRY))
5221    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5222         (plus:DI (match_dup 1) (match_dup 2)))]
5223   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5224   "add{q}\t{%2, %0|%0, %2}"
5225   [(set_attr "type" "alu")
5226    (set_attr "mode" "DI")])
5227
5228 (define_insn "addqi3_carry"
5229   [(set (match_operand:QI 0 "nonimmediate_operand" "=rm,r")
5230           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5231                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5232                    (match_operand:QI 2 "general_operand" "ri,rm")))
5233    (clobber (reg:CC 17))]
5234   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5235   "adc{b}\t{%2, %0|%0, %2}"
5236   [(set_attr "type" "alu")
5237    (set_attr "pent_pair" "pu")
5238    (set_attr "mode" "QI")
5239    (set_attr "ppro_uops" "few")])
5240
5241 (define_insn "addhi3_carry"
5242   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5243           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5244                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5245                    (match_operand:HI 2 "general_operand" "ri,rm")))
5246    (clobber (reg:CC 17))]
5247   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5248   "adc{w}\t{%2, %0|%0, %2}"
5249   [(set_attr "type" "alu")
5250    (set_attr "pent_pair" "pu")
5251    (set_attr "mode" "HI")
5252    (set_attr "ppro_uops" "few")])
5253
5254 (define_insn "addsi3_carry"
5255   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5256           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5257                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5258                    (match_operand:SI 2 "general_operand" "ri,rm")))
5259    (clobber (reg:CC 17))]
5260   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5261   "adc{l}\t{%2, %0|%0, %2}"
5262   [(set_attr "type" "alu")
5263    (set_attr "pent_pair" "pu")
5264    (set_attr "mode" "SI")
5265    (set_attr "ppro_uops" "few")])
5266
5267 (define_insn "*addsi3_carry_zext"
5268   [(set (match_operand:DI 0 "register_operand" "=r")
5269           (zero_extend:DI 
5270             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5271                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5272                      (match_operand:SI 2 "general_operand" "rim"))))
5273    (clobber (reg:CC 17))]
5274   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5275   "adc{l}\t{%2, %k0|%k0, %2}"
5276   [(set_attr "type" "alu")
5277    (set_attr "pent_pair" "pu")
5278    (set_attr "mode" "SI")
5279    (set_attr "ppro_uops" "few")])
5280
5281 (define_insn "*addsi3_cc"
5282   [(set (reg:CC 17)
5283         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5284                     (match_operand:SI 2 "general_operand" "ri,rm")]
5285                    UNSPEC_ADD_CARRY))
5286    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5287         (plus:SI (match_dup 1) (match_dup 2)))]
5288   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5289   "add{l}\t{%2, %0|%0, %2}"
5290   [(set_attr "type" "alu")
5291    (set_attr "mode" "SI")])
5292
5293 (define_insn "addqi3_cc"
5294   [(set (reg:CC 17)
5295         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5296                     (match_operand:QI 2 "general_operand" "qi,qm")]
5297                    UNSPEC_ADD_CARRY))
5298    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5299         (plus:QI (match_dup 1) (match_dup 2)))]
5300   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5301   "add{b}\t{%2, %0|%0, %2}"
5302   [(set_attr "type" "alu")
5303    (set_attr "mode" "QI")])
5304
5305 (define_expand "addsi3"
5306   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5307                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5308                             (match_operand:SI 2 "general_operand" "")))
5309               (clobber (reg:CC 17))])]
5310   ""
5311   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5312
5313 (define_insn "*lea_1"
5314   [(set (match_operand:SI 0 "register_operand" "=r")
5315         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5316   "!TARGET_64BIT"
5317   "lea{l}\t{%a1, %0|%0, %a1}"
5318   [(set_attr "type" "lea")
5319    (set_attr "mode" "SI")])
5320
5321 (define_insn "*lea_1_rex64"
5322   [(set (match_operand:SI 0 "register_operand" "=r")
5323         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5324   "TARGET_64BIT"
5325   "lea{l}\t{%a1, %0|%0, %a1}"
5326   [(set_attr "type" "lea")
5327    (set_attr "mode" "SI")])
5328
5329 (define_insn "*lea_1_zext"
5330   [(set (match_operand:DI 0 "register_operand" "=r")
5331         (zero_extend:DI
5332          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5333   "TARGET_64BIT"
5334   "lea{l}\t{%a1, %k0|%k0, %a1}"
5335   [(set_attr "type" "lea")
5336    (set_attr "mode" "SI")])
5337
5338 (define_insn "*lea_2_rex64"
5339   [(set (match_operand:DI 0 "register_operand" "=r")
5340         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5341   "TARGET_64BIT"
5342   "lea{q}\t{%a1, %0|%0, %a1}"
5343   [(set_attr "type" "lea")
5344    (set_attr "mode" "DI")])
5345
5346 ;; The lea patterns for non-Pmodes needs to be matched by several
5347 ;; insns converted to real lea by splitters.
5348
5349 (define_insn_and_split "*lea_general_1"
5350   [(set (match_operand 0 "register_operand" "=r")
5351         (plus (plus (match_operand 1 "index_register_operand" "r")
5352                     (match_operand 2 "register_operand" "r"))
5353               (match_operand 3 "immediate_operand" "i")))]
5354   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5355     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5356    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5357    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5358    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5359    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5360        || GET_MODE (operands[3]) == VOIDmode)"
5361   "#"
5362   "&& reload_completed"
5363   [(const_int 0)]
5364 {
5365   rtx pat;
5366   operands[0] = gen_lowpart (SImode, operands[0]);
5367   operands[1] = gen_lowpart (Pmode, operands[1]);
5368   operands[2] = gen_lowpart (Pmode, operands[2]);
5369   operands[3] = gen_lowpart (Pmode, operands[3]);
5370   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5371                       operands[3]);
5372   if (Pmode != SImode)
5373     pat = gen_rtx_SUBREG (SImode, pat, 0);
5374   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5375   DONE;
5376 }
5377   [(set_attr "type" "lea")
5378    (set_attr "mode" "SI")])
5379
5380 (define_insn_and_split "*lea_general_1_zext"
5381   [(set (match_operand:DI 0 "register_operand" "=r")
5382         (zero_extend:DI
5383           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "r")
5384                             (match_operand:SI 2 "register_operand" "r"))
5385                    (match_operand:SI 3 "immediate_operand" "i"))))]
5386   "TARGET_64BIT"
5387   "#"
5388   "&& reload_completed"
5389   [(set (match_dup 0)
5390         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5391                                                      (match_dup 2))
5392                                             (match_dup 3)) 0)))]
5393 {
5394   operands[1] = gen_lowpart (Pmode, operands[1]);
5395   operands[2] = gen_lowpart (Pmode, operands[2]);
5396   operands[3] = gen_lowpart (Pmode, operands[3]);
5397 }
5398   [(set_attr "type" "lea")
5399    (set_attr "mode" "SI")])
5400
5401 (define_insn_and_split "*lea_general_2"
5402   [(set (match_operand 0 "register_operand" "=r")
5403         (plus (mult (match_operand 1 "index_register_operand" "r")
5404                     (match_operand 2 "const248_operand" "i"))
5405               (match_operand 3 "nonmemory_operand" "ri")))]
5406   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5407     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5408    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5409    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5410    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5411        || GET_MODE (operands[3]) == VOIDmode)"
5412   "#"
5413   "&& reload_completed"
5414   [(const_int 0)]
5415 {
5416   rtx pat;
5417   operands[0] = gen_lowpart (SImode, operands[0]);
5418   operands[1] = gen_lowpart (Pmode, operands[1]);
5419   operands[3] = gen_lowpart (Pmode, operands[3]);
5420   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5421                       operands[3]);
5422   if (Pmode != SImode)
5423     pat = gen_rtx_SUBREG (SImode, pat, 0);
5424   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5425   DONE;
5426 }
5427   [(set_attr "type" "lea")
5428    (set_attr "mode" "SI")])
5429
5430 (define_insn_and_split "*lea_general_2_zext"
5431   [(set (match_operand:DI 0 "register_operand" "=r")
5432         (zero_extend:DI
5433           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5434                             (match_operand:SI 2 "const248_operand" "n"))
5435                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5436   "TARGET_64BIT"
5437   "#"
5438   "&& reload_completed"
5439   [(set (match_dup 0)
5440         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5441                                                      (match_dup 2))
5442                                             (match_dup 3)) 0)))]
5443 {
5444   operands[1] = gen_lowpart (Pmode, operands[1]);
5445   operands[3] = gen_lowpart (Pmode, operands[3]);
5446 }
5447   [(set_attr "type" "lea")
5448    (set_attr "mode" "SI")])
5449
5450 (define_insn_and_split "*lea_general_3"
5451   [(set (match_operand 0 "register_operand" "=r")
5452         (plus (plus (mult (match_operand 1 "index_register_operand" "r")
5453                           (match_operand 2 "const248_operand" "i"))
5454                     (match_operand 3 "register_operand" "r"))
5455               (match_operand 4 "immediate_operand" "i")))]
5456   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5457     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5458    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5459    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5460    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5461   "#"
5462   "&& reload_completed"
5463   [(const_int 0)]
5464 {
5465   rtx pat;
5466   operands[0] = gen_lowpart (SImode, operands[0]);
5467   operands[1] = gen_lowpart (Pmode, operands[1]);
5468   operands[3] = gen_lowpart (Pmode, operands[3]);
5469   operands[4] = gen_lowpart (Pmode, operands[4]);
5470   pat = gen_rtx_PLUS (Pmode,
5471                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5472                                                          operands[2]),
5473                                     operands[3]),
5474                       operands[4]);
5475   if (Pmode != SImode)
5476     pat = gen_rtx_SUBREG (SImode, pat, 0);
5477   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5478   DONE;
5479 }
5480   [(set_attr "type" "lea")
5481    (set_attr "mode" "SI")])
5482
5483 (define_insn_and_split "*lea_general_3_zext"
5484   [(set (match_operand:DI 0 "register_operand" "=r")
5485         (zero_extend:DI
5486           (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "r")
5487                                      (match_operand:SI 2 "const248_operand" "n"))
5488                             (match_operand:SI 3 "register_operand" "r"))
5489                    (match_operand:SI 4 "immediate_operand" "i"))))]
5490   "TARGET_64BIT"
5491   "#"
5492   "&& reload_completed"
5493   [(set (match_dup 0)
5494         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5495                                                               (match_dup 2))
5496                                                      (match_dup 3))
5497                                             (match_dup 4)) 0)))]
5498 {
5499   operands[1] = gen_lowpart (Pmode, operands[1]);
5500   operands[3] = gen_lowpart (Pmode, operands[3]);
5501   operands[4] = gen_lowpart (Pmode, operands[4]);
5502 }
5503   [(set_attr "type" "lea")
5504    (set_attr "mode" "SI")])
5505
5506 (define_insn "*adddi_1_rex64"
5507   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5508         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5509                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,re")))
5510    (clobber (reg:CC 17))]
5511   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5512 {
5513   switch (get_attr_type (insn))
5514     {
5515     case TYPE_LEA:
5516       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5517       return "lea{q}\t{%a2, %0|%0, %a2}";
5518
5519     case TYPE_INCDEC:
5520       if (! rtx_equal_p (operands[0], operands[1]))
5521         abort ();
5522       if (operands[2] == const1_rtx)
5523         return "inc{q}\t%0";
5524       else if (operands[2] == constm1_rtx)
5525         return "dec{q}\t%0";
5526       else
5527         abort ();
5528
5529     default:
5530       if (! rtx_equal_p (operands[0], operands[1]))
5531         abort ();
5532
5533       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5534          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5535       if (GET_CODE (operands[2]) == CONST_INT
5536           /* Avoid overflows.  */
5537           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5538           && (INTVAL (operands[2]) == 128
5539               || (INTVAL (operands[2]) < 0
5540                   && INTVAL (operands[2]) != -128)))
5541         {
5542           operands[2] = GEN_INT (-INTVAL (operands[2]));
5543           return "sub{q}\t{%2, %0|%0, %2}";
5544         }
5545       return "add{q}\t{%2, %0|%0, %2}";
5546     }
5547 }
5548   [(set (attr "type")
5549      (cond [(eq_attr "alternative" "2")
5550               (const_string "lea")
5551             ; Current assemblers are broken and do not allow @GOTOFF in
5552             ; ought but a memory context.
5553             (match_operand:DI 2 "pic_symbolic_operand" "")
5554               (const_string "lea")
5555             (match_operand:DI 2 "incdec_operand" "")
5556               (const_string "incdec")
5557            ]
5558            (const_string "alu")))
5559    (set_attr "mode" "DI")])
5560
5561 ;; Convert lea to the lea pattern to avoid flags dependency.
5562 (define_split
5563   [(set (match_operand:DI 0 "register_operand" "")
5564         (plus:DI (match_operand:DI 1 "register_operand" "")
5565                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5566    (clobber (reg:CC 17))]
5567   "TARGET_64BIT && reload_completed
5568    && true_regnum (operands[0]) != true_regnum (operands[1])"
5569   [(set (match_dup 0)
5570         (plus:DI (match_dup 1)
5571                  (match_dup 2)))]
5572   "")
5573
5574 (define_insn "*adddi_2_rex64"
5575   [(set (reg 17)
5576         (compare
5577           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5578                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5579           (const_int 0)))                       
5580    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5581         (plus:DI (match_dup 1) (match_dup 2)))]
5582   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5583    && ix86_binary_operator_ok (PLUS, DImode, operands)
5584    /* Current assemblers are broken and do not allow @GOTOFF in
5585       ought but a memory context.  */
5586    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5587 {
5588   switch (get_attr_type (insn))
5589     {
5590     case TYPE_INCDEC:
5591       if (! rtx_equal_p (operands[0], operands[1]))
5592         abort ();
5593       if (operands[2] == const1_rtx)
5594         return "inc{q}\t%0";
5595       else if (operands[2] == constm1_rtx)
5596         return "dec{q}\t%0";
5597       else
5598         abort ();
5599
5600     default:
5601       if (! rtx_equal_p (operands[0], operands[1]))
5602         abort ();
5603       /* ???? We ought to handle there the 32bit case too
5604          - do we need new constraint?  */
5605       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5606          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5607       if (GET_CODE (operands[2]) == CONST_INT
5608           /* Avoid overflows.  */
5609           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5610           && (INTVAL (operands[2]) == 128
5611               || (INTVAL (operands[2]) < 0
5612                   && INTVAL (operands[2]) != -128)))
5613         {
5614           operands[2] = GEN_INT (-INTVAL (operands[2]));
5615           return "sub{q}\t{%2, %0|%0, %2}";
5616         }
5617       return "add{q}\t{%2, %0|%0, %2}";
5618     }
5619 }
5620   [(set (attr "type")
5621      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5622         (const_string "incdec")
5623         (const_string "alu")))
5624    (set_attr "mode" "DI")])
5625
5626 (define_insn "*adddi_3_rex64"
5627   [(set (reg 17)
5628         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5629                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5630    (clobber (match_scratch:DI 0 "=r"))]
5631   "TARGET_64BIT
5632    && ix86_match_ccmode (insn, CCZmode)
5633    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5634    /* Current assemblers are broken and do not allow @GOTOFF in
5635       ought but a memory context.  */
5636    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5637 {
5638   switch (get_attr_type (insn))
5639     {
5640     case TYPE_INCDEC:
5641       if (! rtx_equal_p (operands[0], operands[1]))
5642         abort ();
5643       if (operands[2] == const1_rtx)
5644         return "inc{q}\t%0";
5645       else if (operands[2] == constm1_rtx)
5646         return "dec{q}\t%0";
5647       else
5648         abort ();
5649
5650     default:
5651       if (! rtx_equal_p (operands[0], operands[1]))
5652         abort ();
5653       /* ???? We ought to handle there the 32bit case too
5654          - do we need new constraint?  */
5655       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5656          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5657       if (GET_CODE (operands[2]) == CONST_INT
5658           /* Avoid overflows.  */
5659           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5660           && (INTVAL (operands[2]) == 128
5661               || (INTVAL (operands[2]) < 0
5662                   && INTVAL (operands[2]) != -128)))
5663         {
5664           operands[2] = GEN_INT (-INTVAL (operands[2]));
5665           return "sub{q}\t{%2, %0|%0, %2}";
5666         }
5667       return "add{q}\t{%2, %0|%0, %2}";
5668     }
5669 }
5670   [(set (attr "type")
5671      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5672         (const_string "incdec")
5673         (const_string "alu")))
5674    (set_attr "mode" "DI")])
5675
5676 ; For comparisons against 1, -1 and 128, we may generate better code
5677 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5678 ; is matched then.  We can't accept general immediate, because for
5679 ; case of overflows,  the result is messed up.
5680 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5681 ; when negated.
5682 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5683 ; only for comparisons not depending on it.
5684 (define_insn "*adddi_4_rex64"
5685   [(set (reg 17)
5686         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5687                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5688    (clobber (match_scratch:DI 0 "=rm"))]
5689   "TARGET_64BIT
5690    &&  ix86_match_ccmode (insn, CCGCmode)"
5691 {
5692   switch (get_attr_type (insn))
5693     {
5694     case TYPE_INCDEC:
5695       if (operands[2] == constm1_rtx)
5696         return "inc{q}\t%0";
5697       else if (operands[2] == const1_rtx)
5698         return "dec{q}\t%0";
5699       else
5700         abort();
5701
5702     default:
5703       if (! rtx_equal_p (operands[0], operands[1]))
5704         abort ();
5705       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5706          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5707       if ((INTVAL (operands[2]) == -128
5708            || (INTVAL (operands[2]) > 0
5709                && INTVAL (operands[2]) != 128))
5710           /* Avoid overflows.  */
5711           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5712         return "sub{q}\t{%2, %0|%0, %2}";
5713       operands[2] = GEN_INT (-INTVAL (operands[2]));
5714       return "add{q}\t{%2, %0|%0, %2}";
5715     }
5716 }
5717   [(set (attr "type")
5718      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5719         (const_string "incdec")
5720         (const_string "alu")))
5721    (set_attr "mode" "DI")])
5722
5723 (define_insn "*adddi_5_rex64"
5724   [(set (reg 17)
5725         (compare
5726           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5727                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5728           (const_int 0)))                       
5729    (clobber (match_scratch:DI 0 "=r"))]
5730   "TARGET_64BIT
5731    && ix86_match_ccmode (insn, CCGOCmode)
5732    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5733    /* Current assemblers are broken and do not allow @GOTOFF in
5734       ought but a memory context.  */
5735    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5736 {
5737   switch (get_attr_type (insn))
5738     {
5739     case TYPE_INCDEC:
5740       if (! rtx_equal_p (operands[0], operands[1]))
5741         abort ();
5742       if (operands[2] == const1_rtx)
5743         return "inc{q}\t%0";
5744       else if (operands[2] == constm1_rtx)
5745         return "dec{q}\t%0";
5746       else
5747         abort();
5748
5749     default:
5750       if (! rtx_equal_p (operands[0], operands[1]))
5751         abort ();
5752       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5753          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5754       if (GET_CODE (operands[2]) == CONST_INT
5755           /* Avoid overflows.  */
5756           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5757           && (INTVAL (operands[2]) == 128
5758               || (INTVAL (operands[2]) < 0
5759                   && INTVAL (operands[2]) != -128)))
5760         {
5761           operands[2] = GEN_INT (-INTVAL (operands[2]));
5762           return "sub{q}\t{%2, %0|%0, %2}";
5763         }
5764       return "add{q}\t{%2, %0|%0, %2}";
5765     }
5766 }
5767   [(set (attr "type")
5768      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5769         (const_string "incdec")
5770         (const_string "alu")))
5771    (set_attr "mode" "DI")])
5772
5773
5774 (define_insn "*addsi_1"
5775   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5776         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5777                  (match_operand:SI 2 "general_operand" "rmni,rni,rni")))
5778    (clobber (reg:CC 17))]
5779   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5780 {
5781   switch (get_attr_type (insn))
5782     {
5783     case TYPE_LEA:
5784       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5785       return "lea{l}\t{%a2, %0|%0, %a2}";
5786
5787     case TYPE_INCDEC:
5788       if (! rtx_equal_p (operands[0], operands[1]))
5789         abort ();
5790       if (operands[2] == const1_rtx)
5791         return "inc{l}\t%0";
5792       else if (operands[2] == constm1_rtx)
5793         return "dec{l}\t%0";
5794       else
5795         abort();
5796
5797     default:
5798       if (! rtx_equal_p (operands[0], operands[1]))
5799         abort ();
5800
5801       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5802          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5803       if (GET_CODE (operands[2]) == CONST_INT
5804           && (INTVAL (operands[2]) == 128
5805               || (INTVAL (operands[2]) < 0
5806                   && INTVAL (operands[2]) != -128)))
5807         {
5808           operands[2] = GEN_INT (-INTVAL (operands[2]));
5809           return "sub{l}\t{%2, %0|%0, %2}";
5810         }
5811       return "add{l}\t{%2, %0|%0, %2}";
5812     }
5813 }
5814   [(set (attr "type")
5815      (cond [(eq_attr "alternative" "2")
5816               (const_string "lea")
5817             ; Current assemblers are broken and do not allow @GOTOFF in
5818             ; ought but a memory context.
5819             (match_operand:SI 2 "pic_symbolic_operand" "")
5820               (const_string "lea")
5821             (match_operand:SI 2 "incdec_operand" "")
5822               (const_string "incdec")
5823            ]
5824            (const_string "alu")))
5825    (set_attr "mode" "SI")])
5826
5827 ;; Convert lea to the lea pattern to avoid flags dependency.
5828 (define_split
5829   [(set (match_operand 0 "register_operand" "")
5830         (plus (match_operand 1 "register_operand" "")
5831               (match_operand 2 "nonmemory_operand" "")))
5832    (clobber (reg:CC 17))]
5833   "reload_completed
5834    && true_regnum (operands[0]) != true_regnum (operands[1])"
5835   [(const_int 0)]
5836 {
5837   rtx pat;
5838   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5839      may confuse gen_lowpart.  */
5840   if (GET_MODE (operands[0]) != Pmode)
5841     {
5842       operands[1] = gen_lowpart (Pmode, operands[1]);
5843       operands[2] = gen_lowpart (Pmode, operands[2]);
5844     }
5845   operands[0] = gen_lowpart (SImode, operands[0]);
5846   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5847   if (Pmode != SImode)
5848     pat = gen_rtx_SUBREG (SImode, pat, 0);
5849   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5850   DONE;
5851 })
5852
5853 ;; It may seem that nonimmediate operand is proper one for operand 1.
5854 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5855 ;; we take care in ix86_binary_operator_ok to not allow two memory
5856 ;; operands so proper swapping will be done in reload.  This allow
5857 ;; patterns constructed from addsi_1 to match.
5858 (define_insn "addsi_1_zext"
5859   [(set (match_operand:DI 0 "register_operand" "=r,r")
5860         (zero_extend:DI
5861           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5862                    (match_operand:SI 2 "general_operand" "rmni,rni"))))
5863    (clobber (reg:CC 17))]
5864   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5865 {
5866   switch (get_attr_type (insn))
5867     {
5868     case TYPE_LEA:
5869       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5870       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5871
5872     case TYPE_INCDEC:
5873       if (operands[2] == const1_rtx)
5874         return "inc{l}\t%k0";
5875       else if (operands[2] == constm1_rtx)
5876         return "dec{l}\t%k0";
5877       else
5878         abort();
5879
5880     default:
5881       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5882          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5883       if (GET_CODE (operands[2]) == CONST_INT
5884           && (INTVAL (operands[2]) == 128
5885               || (INTVAL (operands[2]) < 0
5886                   && INTVAL (operands[2]) != -128)))
5887         {
5888           operands[2] = GEN_INT (-INTVAL (operands[2]));
5889           return "sub{l}\t{%2, %k0|%k0, %2}";
5890         }
5891       return "add{l}\t{%2, %k0|%k0, %2}";
5892     }
5893 }
5894   [(set (attr "type")
5895      (cond [(eq_attr "alternative" "1")
5896               (const_string "lea")
5897             ; Current assemblers are broken and do not allow @GOTOFF in
5898             ; ought but a memory context.
5899             (match_operand:SI 2 "pic_symbolic_operand" "")
5900               (const_string "lea")
5901             (match_operand:SI 2 "incdec_operand" "")
5902               (const_string "incdec")
5903            ]
5904            (const_string "alu")))
5905    (set_attr "mode" "SI")])
5906
5907 ;; Convert lea to the lea pattern to avoid flags dependency.
5908 (define_split
5909   [(set (match_operand:DI 0 "register_operand" "")
5910         (zero_extend:DI
5911           (plus:SI (match_operand:SI 1 "register_operand" "")
5912                    (match_operand:SI 2 "nonmemory_operand" ""))))
5913    (clobber (reg:CC 17))]
5914   "TARGET_64BIT && reload_completed
5915    && true_regnum (operands[0]) != true_regnum (operands[1])"
5916   [(set (match_dup 0)
5917         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5918 {
5919   operands[1] = gen_lowpart (Pmode, operands[1]);
5920   operands[2] = gen_lowpart (Pmode, operands[2]);
5921 })
5922
5923 (define_insn "*addsi_2"
5924   [(set (reg 17)
5925         (compare
5926           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5927                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5928           (const_int 0)))                       
5929    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5930         (plus:SI (match_dup 1) (match_dup 2)))]
5931   "ix86_match_ccmode (insn, CCGOCmode)
5932    && ix86_binary_operator_ok (PLUS, SImode, operands)
5933    /* Current assemblers are broken and do not allow @GOTOFF in
5934       ought but a memory context.  */
5935    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5936 {
5937   switch (get_attr_type (insn))
5938     {
5939     case TYPE_INCDEC:
5940       if (! rtx_equal_p (operands[0], operands[1]))
5941         abort ();
5942       if (operands[2] == const1_rtx)
5943         return "inc{l}\t%0";
5944       else if (operands[2] == constm1_rtx)
5945         return "dec{l}\t%0";
5946       else
5947         abort();
5948
5949     default:
5950       if (! rtx_equal_p (operands[0], operands[1]))
5951         abort ();
5952       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5953          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5954       if (GET_CODE (operands[2]) == CONST_INT
5955           && (INTVAL (operands[2]) == 128
5956               || (INTVAL (operands[2]) < 0
5957                   && INTVAL (operands[2]) != -128)))
5958         {
5959           operands[2] = GEN_INT (-INTVAL (operands[2]));
5960           return "sub{l}\t{%2, %0|%0, %2}";
5961         }
5962       return "add{l}\t{%2, %0|%0, %2}";
5963     }
5964 }
5965   [(set (attr "type")
5966      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5967         (const_string "incdec")
5968         (const_string "alu")))
5969    (set_attr "mode" "SI")])
5970
5971 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5972 (define_insn "*addsi_2_zext"
5973   [(set (reg 17)
5974         (compare
5975           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5976                    (match_operand:SI 2 "general_operand" "rmni"))
5977           (const_int 0)))                       
5978    (set (match_operand:DI 0 "register_operand" "=r")
5979         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5980   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5981    && ix86_binary_operator_ok (PLUS, SImode, operands)
5982    /* Current assemblers are broken and do not allow @GOTOFF in
5983       ought but a memory context.  */
5984    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5985 {
5986   switch (get_attr_type (insn))
5987     {
5988     case TYPE_INCDEC:
5989       if (operands[2] == const1_rtx)
5990         return "inc{l}\t%k0";
5991       else if (operands[2] == constm1_rtx)
5992         return "dec{l}\t%k0";
5993       else
5994         abort();
5995
5996     default:
5997       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5998          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5999       if (GET_CODE (operands[2]) == CONST_INT
6000           && (INTVAL (operands[2]) == 128
6001               || (INTVAL (operands[2]) < 0
6002                   && INTVAL (operands[2]) != -128)))
6003         {
6004           operands[2] = GEN_INT (-INTVAL (operands[2]));
6005           return "sub{l}\t{%2, %k0|%k0, %2}";
6006         }
6007       return "add{l}\t{%2, %k0|%k0, %2}";
6008     }
6009 }
6010   [(set (attr "type")
6011      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6012         (const_string "incdec")
6013         (const_string "alu")))
6014    (set_attr "mode" "SI")])
6015
6016 (define_insn "*addsi_3"
6017   [(set (reg 17)
6018         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6019                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6020    (clobber (match_scratch:SI 0 "=r"))]
6021   "ix86_match_ccmode (insn, CCZmode)
6022    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
6023    /* Current assemblers are broken and do not allow @GOTOFF in
6024       ought but a memory context.  */
6025    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6026 {
6027   switch (get_attr_type (insn))
6028     {
6029     case TYPE_INCDEC:
6030       if (! rtx_equal_p (operands[0], operands[1]))
6031         abort ();
6032       if (operands[2] == const1_rtx)
6033         return "inc{l}\t%0";
6034       else if (operands[2] == constm1_rtx)
6035         return "dec{l}\t%0";
6036       else
6037         abort();
6038
6039     default:
6040       if (! rtx_equal_p (operands[0], operands[1]))
6041         abort ();
6042       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6043          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6044       if (GET_CODE (operands[2]) == CONST_INT
6045           && (INTVAL (operands[2]) == 128
6046               || (INTVAL (operands[2]) < 0
6047                   && INTVAL (operands[2]) != -128)))
6048         {
6049           operands[2] = GEN_INT (-INTVAL (operands[2]));
6050           return "sub{l}\t{%2, %0|%0, %2}";
6051         }
6052       return "add{l}\t{%2, %0|%0, %2}";
6053     }
6054 }
6055   [(set (attr "type")
6056      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6057         (const_string "incdec")
6058         (const_string "alu")))
6059    (set_attr "mode" "SI")])
6060
6061 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6062 (define_insn "*addsi_3_zext"
6063   [(set (reg 17)
6064         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6065                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6066    (set (match_operand:DI 0 "register_operand" "=r")
6067         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6068   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6069    && ix86_binary_operator_ok (PLUS, SImode, operands)
6070    /* Current assemblers are broken and do not allow @GOTOFF in
6071       ought but a memory context.  */
6072    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6073 {
6074   switch (get_attr_type (insn))
6075     {
6076     case TYPE_INCDEC:
6077       if (operands[2] == const1_rtx)
6078         return "inc{l}\t%k0";
6079       else if (operands[2] == constm1_rtx)
6080         return "dec{l}\t%k0";
6081       else
6082         abort();
6083
6084     default:
6085       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6086          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6087       if (GET_CODE (operands[2]) == CONST_INT
6088           && (INTVAL (operands[2]) == 128
6089               || (INTVAL (operands[2]) < 0
6090                   && INTVAL (operands[2]) != -128)))
6091         {
6092           operands[2] = GEN_INT (-INTVAL (operands[2]));
6093           return "sub{l}\t{%2, %k0|%k0, %2}";
6094         }
6095       return "add{l}\t{%2, %k0|%k0, %2}";
6096     }
6097 }
6098   [(set (attr "type")
6099      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6100         (const_string "incdec")
6101         (const_string "alu")))
6102    (set_attr "mode" "SI")])
6103
6104 ; For comparisons against 1, -1 and 128, we may generate better code
6105 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6106 ; is matched then.  We can't accept general immediate, because for
6107 ; case of overflows,  the result is messed up.
6108 ; This pattern also don't hold of 0x80000000, since the value overflows
6109 ; when negated.
6110 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6111 ; only for comparisons not depending on it.
6112 (define_insn "*addsi_4"
6113   [(set (reg 17)
6114         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6115                  (match_operand:SI 2 "const_int_operand" "n")))
6116    (clobber (match_scratch:SI 0 "=rm"))]
6117   "ix86_match_ccmode (insn, CCGCmode)
6118    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6119 {
6120   switch (get_attr_type (insn))
6121     {
6122     case TYPE_INCDEC:
6123       if (operands[2] == constm1_rtx)
6124         return "inc{l}\t%0";
6125       else if (operands[2] == const1_rtx)
6126         return "dec{l}\t%0";
6127       else
6128         abort();
6129
6130     default:
6131       if (! rtx_equal_p (operands[0], operands[1]))
6132         abort ();
6133       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6134          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6135       if ((INTVAL (operands[2]) == -128
6136            || (INTVAL (operands[2]) > 0
6137                && INTVAL (operands[2]) != 128)))
6138         return "sub{l}\t{%2, %0|%0, %2}";
6139       operands[2] = GEN_INT (-INTVAL (operands[2]));
6140       return "add{l}\t{%2, %0|%0, %2}";
6141     }
6142 }
6143   [(set (attr "type")
6144      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6145         (const_string "incdec")
6146         (const_string "alu")))
6147    (set_attr "mode" "SI")])
6148
6149 (define_insn "*addsi_5"
6150   [(set (reg 17)
6151         (compare
6152           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6153                    (match_operand:SI 2 "general_operand" "rmni"))
6154           (const_int 0)))                       
6155    (clobber (match_scratch:SI 0 "=r"))]
6156   "ix86_match_ccmode (insn, CCGOCmode)
6157    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
6158    /* Current assemblers are broken and do not allow @GOTOFF in
6159       ought but a memory context.  */
6160    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6161 {
6162   switch (get_attr_type (insn))
6163     {
6164     case TYPE_INCDEC:
6165       if (! rtx_equal_p (operands[0], operands[1]))
6166         abort ();
6167       if (operands[2] == const1_rtx)
6168         return "inc{l}\t%0";
6169       else if (operands[2] == constm1_rtx)
6170         return "dec{l}\t%0";
6171       else
6172         abort();
6173
6174     default:
6175       if (! rtx_equal_p (operands[0], operands[1]))
6176         abort ();
6177       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6178          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6179       if (GET_CODE (operands[2]) == CONST_INT
6180           && (INTVAL (operands[2]) == 128
6181               || (INTVAL (operands[2]) < 0
6182                   && INTVAL (operands[2]) != -128)))
6183         {
6184           operands[2] = GEN_INT (-INTVAL (operands[2]));
6185           return "sub{l}\t{%2, %0|%0, %2}";
6186         }
6187       return "add{l}\t{%2, %0|%0, %2}";
6188     }
6189 }
6190   [(set (attr "type")
6191      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6192         (const_string "incdec")
6193         (const_string "alu")))
6194    (set_attr "mode" "SI")])
6195
6196 (define_expand "addhi3"
6197   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6198                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6199                             (match_operand:HI 2 "general_operand" "")))
6200               (clobber (reg:CC 17))])]
6201   "TARGET_HIMODE_MATH"
6202   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6203
6204 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6205 ;; type optimizations enabled by define-splits.  This is not important
6206 ;; for PII, and in fact harmful because of partial register stalls.
6207
6208 (define_insn "*addhi_1_lea"
6209   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6210         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6211                  (match_operand:HI 2 "general_operand" "ri,rm,rni")))
6212    (clobber (reg:CC 17))]
6213   "!TARGET_PARTIAL_REG_STALL
6214    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6215 {
6216   switch (get_attr_type (insn))
6217     {
6218     case TYPE_LEA:
6219       return "#";
6220     case TYPE_INCDEC:
6221       if (operands[2] == const1_rtx)
6222         return "inc{w}\t%0";
6223       else if (operands[2] == constm1_rtx)
6224         return "dec{w}\t%0";
6225       abort();
6226
6227     default:
6228       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6229          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6230       if (GET_CODE (operands[2]) == CONST_INT
6231           && (INTVAL (operands[2]) == 128
6232               || (INTVAL (operands[2]) < 0
6233                   && INTVAL (operands[2]) != -128)))
6234         {
6235           operands[2] = GEN_INT (-INTVAL (operands[2]));
6236           return "sub{w}\t{%2, %0|%0, %2}";
6237         }
6238       return "add{w}\t{%2, %0|%0, %2}";
6239     }
6240 }
6241   [(set (attr "type")
6242      (if_then_else (eq_attr "alternative" "2")
6243         (const_string "lea")
6244         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6245            (const_string "incdec")
6246            (const_string "alu"))))
6247    (set_attr "mode" "HI,HI,SI")])
6248
6249 (define_insn "*addhi_1"
6250   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6251         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6252                  (match_operand:HI 2 "general_operand" "ri,rm")))
6253    (clobber (reg:CC 17))]
6254   "TARGET_PARTIAL_REG_STALL
6255    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6256 {
6257   switch (get_attr_type (insn))
6258     {
6259     case TYPE_INCDEC:
6260       if (operands[2] == const1_rtx)
6261         return "inc{w}\t%0";
6262       else if (operands[2] == constm1_rtx)
6263         return "dec{w}\t%0";
6264       abort();
6265
6266     default:
6267       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6268          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6269       if (GET_CODE (operands[2]) == CONST_INT
6270           && (INTVAL (operands[2]) == 128
6271               || (INTVAL (operands[2]) < 0
6272                   && INTVAL (operands[2]) != -128)))
6273         {
6274           operands[2] = GEN_INT (-INTVAL (operands[2]));
6275           return "sub{w}\t{%2, %0|%0, %2}";
6276         }
6277       return "add{w}\t{%2, %0|%0, %2}";
6278     }
6279 }
6280   [(set (attr "type")
6281      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6282         (const_string "incdec")
6283         (const_string "alu")))
6284    (set_attr "mode" "HI")])
6285
6286 (define_insn "*addhi_2"
6287   [(set (reg 17)
6288         (compare
6289           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6290                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6291           (const_int 0)))                       
6292    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6293         (plus:HI (match_dup 1) (match_dup 2)))]
6294   "ix86_match_ccmode (insn, CCGOCmode)
6295    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6296 {
6297   switch (get_attr_type (insn))
6298     {
6299     case TYPE_INCDEC:
6300       if (operands[2] == const1_rtx)
6301         return "inc{w}\t%0";
6302       else if (operands[2] == constm1_rtx)
6303         return "dec{w}\t%0";
6304       abort();
6305
6306     default:
6307       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6308          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6309       if (GET_CODE (operands[2]) == CONST_INT
6310           && (INTVAL (operands[2]) == 128
6311               || (INTVAL (operands[2]) < 0
6312                   && INTVAL (operands[2]) != -128)))
6313         {
6314           operands[2] = GEN_INT (-INTVAL (operands[2]));
6315           return "sub{w}\t{%2, %0|%0, %2}";
6316         }
6317       return "add{w}\t{%2, %0|%0, %2}";
6318     }
6319 }
6320   [(set (attr "type")
6321      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6322         (const_string "incdec")
6323         (const_string "alu")))
6324    (set_attr "mode" "HI")])
6325
6326 (define_insn "*addhi_3"
6327   [(set (reg 17)
6328         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6329                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6330    (clobber (match_scratch:HI 0 "=r"))]
6331   "ix86_match_ccmode (insn, CCZmode)
6332    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6333 {
6334   switch (get_attr_type (insn))
6335     {
6336     case TYPE_INCDEC:
6337       if (operands[2] == const1_rtx)
6338         return "inc{w}\t%0";
6339       else if (operands[2] == constm1_rtx)
6340         return "dec{w}\t%0";
6341       abort();
6342
6343     default:
6344       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6345          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6346       if (GET_CODE (operands[2]) == CONST_INT
6347           && (INTVAL (operands[2]) == 128
6348               || (INTVAL (operands[2]) < 0
6349                   && INTVAL (operands[2]) != -128)))
6350         {
6351           operands[2] = GEN_INT (-INTVAL (operands[2]));
6352           return "sub{w}\t{%2, %0|%0, %2}";
6353         }
6354       return "add{w}\t{%2, %0|%0, %2}";
6355     }
6356 }
6357   [(set (attr "type")
6358      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6359         (const_string "incdec")
6360         (const_string "alu")))
6361    (set_attr "mode" "HI")])
6362
6363 ; See comments above addsi_3_imm for details.
6364 (define_insn "*addhi_4"
6365   [(set (reg 17)
6366         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6367                  (match_operand:HI 2 "const_int_operand" "n")))
6368    (clobber (match_scratch:HI 0 "=rm"))]
6369   "ix86_match_ccmode (insn, CCGCmode)
6370    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6371 {
6372   switch (get_attr_type (insn))
6373     {
6374     case TYPE_INCDEC:
6375       if (operands[2] == constm1_rtx)
6376         return "inc{w}\t%0";
6377       else if (operands[2] == const1_rtx)
6378         return "dec{w}\t%0";
6379       else
6380         abort();
6381
6382     default:
6383       if (! rtx_equal_p (operands[0], operands[1]))
6384         abort ();
6385       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6386          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6387       if ((INTVAL (operands[2]) == -128
6388            || (INTVAL (operands[2]) > 0
6389                && INTVAL (operands[2]) != 128)))
6390         return "sub{w}\t{%2, %0|%0, %2}";
6391       operands[2] = GEN_INT (-INTVAL (operands[2]));
6392       return "add{w}\t{%2, %0|%0, %2}";
6393     }
6394 }
6395   [(set (attr "type")
6396      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6397         (const_string "incdec")
6398         (const_string "alu")))
6399    (set_attr "mode" "SI")])
6400
6401
6402 (define_insn "*addhi_5"
6403   [(set (reg 17)
6404         (compare
6405           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6406                    (match_operand:HI 2 "general_operand" "rmni"))
6407           (const_int 0)))                       
6408    (clobber (match_scratch:HI 0 "=r"))]
6409   "ix86_match_ccmode (insn, CCGOCmode)
6410    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6411 {
6412   switch (get_attr_type (insn))
6413     {
6414     case TYPE_INCDEC:
6415       if (operands[2] == const1_rtx)
6416         return "inc{w}\t%0";
6417       else if (operands[2] == constm1_rtx)
6418         return "dec{w}\t%0";
6419       abort();
6420
6421     default:
6422       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6423          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6424       if (GET_CODE (operands[2]) == CONST_INT
6425           && (INTVAL (operands[2]) == 128
6426               || (INTVAL (operands[2]) < 0
6427                   && INTVAL (operands[2]) != -128)))
6428         {
6429           operands[2] = GEN_INT (-INTVAL (operands[2]));
6430           return "sub{w}\t{%2, %0|%0, %2}";
6431         }
6432       return "add{w}\t{%2, %0|%0, %2}";
6433     }
6434 }
6435   [(set (attr "type")
6436      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6437         (const_string "incdec")
6438         (const_string "alu")))
6439    (set_attr "mode" "HI")])
6440
6441 (define_expand "addqi3"
6442   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6443                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6444                             (match_operand:QI 2 "general_operand" "")))
6445               (clobber (reg:CC 17))])]
6446   "TARGET_QIMODE_MATH"
6447   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6448
6449 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6450 (define_insn "*addqi_1_lea"
6451   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6452         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6453                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,rn")))
6454    (clobber (reg:CC 17))]
6455   "!TARGET_PARTIAL_REG_STALL
6456    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6457 {
6458   int widen = (which_alternative == 2);
6459   switch (get_attr_type (insn))
6460     {
6461     case TYPE_LEA:
6462       return "#";
6463     case TYPE_INCDEC:
6464       if (operands[2] == const1_rtx)
6465         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6466       else if (operands[2] == constm1_rtx)
6467         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6468       abort();
6469
6470     default:
6471       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6472          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6473       if (GET_CODE (operands[2]) == CONST_INT
6474           && (INTVAL (operands[2]) == 128
6475               || (INTVAL (operands[2]) < 0
6476                   && INTVAL (operands[2]) != -128)))
6477         {
6478           operands[2] = GEN_INT (-INTVAL (operands[2]));
6479           if (widen)
6480             return "sub{l}\t{%2, %k0|%k0, %2}";
6481           else
6482             return "sub{b}\t{%2, %0|%0, %2}";
6483         }
6484       if (widen)
6485         return "add{l}\t{%k2, %k0|%k0, %k2}";
6486       else
6487         return "add{b}\t{%2, %0|%0, %2}";
6488     }
6489 }
6490   [(set (attr "type")
6491      (if_then_else (eq_attr "alternative" "3")
6492         (const_string "lea")
6493         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6494            (const_string "incdec")
6495            (const_string "alu"))))
6496    (set_attr "mode" "QI,QI,SI,SI")])
6497
6498 (define_insn "*addqi_1"
6499   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6500         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6501                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6502    (clobber (reg:CC 17))]
6503   "TARGET_PARTIAL_REG_STALL
6504    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6505 {
6506   int widen = (which_alternative == 2);
6507   switch (get_attr_type (insn))
6508     {
6509     case TYPE_INCDEC:
6510       if (operands[2] == const1_rtx)
6511         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6512       else if (operands[2] == constm1_rtx)
6513         return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6514       abort();
6515
6516     default:
6517       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6518          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6519       if (GET_CODE (operands[2]) == CONST_INT
6520           && (INTVAL (operands[2]) == 128
6521               || (INTVAL (operands[2]) < 0
6522                   && INTVAL (operands[2]) != -128)))
6523         {
6524           operands[2] = GEN_INT (-INTVAL (operands[2]));
6525           if (widen)
6526             return "sub{l}\t{%2, %k0|%k0, %2}";
6527           else
6528             return "sub{b}\t{%2, %0|%0, %2}";
6529         }
6530       if (widen)
6531         return "add{l}\t{%k2, %k0|%k0, %k2}";
6532       else
6533         return "add{b}\t{%2, %0|%0, %2}";
6534     }
6535 }
6536   [(set (attr "type")
6537      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6538         (const_string "incdec")
6539         (const_string "alu")))
6540    (set_attr "mode" "QI,QI,SI")])
6541
6542 (define_insn "*addqi_1_slp"
6543   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6544         (plus:QI (match_dup 0)
6545                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6546    (clobber (reg:CC 17))]
6547   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6548    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6549 {
6550   switch (get_attr_type (insn))
6551     {
6552     case TYPE_INCDEC:
6553       if (operands[1] == const1_rtx)
6554         return "inc{b}\t%0";
6555       else if (operands[1] == constm1_rtx)
6556         return "dec{b}\t%0";
6557       abort();
6558
6559     default:
6560       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6561       if (GET_CODE (operands[1]) == CONST_INT
6562           && INTVAL (operands[1]) < 0)
6563         {
6564           operands[2] = GEN_INT (-INTVAL (operands[2]));
6565           return "sub{b}\t{%1, %0|%0, %1}";
6566         }
6567       return "add{b}\t{%1, %0|%0, %1}";
6568     }
6569 }
6570   [(set (attr "type")
6571      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6572         (const_string "incdec")
6573         (const_string "alu1")))
6574    (set_attr "mode" "QI")])
6575
6576 (define_insn "*addqi_2"
6577   [(set (reg 17)
6578         (compare
6579           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6580                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6581           (const_int 0)))
6582    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6583         (plus:QI (match_dup 1) (match_dup 2)))]
6584   "ix86_match_ccmode (insn, CCGOCmode)
6585    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6586 {
6587   switch (get_attr_type (insn))
6588     {
6589     case TYPE_INCDEC:
6590       if (operands[2] == const1_rtx)
6591         return "inc{b}\t%0";
6592       else if (operands[2] == constm1_rtx
6593                || (GET_CODE (operands[2]) == CONST_INT
6594                    && INTVAL (operands[2]) == 255))
6595         return "dec{b}\t%0";
6596       abort();
6597
6598     default:
6599       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6600       if (GET_CODE (operands[2]) == CONST_INT
6601           && INTVAL (operands[2]) < 0)
6602         {
6603           operands[2] = GEN_INT (-INTVAL (operands[2]));
6604           return "sub{b}\t{%2, %0|%0, %2}";
6605         }
6606       return "add{b}\t{%2, %0|%0, %2}";
6607     }
6608 }
6609   [(set (attr "type")
6610      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6611         (const_string "incdec")
6612         (const_string "alu")))
6613    (set_attr "mode" "QI")])
6614
6615 (define_insn "*addqi_3"
6616   [(set (reg 17)
6617         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6618                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6619    (clobber (match_scratch:QI 0 "=q"))]
6620   "ix86_match_ccmode (insn, CCZmode)
6621    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6622 {
6623   switch (get_attr_type (insn))
6624     {
6625     case TYPE_INCDEC:
6626       if (operands[2] == const1_rtx)
6627         return "inc{b}\t%0";
6628       else if (operands[2] == constm1_rtx
6629                || (GET_CODE (operands[2]) == CONST_INT
6630                    && INTVAL (operands[2]) == 255))
6631         return "dec{b}\t%0";
6632       abort();
6633
6634     default:
6635       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6636       if (GET_CODE (operands[2]) == CONST_INT
6637           && INTVAL (operands[2]) < 0)
6638         {
6639           operands[2] = GEN_INT (-INTVAL (operands[2]));
6640           return "sub{b}\t{%2, %0|%0, %2}";
6641         }
6642       return "add{b}\t{%2, %0|%0, %2}";
6643     }
6644 }
6645   [(set (attr "type")
6646      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6647         (const_string "incdec")
6648         (const_string "alu")))
6649    (set_attr "mode" "QI")])
6650
6651 ; See comments above addsi_3_imm for details.
6652 (define_insn "*addqi_4"
6653   [(set (reg 17)
6654         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6655                  (match_operand:QI 2 "const_int_operand" "n")))
6656    (clobber (match_scratch:QI 0 "=qm"))]
6657   "ix86_match_ccmode (insn, CCGCmode)
6658    && (INTVAL (operands[2]) & 0xff) != 0x80"
6659 {
6660   switch (get_attr_type (insn))
6661     {
6662     case TYPE_INCDEC:
6663       if (operands[2] == constm1_rtx
6664           || (GET_CODE (operands[2]) == CONST_INT
6665               && INTVAL (operands[2]) == 255))
6666         return "inc{b}\t%0";
6667       else if (operands[2] == const1_rtx)
6668         return "dec{b}\t%0";
6669       else
6670         abort();
6671
6672     default:
6673       if (! rtx_equal_p (operands[0], operands[1]))
6674         abort ();
6675       if (INTVAL (operands[2]) < 0)
6676         {
6677           operands[2] = GEN_INT (-INTVAL (operands[2]));
6678           return "add{b}\t{%2, %0|%0, %2}";
6679         }
6680       return "sub{b}\t{%2, %0|%0, %2}";
6681     }
6682 }
6683   [(set (attr "type")
6684      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6685         (const_string "incdec")
6686         (const_string "alu")))
6687    (set_attr "mode" "QI")])
6688
6689
6690 (define_insn "*addqi_5"
6691   [(set (reg 17)
6692         (compare
6693           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6694                    (match_operand:QI 2 "general_operand" "qmni"))
6695           (const_int 0)))
6696    (clobber (match_scratch:QI 0 "=q"))]
6697   "ix86_match_ccmode (insn, CCGOCmode)
6698    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6699 {
6700   switch (get_attr_type (insn))
6701     {
6702     case TYPE_INCDEC:
6703       if (operands[2] == const1_rtx)
6704         return "inc{b}\t%0";
6705       else if (operands[2] == constm1_rtx
6706                || (GET_CODE (operands[2]) == CONST_INT
6707                    && INTVAL (operands[2]) == 255))
6708         return "dec{b}\t%0";
6709       abort();
6710
6711     default:
6712       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6713       if (GET_CODE (operands[2]) == CONST_INT
6714           && INTVAL (operands[2]) < 0)
6715         {
6716           operands[2] = GEN_INT (-INTVAL (operands[2]));
6717           return "sub{b}\t{%2, %0|%0, %2}";
6718         }
6719       return "add{b}\t{%2, %0|%0, %2}";
6720     }
6721 }
6722   [(set (attr "type")
6723      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6724         (const_string "incdec")
6725         (const_string "alu")))
6726    (set_attr "mode" "QI")])
6727
6728
6729 (define_insn "addqi_ext_1"
6730   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6731                          (const_int 8)
6732                          (const_int 8))
6733         (plus:SI
6734           (zero_extract:SI
6735             (match_operand 1 "ext_register_operand" "0")
6736             (const_int 8)
6737             (const_int 8))
6738           (match_operand:QI 2 "general_operand" "Qmn")))
6739    (clobber (reg:CC 17))]
6740   "!TARGET_64BIT"
6741 {
6742   switch (get_attr_type (insn))
6743     {
6744     case TYPE_INCDEC:
6745       if (operands[2] == const1_rtx)
6746         return "inc{b}\t%h0";
6747       else if (operands[2] == constm1_rtx
6748                || (GET_CODE (operands[2]) == CONST_INT
6749                    && INTVAL (operands[2]) == 255))
6750         return "dec{b}\t%h0";
6751       abort();
6752
6753     default:
6754       return "add{b}\t{%2, %h0|%h0, %2}";
6755     }
6756 }
6757   [(set (attr "type")
6758      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6759         (const_string "incdec")
6760         (const_string "alu")))
6761    (set_attr "mode" "QI")])
6762
6763 (define_insn "*addqi_ext_1_rex64"
6764   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6765                          (const_int 8)
6766                          (const_int 8))
6767         (plus:SI
6768           (zero_extract:SI
6769             (match_operand 1 "ext_register_operand" "0")
6770             (const_int 8)
6771             (const_int 8))
6772           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6773    (clobber (reg:CC 17))]
6774   "TARGET_64BIT"
6775 {
6776   switch (get_attr_type (insn))
6777     {
6778     case TYPE_INCDEC:
6779       if (operands[2] == const1_rtx)
6780         return "inc{b}\t%h0";
6781       else if (operands[2] == constm1_rtx
6782                || (GET_CODE (operands[2]) == CONST_INT
6783                    && INTVAL (operands[2]) == 255))
6784         return "dec{b}\t%h0";
6785       abort();
6786
6787     default:
6788       return "add{b}\t{%2, %h0|%h0, %2}";
6789     }
6790 }
6791   [(set (attr "type")
6792      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6793         (const_string "incdec")
6794         (const_string "alu")))
6795    (set_attr "mode" "QI")])
6796
6797 (define_insn "*addqi_ext_2"
6798   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6799                          (const_int 8)
6800                          (const_int 8))
6801         (plus:SI
6802           (zero_extract:SI
6803             (match_operand 1 "ext_register_operand" "%0")
6804             (const_int 8)
6805             (const_int 8))
6806           (zero_extract:SI
6807             (match_operand 2 "ext_register_operand" "Q")
6808             (const_int 8)
6809             (const_int 8))))
6810    (clobber (reg:CC 17))]
6811   ""
6812   "add{b}\t{%h2, %h0|%h0, %h2}"
6813   [(set_attr "type" "alu")
6814    (set_attr "mode" "QI")])
6815
6816 ;; The patterns that match these are at the end of this file.
6817
6818 (define_expand "addxf3"
6819   [(set (match_operand:XF 0 "register_operand" "")
6820         (plus:XF (match_operand:XF 1 "register_operand" "")
6821                  (match_operand:XF 2 "register_operand" "")))]
6822   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
6823   "")
6824
6825 (define_expand "addtf3"
6826   [(set (match_operand:TF 0 "register_operand" "")
6827         (plus:TF (match_operand:TF 1 "register_operand" "")
6828                  (match_operand:TF 2 "register_operand" "")))]
6829   "TARGET_80387"
6830   "")
6831
6832 (define_expand "adddf3"
6833   [(set (match_operand:DF 0 "register_operand" "")
6834         (plus:DF (match_operand:DF 1 "register_operand" "")
6835                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6836   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6837   "")
6838
6839 (define_expand "addsf3"
6840   [(set (match_operand:SF 0 "register_operand" "")
6841         (plus:SF (match_operand:SF 1 "register_operand" "")
6842                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6843   "TARGET_80387 || TARGET_SSE_MATH"
6844   "")
6845 \f
6846 ;; Subtract instructions
6847
6848 ;; %%% splits for subsidi3
6849
6850 (define_expand "subdi3"
6851   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6852                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6853                              (match_operand:DI 2 "x86_64_general_operand" "")))
6854               (clobber (reg:CC 17))])]
6855   ""
6856   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6857
6858 (define_insn "*subdi3_1"
6859   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6860         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6861                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6862    (clobber (reg:CC 17))]
6863   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6864   "#")
6865
6866 (define_split
6867   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6868         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6869                   (match_operand:DI 2 "general_operand" "")))
6870    (clobber (reg:CC 17))]
6871   "!TARGET_64BIT && reload_completed"
6872   [(parallel [(set (reg:CC 17) (compare:CC (match_dup 1) (match_dup 2)))
6873               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6874    (parallel [(set (match_dup 3)
6875                    (minus:SI (match_dup 4)
6876                              (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
6877                                       (match_dup 5))))
6878               (clobber (reg:CC 17))])]
6879   "split_di (operands+0, 1, operands+0, operands+3);
6880    split_di (operands+1, 1, operands+1, operands+4);
6881    split_di (operands+2, 1, operands+2, operands+5);")
6882
6883 (define_insn "subdi3_carry_rex64"
6884   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6885           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6886             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6887                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6888    (clobber (reg:CC 17))]
6889   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6890   "sbb{q}\t{%2, %0|%0, %2}"
6891   [(set_attr "type" "alu")
6892    (set_attr "pent_pair" "pu")
6893    (set_attr "ppro_uops" "few")
6894    (set_attr "mode" "DI")])
6895
6896 (define_insn "*subdi_1_rex64"
6897   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6898         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6899                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6900    (clobber (reg:CC 17))]
6901   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6902   "sub{q}\t{%2, %0|%0, %2}"
6903   [(set_attr "type" "alu")
6904    (set_attr "mode" "DI")])
6905
6906 (define_insn "*subdi_2_rex64"
6907   [(set (reg 17)
6908         (compare
6909           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6910                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6911           (const_int 0)))
6912    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6913         (minus:DI (match_dup 1) (match_dup 2)))]
6914   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6915    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6916   "sub{q}\t{%2, %0|%0, %2}"
6917   [(set_attr "type" "alu")
6918    (set_attr "mode" "DI")])
6919
6920 (define_insn "*subdi_3_rex63"
6921   [(set (reg 17)
6922         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6923                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6924    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6925         (minus:DI (match_dup 1) (match_dup 2)))]
6926   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6927    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6928   "sub{q}\t{%2, %0|%0, %2}"
6929   [(set_attr "type" "alu")
6930    (set_attr "mode" "DI")])
6931
6932 (define_insn "subqi3_carry"
6933   [(set (match_operand:QI 0 "nonimmediate_operand" "=rm,r")
6934           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6935             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6936                (match_operand:QI 2 "general_operand" "ri,rm"))))
6937    (clobber (reg:CC 17))]
6938   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6939   "sbb{b}\t{%2, %0|%0, %2}"
6940   [(set_attr "type" "alu")
6941    (set_attr "pent_pair" "pu")
6942    (set_attr "ppro_uops" "few")
6943    (set_attr "mode" "QI")])
6944
6945 (define_insn "subhi3_carry"
6946   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6947           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6948             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6949                (match_operand:HI 2 "general_operand" "ri,rm"))))
6950    (clobber (reg:CC 17))]
6951   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6952   "sbb{w}\t{%2, %0|%0, %2}"
6953   [(set_attr "type" "alu")
6954    (set_attr "pent_pair" "pu")
6955    (set_attr "ppro_uops" "few")
6956    (set_attr "mode" "HI")])
6957
6958 (define_insn "subsi3_carry"
6959   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6960           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6961             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6962                (match_operand:SI 2 "general_operand" "ri,rm"))))
6963    (clobber (reg:CC 17))]
6964   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6965   "sbb{l}\t{%2, %0|%0, %2}"
6966   [(set_attr "type" "alu")
6967    (set_attr "pent_pair" "pu")
6968    (set_attr "ppro_uops" "few")
6969    (set_attr "mode" "SI")])
6970
6971 (define_insn "subsi3_carry_zext"
6972   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6973           (zero_extend:DI
6974             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6975               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6976                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6977    (clobber (reg:CC 17))]
6978   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6979   "sbb{l}\t{%2, %k0|%k0, %2}"
6980   [(set_attr "type" "alu")
6981    (set_attr "pent_pair" "pu")
6982    (set_attr "ppro_uops" "few")
6983    (set_attr "mode" "SI")])
6984
6985 (define_expand "subsi3"
6986   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6987                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6988                              (match_operand:SI 2 "general_operand" "")))
6989               (clobber (reg:CC 17))])]
6990   ""
6991   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6992
6993 (define_insn "*subsi_1"
6994   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6995         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6996                   (match_operand:SI 2 "general_operand" "ri,rm")))
6997    (clobber (reg:CC 17))]
6998   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6999   "sub{l}\t{%2, %0|%0, %2}"
7000   [(set_attr "type" "alu")
7001    (set_attr "mode" "SI")])
7002
7003 (define_insn "*subsi_1_zext"
7004   [(set (match_operand:DI 0 "register_operand" "=r")
7005         (zero_extend:DI
7006           (minus:SI (match_operand:SI 1 "register_operand" "0")
7007                     (match_operand:SI 2 "general_operand" "rim"))))
7008    (clobber (reg:CC 17))]
7009   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7010   "sub{l}\t{%2, %k0|%k0, %2}"
7011   [(set_attr "type" "alu")
7012    (set_attr "mode" "SI")])
7013
7014 (define_insn "*subsi_2"
7015   [(set (reg 17)
7016         (compare
7017           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7018                     (match_operand:SI 2 "general_operand" "ri,rm"))
7019           (const_int 0)))
7020    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7021         (minus:SI (match_dup 1) (match_dup 2)))]
7022   "ix86_match_ccmode (insn, CCGOCmode)
7023    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7024   "sub{l}\t{%2, %0|%0, %2}"
7025   [(set_attr "type" "alu")
7026    (set_attr "mode" "SI")])
7027
7028 (define_insn "*subsi_2_zext"
7029   [(set (reg 17)
7030         (compare
7031           (minus:SI (match_operand:SI 1 "register_operand" "0")
7032                     (match_operand:SI 2 "general_operand" "rim"))
7033           (const_int 0)))
7034    (set (match_operand:DI 0 "register_operand" "=r")
7035         (zero_extend:DI
7036           (minus:SI (match_dup 1)
7037                     (match_dup 2))))]
7038   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7039    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7040   "sub{l}\t{%2, %k0|%k0, %2}"
7041   [(set_attr "type" "alu")
7042    (set_attr "mode" "SI")])
7043
7044 (define_insn "*subsi_3"
7045   [(set (reg 17)
7046         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7047                  (match_operand:SI 2 "general_operand" "ri,rm")))
7048    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7049         (minus:SI (match_dup 1) (match_dup 2)))]
7050   "ix86_match_ccmode (insn, CCmode)
7051    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7052   "sub{l}\t{%2, %0|%0, %2}"
7053   [(set_attr "type" "alu")
7054    (set_attr "mode" "SI")])
7055
7056 (define_insn "*subsi_3_zext"
7057   [(set (reg 17)
7058         (compare (match_operand:SI 1 "register_operand" "0")
7059                  (match_operand:SI 2 "general_operand" "rim")))
7060    (set (match_operand:DI 0 "register_operand" "=r")
7061         (zero_extend:DI
7062           (minus:SI (match_dup 1)
7063                     (match_dup 2))))]
7064   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7065    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7066   "sub{q}\t{%2, %0|%0, %2}"
7067   [(set_attr "type" "alu")
7068    (set_attr "mode" "DI")])
7069
7070 (define_expand "subhi3"
7071   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7072                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7073                              (match_operand:HI 2 "general_operand" "")))
7074               (clobber (reg:CC 17))])]
7075   "TARGET_HIMODE_MATH"
7076   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7077
7078 (define_insn "*subhi_1"
7079   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7080         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7081                   (match_operand:HI 2 "general_operand" "ri,rm")))
7082    (clobber (reg:CC 17))]
7083   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7084   "sub{w}\t{%2, %0|%0, %2}"
7085   [(set_attr "type" "alu")
7086    (set_attr "mode" "HI")])
7087
7088 (define_insn "*subhi_2"
7089   [(set (reg 17)
7090         (compare
7091           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7092                     (match_operand:HI 2 "general_operand" "ri,rm"))
7093           (const_int 0)))
7094    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7095         (minus:HI (match_dup 1) (match_dup 2)))]
7096   "ix86_match_ccmode (insn, CCGOCmode)
7097    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7098   "sub{w}\t{%2, %0|%0, %2}"
7099   [(set_attr "type" "alu")
7100    (set_attr "mode" "HI")])
7101
7102 (define_insn "*subhi_3"
7103   [(set (reg 17)
7104         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7105                  (match_operand:HI 2 "general_operand" "ri,rm")))
7106    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7107         (minus:HI (match_dup 1) (match_dup 2)))]
7108   "ix86_match_ccmode (insn, CCmode)
7109    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7110   "sub{w}\t{%2, %0|%0, %2}"
7111   [(set_attr "type" "alu")
7112    (set_attr "mode" "HI")])
7113
7114 (define_expand "subqi3"
7115   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7116                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7117                              (match_operand:QI 2 "general_operand" "")))
7118               (clobber (reg:CC 17))])]
7119   "TARGET_QIMODE_MATH"
7120   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7121
7122 (define_insn "*subqi_1"
7123   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7124         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7125                   (match_operand:QI 2 "general_operand" "qn,qmn")))
7126    (clobber (reg:CC 17))]
7127   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7128   "sub{b}\t{%2, %0|%0, %2}"
7129   [(set_attr "type" "alu")
7130    (set_attr "mode" "QI")])
7131
7132 (define_insn "*subqi_1_slp"
7133   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7134         (minus:QI (match_dup 0)
7135                   (match_operand:QI 1 "general_operand" "qn,qmn")))
7136    (clobber (reg:CC 17))]
7137   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7138    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7139   "sub{b}\t{%1, %0|%0, %1}"
7140   [(set_attr "type" "alu1")
7141    (set_attr "mode" "QI")])
7142
7143 (define_insn "*subqi_2"
7144   [(set (reg 17)
7145         (compare
7146           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7147                     (match_operand:QI 2 "general_operand" "qi,qm"))
7148           (const_int 0)))
7149    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7150         (minus:HI (match_dup 1) (match_dup 2)))]
7151   "ix86_match_ccmode (insn, CCGOCmode)
7152    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7153   "sub{b}\t{%2, %0|%0, %2}"
7154   [(set_attr "type" "alu")
7155    (set_attr "mode" "QI")])
7156
7157 (define_insn "*subqi_3"
7158   [(set (reg 17)
7159         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7160                  (match_operand:QI 2 "general_operand" "qi,qm")))
7161    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7162         (minus:HI (match_dup 1) (match_dup 2)))]
7163   "ix86_match_ccmode (insn, CCmode)
7164    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7165   "sub{b}\t{%2, %0|%0, %2}"
7166   [(set_attr "type" "alu")
7167    (set_attr "mode" "QI")])
7168
7169 ;; The patterns that match these are at the end of this file.
7170
7171 (define_expand "subxf3"
7172   [(set (match_operand:XF 0 "register_operand" "")
7173         (minus:XF (match_operand:XF 1 "register_operand" "")
7174                   (match_operand:XF 2 "register_operand" "")))]
7175   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
7176   "")
7177
7178 (define_expand "subtf3"
7179   [(set (match_operand:TF 0 "register_operand" "")
7180         (minus:TF (match_operand:TF 1 "register_operand" "")
7181                   (match_operand:TF 2 "register_operand" "")))]
7182   "TARGET_80387"
7183   "")
7184
7185 (define_expand "subdf3"
7186   [(set (match_operand:DF 0 "register_operand" "")
7187         (minus:DF (match_operand:DF 1 "register_operand" "")
7188                   (match_operand:DF 2 "nonimmediate_operand" "")))]
7189   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7190   "")
7191
7192 (define_expand "subsf3"
7193   [(set (match_operand:SF 0 "register_operand" "")
7194         (minus:SF (match_operand:SF 1 "register_operand" "")
7195                   (match_operand:SF 2 "nonimmediate_operand" "")))]
7196   "TARGET_80387 || TARGET_SSE_MATH"
7197   "")
7198 \f
7199 ;; Multiply instructions
7200
7201 (define_expand "muldi3"
7202   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7203                    (mult:DI (match_operand:DI 1 "register_operand" "")
7204                             (match_operand:DI 2 "x86_64_general_operand" "")))
7205               (clobber (reg:CC 17))])]
7206   "TARGET_64BIT"
7207   "")
7208
7209 (define_insn "*muldi3_1_rex64"
7210   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7211         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7212                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7213    (clobber (reg:CC 17))]
7214   "TARGET_64BIT
7215    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7216   "@
7217    imul{q}\t{%2, %1, %0|%0, %1, %2}
7218    imul{q}\t{%2, %1, %0|%0, %1, %2}
7219    imul{q}\t{%2, %0|%0, %2}"
7220   [(set_attr "type" "imul")
7221    (set_attr "prefix_0f" "0,0,1")
7222    (set (attr "athlon_decode")
7223         (cond [(eq_attr "cpu" "athlon")
7224                   (const_string "vector")
7225                (eq_attr "alternative" "1")
7226                   (const_string "vector")
7227                (and (eq_attr "alternative" "2")
7228                     (match_operand 1 "memory_operand" ""))
7229                   (const_string "vector")]
7230               (const_string "direct")))
7231    (set_attr "mode" "DI")])
7232
7233 (define_expand "mulsi3"
7234   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7235                    (mult:SI (match_operand:SI 1 "register_operand" "")
7236                             (match_operand:SI 2 "general_operand" "")))
7237               (clobber (reg:CC 17))])]
7238   ""
7239   "")
7240
7241 (define_insn "*mulsi3_1"
7242   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7243         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7244                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7245    (clobber (reg:CC 17))]
7246   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7247   "@
7248    imul{l}\t{%2, %1, %0|%0, %1, %2}
7249    imul{l}\t{%2, %1, %0|%0, %1, %2}
7250    imul{l}\t{%2, %0|%0, %2}"
7251   [(set_attr "type" "imul")
7252    (set_attr "prefix_0f" "0,0,1")
7253    (set (attr "athlon_decode")
7254         (cond [(eq_attr "cpu" "athlon")
7255                   (const_string "vector")
7256                (eq_attr "alternative" "1")
7257                   (const_string "vector")
7258                (and (eq_attr "alternative" "2")
7259                     (match_operand 1 "memory_operand" ""))
7260                   (const_string "vector")]
7261               (const_string "direct")))
7262    (set_attr "mode" "SI")])
7263
7264 (define_insn "*mulsi3_1_zext"
7265   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7266         (zero_extend:DI
7267           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7268                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7269    (clobber (reg:CC 17))]
7270   "TARGET_64BIT
7271    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7272   "@
7273    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7274    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7275    imul{l}\t{%2, %k0|%k0, %2}"
7276   [(set_attr "type" "imul")
7277    (set_attr "prefix_0f" "0,0,1")
7278    (set (attr "athlon_decode")
7279         (cond [(eq_attr "cpu" "athlon")
7280                   (const_string "vector")
7281                (eq_attr "alternative" "1")
7282                   (const_string "vector")
7283                (and (eq_attr "alternative" "2")
7284                     (match_operand 1 "memory_operand" ""))
7285                   (const_string "vector")]
7286               (const_string "direct")))
7287    (set_attr "mode" "SI")])
7288
7289 (define_expand "mulhi3"
7290   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7291                    (mult:HI (match_operand:HI 1 "register_operand" "")
7292                             (match_operand:HI 2 "general_operand" "")))
7293               (clobber (reg:CC 17))])]
7294   "TARGET_HIMODE_MATH"
7295   "")
7296
7297 (define_insn "*mulhi3_1"
7298   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7299         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7300                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7301    (clobber (reg:CC 17))]
7302   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7303   "@
7304    imul{w}\t{%2, %1, %0|%0, %1, %2}
7305    imul{w}\t{%2, %1, %0|%0, %1, %2}
7306    imul{w}\t{%2, %0|%0, %2}"
7307   [(set_attr "type" "imul")
7308    (set_attr "prefix_0f" "0,0,1")
7309    (set (attr "athlon_decode")
7310         (cond [(eq_attr "cpu" "athlon")
7311                   (const_string "vector")
7312                (eq_attr "alternative" "1,2")
7313                   (const_string "vector")]
7314               (const_string "direct")))
7315    (set_attr "mode" "HI")])
7316
7317 (define_expand "mulqi3"
7318   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7319                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7320                             (match_operand:QI 2 "register_operand" "")))
7321               (clobber (reg:CC 17))])]
7322   "TARGET_QIMODE_MATH"
7323   "")
7324
7325 (define_insn "*mulqi3_1"
7326   [(set (match_operand:QI 0 "register_operand" "=a")
7327         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7328                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7329    (clobber (reg:CC 17))]
7330   "TARGET_QIMODE_MATH
7331    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7332   "mul{b}\t%2"
7333   [(set_attr "type" "imul")
7334    (set_attr "length_immediate" "0")
7335    (set (attr "athlon_decode")
7336      (if_then_else (eq_attr "cpu" "athlon")
7337         (const_string "vector")
7338         (const_string "direct")))
7339    (set_attr "mode" "QI")])
7340
7341 (define_expand "umulqihi3"
7342   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7343                    (mult:HI (zero_extend:HI
7344                               (match_operand:QI 1 "nonimmediate_operand" ""))
7345                             (zero_extend:HI
7346                               (match_operand:QI 2 "register_operand" ""))))
7347               (clobber (reg:CC 17))])]
7348   "TARGET_QIMODE_MATH"
7349   "")
7350
7351 (define_insn "*umulqihi3_1"
7352   [(set (match_operand:HI 0 "register_operand" "=a")
7353         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7354                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7355    (clobber (reg:CC 17))]
7356   "TARGET_QIMODE_MATH
7357    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7358   "mul{b}\t%2"
7359   [(set_attr "type" "imul")
7360    (set_attr "length_immediate" "0")
7361    (set (attr "athlon_decode")
7362      (if_then_else (eq_attr "cpu" "athlon")
7363         (const_string "vector")
7364         (const_string "direct")))
7365    (set_attr "mode" "QI")])
7366
7367 (define_expand "mulqihi3"
7368   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7369                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7370                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7371               (clobber (reg:CC 17))])]
7372   "TARGET_QIMODE_MATH"
7373   "")
7374
7375 (define_insn "*mulqihi3_insn"
7376   [(set (match_operand:HI 0 "register_operand" "=a")
7377         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7378                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7379    (clobber (reg:CC 17))]
7380   "TARGET_QIMODE_MATH
7381    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7382   "imul{b}\t%2"
7383   [(set_attr "type" "imul")
7384    (set_attr "length_immediate" "0")
7385    (set (attr "athlon_decode")
7386      (if_then_else (eq_attr "cpu" "athlon")
7387         (const_string "vector")
7388         (const_string "direct")))
7389    (set_attr "mode" "QI")])
7390
7391 (define_expand "umulditi3"
7392   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7393                    (mult:TI (zero_extend:TI
7394                               (match_operand:DI 1 "nonimmediate_operand" ""))
7395                             (zero_extend:TI
7396                               (match_operand:DI 2 "register_operand" ""))))
7397               (clobber (reg:CC 17))])]
7398   "TARGET_64BIT"
7399   "")
7400
7401 (define_insn "*umulditi3_insn"
7402   [(set (match_operand:TI 0 "register_operand" "=A")
7403         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7404                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7405    (clobber (reg:CC 17))]
7406   "TARGET_64BIT
7407    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7408   "mul{q}\t%2"
7409   [(set_attr "type" "imul")
7410    (set_attr "ppro_uops" "few")
7411    (set_attr "length_immediate" "0")
7412    (set (attr "athlon_decode")
7413      (if_then_else (eq_attr "cpu" "athlon")
7414         (const_string "vector")
7415         (const_string "double")))
7416    (set_attr "mode" "DI")])
7417
7418 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7419 (define_expand "umulsidi3"
7420   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7421                    (mult:DI (zero_extend:DI
7422                               (match_operand:SI 1 "nonimmediate_operand" ""))
7423                             (zero_extend:DI
7424                               (match_operand:SI 2 "register_operand" ""))))
7425               (clobber (reg:CC 17))])]
7426   "!TARGET_64BIT"
7427   "")
7428
7429 (define_insn "*umulsidi3_insn"
7430   [(set (match_operand:DI 0 "register_operand" "=A")
7431         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7432                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7433    (clobber (reg:CC 17))]
7434   "!TARGET_64BIT
7435    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7436   "mul{l}\t%2"
7437   [(set_attr "type" "imul")
7438    (set_attr "ppro_uops" "few")
7439    (set_attr "length_immediate" "0")
7440    (set (attr "athlon_decode")
7441      (if_then_else (eq_attr "cpu" "athlon")
7442         (const_string "vector")
7443         (const_string "double")))
7444    (set_attr "mode" "SI")])
7445
7446 (define_expand "mulditi3"
7447   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7448                    (mult:TI (sign_extend:TI
7449                               (match_operand:DI 1 "nonimmediate_operand" ""))
7450                             (sign_extend:TI
7451                               (match_operand:DI 2 "register_operand" ""))))
7452               (clobber (reg:CC 17))])]
7453   "TARGET_64BIT"
7454   "")
7455
7456 (define_insn "*mulditi3_insn"
7457   [(set (match_operand:TI 0 "register_operand" "=A")
7458         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7459                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7460    (clobber (reg:CC 17))]
7461   "TARGET_64BIT
7462    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7463   "imul{q}\t%2"
7464   [(set_attr "type" "imul")
7465    (set_attr "length_immediate" "0")
7466    (set (attr "athlon_decode")
7467      (if_then_else (eq_attr "cpu" "athlon")
7468         (const_string "vector")
7469         (const_string "double")))
7470    (set_attr "mode" "DI")])
7471
7472 (define_expand "mulsidi3"
7473   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7474                    (mult:DI (sign_extend:DI
7475                               (match_operand:SI 1 "nonimmediate_operand" ""))
7476                             (sign_extend:DI
7477                               (match_operand:SI 2 "register_operand" ""))))
7478               (clobber (reg:CC 17))])]
7479   "!TARGET_64BIT"
7480   "")
7481
7482 (define_insn "*mulsidi3_insn"
7483   [(set (match_operand:DI 0 "register_operand" "=A")
7484         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7485                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7486    (clobber (reg:CC 17))]
7487   "!TARGET_64BIT
7488    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7489   "imul{l}\t%2"
7490   [(set_attr "type" "imul")
7491    (set_attr "length_immediate" "0")
7492    (set (attr "athlon_decode")
7493      (if_then_else (eq_attr "cpu" "athlon")
7494         (const_string "vector")
7495         (const_string "double")))
7496    (set_attr "mode" "SI")])
7497
7498 (define_expand "umuldi3_highpart"
7499   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7500                    (truncate:DI
7501                      (lshiftrt:TI
7502                        (mult:TI (zero_extend:TI
7503                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7504                                 (zero_extend:TI
7505                                   (match_operand:DI 2 "register_operand" "")))
7506                        (const_int 64))))
7507               (clobber (match_scratch:DI 3 ""))
7508               (clobber (reg:CC 17))])]
7509   "TARGET_64BIT"
7510   "")
7511
7512 (define_insn "*umuldi3_highpart_rex64"
7513   [(set (match_operand:DI 0 "register_operand" "=d")
7514         (truncate:DI
7515           (lshiftrt:TI
7516             (mult:TI (zero_extend:TI
7517                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7518                      (zero_extend:TI
7519                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7520             (const_int 64))))
7521    (clobber (match_scratch:DI 3 "=1"))
7522    (clobber (reg:CC 17))]
7523   "TARGET_64BIT
7524    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7525   "mul{q}\t%2"
7526   [(set_attr "type" "imul")
7527    (set_attr "ppro_uops" "few")
7528    (set_attr "length_immediate" "0")
7529    (set (attr "athlon_decode")
7530      (if_then_else (eq_attr "cpu" "athlon")
7531         (const_string "vector")
7532         (const_string "double")))
7533    (set_attr "mode" "DI")])
7534
7535 (define_expand "umulsi3_highpart"
7536   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7537                    (truncate:SI
7538                      (lshiftrt:DI
7539                        (mult:DI (zero_extend:DI
7540                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7541                                 (zero_extend:DI
7542                                   (match_operand:SI 2 "register_operand" "")))
7543                        (const_int 32))))
7544               (clobber (match_scratch:SI 3 ""))
7545               (clobber (reg:CC 17))])]
7546   ""
7547   "")
7548
7549 (define_insn "*umulsi3_highpart_insn"
7550   [(set (match_operand:SI 0 "register_operand" "=d")
7551         (truncate:SI
7552           (lshiftrt:DI
7553             (mult:DI (zero_extend:DI
7554                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7555                      (zero_extend:DI
7556                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7557             (const_int 32))))
7558    (clobber (match_scratch:SI 3 "=1"))
7559    (clobber (reg:CC 17))]
7560   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7561   "mul{l}\t%2"
7562   [(set_attr "type" "imul")
7563    (set_attr "ppro_uops" "few")
7564    (set_attr "length_immediate" "0")
7565    (set (attr "athlon_decode")
7566      (if_then_else (eq_attr "cpu" "athlon")
7567         (const_string "vector")
7568         (const_string "double")))
7569    (set_attr "mode" "SI")])
7570
7571 (define_insn "*umulsi3_highpart_zext"
7572   [(set (match_operand:DI 0 "register_operand" "=d")
7573         (zero_extend:DI (truncate:SI
7574           (lshiftrt:DI
7575             (mult:DI (zero_extend:DI
7576                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7577                      (zero_extend:DI
7578                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7579             (const_int 32)))))
7580    (clobber (match_scratch:SI 3 "=1"))
7581    (clobber (reg:CC 17))]
7582   "TARGET_64BIT
7583    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7584   "mul{l}\t%2"
7585   [(set_attr "type" "imul")
7586    (set_attr "ppro_uops" "few")
7587    (set_attr "length_immediate" "0")
7588    (set (attr "athlon_decode")
7589      (if_then_else (eq_attr "cpu" "athlon")
7590         (const_string "vector")
7591         (const_string "double")))
7592    (set_attr "mode" "SI")])
7593
7594 (define_expand "smuldi3_highpart"
7595   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7596                    (truncate:DI
7597                      (lshiftrt:TI
7598                        (mult:TI (sign_extend:TI
7599                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7600                                 (sign_extend:TI
7601                                   (match_operand:DI 2 "register_operand" "")))
7602                        (const_int 64))))
7603               (clobber (match_scratch:DI 3 ""))
7604               (clobber (reg:CC 17))])]
7605   "TARGET_64BIT"
7606   "")
7607
7608 (define_insn "*smuldi3_highpart_rex64"
7609   [(set (match_operand:DI 0 "register_operand" "=d")
7610         (truncate:DI
7611           (lshiftrt:TI
7612             (mult:TI (sign_extend:TI
7613                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7614                      (sign_extend:TI
7615                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7616             (const_int 64))))
7617    (clobber (match_scratch:DI 3 "=1"))
7618    (clobber (reg:CC 17))]
7619   "TARGET_64BIT
7620    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7621   "imul{q}\t%2"
7622   [(set_attr "type" "imul")
7623    (set_attr "ppro_uops" "few")
7624    (set (attr "athlon_decode")
7625      (if_then_else (eq_attr "cpu" "athlon")
7626         (const_string "vector")
7627         (const_string "double")))
7628    (set_attr "mode" "DI")])
7629
7630 (define_expand "smulsi3_highpart"
7631   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7632                    (truncate:SI
7633                      (lshiftrt:DI
7634                        (mult:DI (sign_extend:DI
7635                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7636                                 (sign_extend:DI
7637                                   (match_operand:SI 2 "register_operand" "")))
7638                        (const_int 32))))
7639               (clobber (match_scratch:SI 3 ""))
7640               (clobber (reg:CC 17))])]
7641   ""
7642   "")
7643
7644 (define_insn "*smulsi3_highpart_insn"
7645   [(set (match_operand:SI 0 "register_operand" "=d")
7646         (truncate:SI
7647           (lshiftrt:DI
7648             (mult:DI (sign_extend:DI
7649                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7650                      (sign_extend:DI
7651                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7652             (const_int 32))))
7653    (clobber (match_scratch:SI 3 "=1"))
7654    (clobber (reg:CC 17))]
7655   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7656   "imul{l}\t%2"
7657   [(set_attr "type" "imul")
7658    (set_attr "ppro_uops" "few")
7659    (set (attr "athlon_decode")
7660      (if_then_else (eq_attr "cpu" "athlon")
7661         (const_string "vector")
7662         (const_string "double")))
7663    (set_attr "mode" "SI")])
7664
7665 (define_insn "*smulsi3_highpart_zext"
7666   [(set (match_operand:DI 0 "register_operand" "=d")
7667         (zero_extend:DI (truncate:SI
7668           (lshiftrt:DI
7669             (mult:DI (sign_extend:DI
7670                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7671                      (sign_extend:DI
7672                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7673             (const_int 32)))))
7674    (clobber (match_scratch:SI 3 "=1"))
7675    (clobber (reg:CC 17))]
7676   "TARGET_64BIT
7677    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7678   "imul{l}\t%2"
7679   [(set_attr "type" "imul")
7680    (set_attr "ppro_uops" "few")
7681    (set (attr "athlon_decode")
7682      (if_then_else (eq_attr "cpu" "athlon")
7683         (const_string "vector")
7684         (const_string "double")))
7685    (set_attr "mode" "SI")])
7686
7687 ;; The patterns that match these are at the end of this file.
7688
7689 (define_expand "mulxf3"
7690   [(set (match_operand:XF 0 "register_operand" "")
7691         (mult:XF (match_operand:XF 1 "register_operand" "")
7692                  (match_operand:XF 2 "register_operand" "")))]
7693   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
7694   "")
7695
7696 (define_expand "multf3"
7697   [(set (match_operand:TF 0 "register_operand" "")
7698         (mult:TF (match_operand:TF 1 "register_operand" "")
7699                  (match_operand:TF 2 "register_operand" "")))]
7700   "TARGET_80387"
7701   "")
7702
7703 (define_expand "muldf3"
7704   [(set (match_operand:DF 0 "register_operand" "")
7705         (mult:DF (match_operand:DF 1 "register_operand" "")
7706                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7707   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7708   "")
7709
7710 (define_expand "mulsf3"
7711   [(set (match_operand:SF 0 "register_operand" "")
7712         (mult:SF (match_operand:SF 1 "register_operand" "")
7713                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7714   "TARGET_80387 || TARGET_SSE_MATH"
7715   "")
7716 \f
7717 ;; Divide instructions
7718
7719 (define_insn "divqi3"
7720   [(set (match_operand:QI 0 "register_operand" "=a")
7721         (div:QI (match_operand:HI 1 "register_operand" "0")
7722                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7723    (clobber (reg:CC 17))]
7724   "TARGET_QIMODE_MATH"
7725   "idiv{b}\t%2"
7726   [(set_attr "type" "idiv")
7727    (set_attr "mode" "QI")
7728    (set_attr "ppro_uops" "few")])
7729
7730 (define_insn "udivqi3"
7731   [(set (match_operand:QI 0 "register_operand" "=a")
7732         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7733                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7734    (clobber (reg:CC 17))]
7735   "TARGET_QIMODE_MATH"
7736   "div{b}\t%2"
7737   [(set_attr "type" "idiv")
7738    (set_attr "mode" "QI")
7739    (set_attr "ppro_uops" "few")])
7740
7741 ;; The patterns that match these are at the end of this file.
7742
7743 (define_expand "divxf3"
7744   [(set (match_operand:XF 0 "register_operand" "")
7745         (div:XF (match_operand:XF 1 "register_operand" "")
7746                 (match_operand:XF 2 "register_operand" "")))]
7747   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
7748   "")
7749
7750 (define_expand "divtf3"
7751   [(set (match_operand:TF 0 "register_operand" "")
7752         (div:TF (match_operand:TF 1 "register_operand" "")
7753                 (match_operand:TF 2 "register_operand" "")))]
7754   "TARGET_80387"
7755   "")
7756
7757 (define_expand "divdf3"
7758   [(set (match_operand:DF 0 "register_operand" "")
7759         (div:DF (match_operand:DF 1 "register_operand" "")
7760                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7761    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7762    "")
7763  
7764 (define_expand "divsf3"
7765   [(set (match_operand:SF 0 "register_operand" "")
7766         (div:SF (match_operand:SF 1 "register_operand" "")
7767                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7768   "TARGET_80387 || TARGET_SSE_MATH"
7769   "")
7770 \f
7771 ;; Remainder instructions.
7772
7773 (define_expand "divmoddi4"
7774   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7775                    (div:DI (match_operand:DI 1 "register_operand" "")
7776                            (match_operand:DI 2 "nonimmediate_operand" "")))
7777               (set (match_operand:DI 3 "register_operand" "")
7778                    (mod:DI (match_dup 1) (match_dup 2)))
7779               (clobber (reg:CC 17))])]
7780   "TARGET_64BIT"
7781   "")
7782
7783 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7784 ;; Penalize eax case slightly because it results in worse scheduling
7785 ;; of code.
7786 (define_insn "*divmoddi4_nocltd_rex64"
7787   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7788         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7789                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7790    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7791         (mod:DI (match_dup 2) (match_dup 3)))
7792    (clobber (reg:CC 17))]
7793   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7794   "#"
7795   [(set_attr "type" "multi")])
7796
7797 (define_insn "*divmoddi4_cltd_rex64"
7798   [(set (match_operand:DI 0 "register_operand" "=a")
7799         (div:DI (match_operand:DI 2 "register_operand" "a")
7800                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7801    (set (match_operand:DI 1 "register_operand" "=&d")
7802         (mod:DI (match_dup 2) (match_dup 3)))
7803    (clobber (reg:CC 17))]
7804   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7805   "#"
7806   [(set_attr "type" "multi")])
7807
7808 (define_insn "*divmoddi_noext_rex64"
7809   [(set (match_operand:DI 0 "register_operand" "=a")
7810         (div:DI (match_operand:DI 1 "register_operand" "0")
7811                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7812    (set (match_operand:DI 3 "register_operand" "=d")
7813         (mod:DI (match_dup 1) (match_dup 2)))
7814    (use (match_operand:DI 4 "register_operand" "3"))
7815    (clobber (reg:CC 17))]
7816   "TARGET_64BIT"
7817   "idiv{q}\t%2"
7818   [(set_attr "type" "idiv")
7819    (set_attr "mode" "DI")
7820    (set_attr "ppro_uops" "few")])
7821
7822 (define_split
7823   [(set (match_operand:DI 0 "register_operand" "")
7824         (div:DI (match_operand:DI 1 "register_operand" "")
7825                 (match_operand:DI 2 "nonimmediate_operand" "")))
7826    (set (match_operand:DI 3 "register_operand" "")
7827         (mod:DI (match_dup 1) (match_dup 2)))
7828    (clobber (reg:CC 17))]
7829   "TARGET_64BIT && reload_completed"
7830   [(parallel [(set (match_dup 3)
7831                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7832               (clobber (reg:CC 17))])
7833    (parallel [(set (match_dup 0)
7834                    (div:DI (reg:DI 0) (match_dup 2)))
7835               (set (match_dup 3)
7836                    (mod:DI (reg:DI 0) (match_dup 2)))
7837               (use (match_dup 3))
7838               (clobber (reg:CC 17))])]
7839 {
7840   /* Avoid use of cltd in favor of a mov+shift.  */
7841   if (!TARGET_USE_CLTD && !optimize_size)
7842     {
7843       if (true_regnum (operands[1]))
7844         emit_move_insn (operands[0], operands[1]);
7845       else
7846         emit_move_insn (operands[3], operands[1]);
7847       operands[4] = operands[3];
7848     }
7849   else
7850     {
7851       if (true_regnum (operands[1]))
7852         abort();
7853       operands[4] = operands[1];
7854     }
7855 })
7856
7857
7858 (define_expand "divmodsi4"
7859   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7860                    (div:SI (match_operand:SI 1 "register_operand" "")
7861                            (match_operand:SI 2 "nonimmediate_operand" "")))
7862               (set (match_operand:SI 3 "register_operand" "")
7863                    (mod:SI (match_dup 1) (match_dup 2)))
7864               (clobber (reg:CC 17))])]
7865   ""
7866   "")
7867
7868 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7869 ;; Penalize eax case slightly because it results in worse scheduling
7870 ;; of code.
7871 (define_insn "*divmodsi4_nocltd"
7872   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7873         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7874                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7875    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7876         (mod:SI (match_dup 2) (match_dup 3)))
7877    (clobber (reg:CC 17))]
7878   "!optimize_size && !TARGET_USE_CLTD"
7879   "#"
7880   [(set_attr "type" "multi")])
7881
7882 (define_insn "*divmodsi4_cltd"
7883   [(set (match_operand:SI 0 "register_operand" "=a")
7884         (div:SI (match_operand:SI 2 "register_operand" "a")
7885                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7886    (set (match_operand:SI 1 "register_operand" "=&d")
7887         (mod:SI (match_dup 2) (match_dup 3)))
7888    (clobber (reg:CC 17))]
7889   "optimize_size || TARGET_USE_CLTD"
7890   "#"
7891   [(set_attr "type" "multi")])
7892
7893 (define_insn "*divmodsi_noext"
7894   [(set (match_operand:SI 0 "register_operand" "=a")
7895         (div:SI (match_operand:SI 1 "register_operand" "0")
7896                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7897    (set (match_operand:SI 3 "register_operand" "=d")
7898         (mod:SI (match_dup 1) (match_dup 2)))
7899    (use (match_operand:SI 4 "register_operand" "3"))
7900    (clobber (reg:CC 17))]
7901   ""
7902   "idiv{l}\t%2"
7903   [(set_attr "type" "idiv")
7904    (set_attr "mode" "SI")
7905    (set_attr "ppro_uops" "few")])
7906
7907 (define_split
7908   [(set (match_operand:SI 0 "register_operand" "")
7909         (div:SI (match_operand:SI 1 "register_operand" "")
7910                 (match_operand:SI 2 "nonimmediate_operand" "")))
7911    (set (match_operand:SI 3 "register_operand" "")
7912         (mod:SI (match_dup 1) (match_dup 2)))
7913    (clobber (reg:CC 17))]
7914   "reload_completed"
7915   [(parallel [(set (match_dup 3)
7916                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7917               (clobber (reg:CC 17))])
7918    (parallel [(set (match_dup 0)
7919                    (div:SI (reg:SI 0) (match_dup 2)))
7920               (set (match_dup 3)
7921                    (mod:SI (reg:SI 0) (match_dup 2)))
7922               (use (match_dup 3))
7923               (clobber (reg:CC 17))])]
7924 {
7925   /* Avoid use of cltd in favor of a mov+shift.  */
7926   if (!TARGET_USE_CLTD && !optimize_size)
7927     {
7928       if (true_regnum (operands[1]))
7929         emit_move_insn (operands[0], operands[1]);
7930       else
7931         emit_move_insn (operands[3], operands[1]);
7932       operands[4] = operands[3];
7933     }
7934   else
7935     {
7936       if (true_regnum (operands[1]))
7937         abort();
7938       operands[4] = operands[1];
7939     }
7940 })
7941 ;; %%% Split me.
7942 (define_insn "divmodhi4"
7943   [(set (match_operand:HI 0 "register_operand" "=a")
7944         (div:HI (match_operand:HI 1 "register_operand" "0")
7945                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7946    (set (match_operand:HI 3 "register_operand" "=&d")
7947         (mod:HI (match_dup 1) (match_dup 2)))
7948    (clobber (reg:CC 17))]
7949   "TARGET_HIMODE_MATH"
7950   "cwtd\;idiv{w}\t%2"
7951   [(set_attr "type" "multi")
7952    (set_attr "length_immediate" "0")
7953    (set_attr "mode" "SI")])
7954
7955 (define_insn "udivmoddi4"
7956   [(set (match_operand:DI 0 "register_operand" "=a")
7957         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7958                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7959    (set (match_operand:DI 3 "register_operand" "=&d")
7960         (umod:DI (match_dup 1) (match_dup 2)))
7961    (clobber (reg:CC 17))]
7962   "TARGET_64BIT"
7963   "xor{q}\t%3, %3\;div{q}\t%2"
7964   [(set_attr "type" "multi")
7965    (set_attr "length_immediate" "0")
7966    (set_attr "mode" "DI")])
7967
7968 (define_insn "*udivmoddi4_noext"
7969   [(set (match_operand:DI 0 "register_operand" "=a")
7970         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7971                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7972    (set (match_operand:DI 3 "register_operand" "=d")
7973         (umod:DI (match_dup 1) (match_dup 2)))
7974    (use (match_dup 3))
7975    (clobber (reg:CC 17))]
7976   "TARGET_64BIT"
7977   "div{q}\t%2"
7978   [(set_attr "type" "idiv")
7979    (set_attr "ppro_uops" "few")
7980    (set_attr "mode" "DI")])
7981
7982 (define_split
7983   [(set (match_operand:DI 0 "register_operand" "")
7984         (udiv:DI (match_operand:DI 1 "register_operand" "")
7985                  (match_operand:DI 2 "nonimmediate_operand" "")))
7986    (set (match_operand:DI 3 "register_operand" "")
7987         (umod:DI (match_dup 1) (match_dup 2)))
7988    (clobber (reg:CC 17))]
7989   "TARGET_64BIT && reload_completed"
7990   [(set (match_dup 3) (const_int 0))
7991    (parallel [(set (match_dup 0)
7992                    (udiv:DI (match_dup 1) (match_dup 2)))
7993               (set (match_dup 3)
7994                    (umod:DI (match_dup 1) (match_dup 2)))
7995               (use (match_dup 3))
7996               (clobber (reg:CC 17))])]
7997   "")
7998
7999 (define_insn "udivmodsi4"
8000   [(set (match_operand:SI 0 "register_operand" "=a")
8001         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8002                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8003    (set (match_operand:SI 3 "register_operand" "=&d")
8004         (umod:SI (match_dup 1) (match_dup 2)))
8005    (clobber (reg:CC 17))]
8006   ""
8007   "xor{l}\t%3, %3\;div{l}\t%2"
8008   [(set_attr "type" "multi")
8009    (set_attr "length_immediate" "0")
8010    (set_attr "mode" "SI")])
8011
8012 (define_insn "*udivmodsi4_noext"
8013   [(set (match_operand:SI 0 "register_operand" "=a")
8014         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8015                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8016    (set (match_operand:SI 3 "register_operand" "=d")
8017         (umod:SI (match_dup 1) (match_dup 2)))
8018    (use (match_dup 3))
8019    (clobber (reg:CC 17))]
8020   ""
8021   "div{l}\t%2"
8022   [(set_attr "type" "idiv")
8023    (set_attr "ppro_uops" "few")
8024    (set_attr "mode" "SI")])
8025
8026 (define_split
8027   [(set (match_operand:SI 0 "register_operand" "")
8028         (udiv:SI (match_operand:SI 1 "register_operand" "")
8029                  (match_operand:SI 2 "nonimmediate_operand" "")))
8030    (set (match_operand:SI 3 "register_operand" "")
8031         (umod:SI (match_dup 1) (match_dup 2)))
8032    (clobber (reg:CC 17))]
8033   "reload_completed"
8034   [(set (match_dup 3) (const_int 0))
8035    (parallel [(set (match_dup 0)
8036                    (udiv:SI (match_dup 1) (match_dup 2)))
8037               (set (match_dup 3)
8038                    (umod:SI (match_dup 1) (match_dup 2)))
8039               (use (match_dup 3))
8040               (clobber (reg:CC 17))])]
8041   "")
8042
8043 (define_expand "udivmodhi4"
8044   [(set (match_dup 4) (const_int 0))
8045    (parallel [(set (match_operand:HI 0 "register_operand" "")
8046                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8047                             (match_operand:HI 2 "nonimmediate_operand" "")))
8048               (set (match_operand:HI 3 "register_operand" "")
8049                    (umod:HI (match_dup 1) (match_dup 2)))
8050               (use (match_dup 4))
8051               (clobber (reg:CC 17))])]
8052   "TARGET_HIMODE_MATH"
8053   "operands[4] = gen_reg_rtx (HImode);")
8054
8055 (define_insn "*udivmodhi_noext"
8056   [(set (match_operand:HI 0 "register_operand" "=a")
8057         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8058                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8059    (set (match_operand:HI 3 "register_operand" "=d")
8060         (umod:HI (match_dup 1) (match_dup 2)))
8061    (use (match_operand:HI 4 "register_operand" "3"))
8062    (clobber (reg:CC 17))]
8063   ""
8064   "div{w}\t%2"
8065   [(set_attr "type" "idiv")
8066    (set_attr "mode" "HI")
8067    (set_attr "ppro_uops" "few")])
8068
8069 ;; We can not use div/idiv for double division, because it causes
8070 ;; "division by zero" on the overflow and that's not what we expect
8071 ;; from truncate.  Because true (non truncating) double division is
8072 ;; never generated, we can't create this insn anyway.
8073 ;
8074 ;(define_insn ""
8075 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8076 ;       (truncate:SI
8077 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8078 ;                  (zero_extend:DI
8079 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8080 ;   (set (match_operand:SI 3 "register_operand" "=d")
8081 ;       (truncate:SI
8082 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8083 ;   (clobber (reg:CC 17))]
8084 ;  ""
8085 ;  "div{l}\t{%2, %0|%0, %2}"
8086 ;  [(set_attr "type" "idiv")
8087 ;   (set_attr "ppro_uops" "few")])
8088 \f
8089 ;;- Logical AND instructions
8090
8091 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8092 ;; Note that this excludes ah.
8093
8094 (define_insn "*testdi_1_rex64"
8095   [(set (reg 17)
8096         (compare
8097           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8098                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8099           (const_int 0)))]
8100   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8101    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8102   "@
8103    test{l}\t{%k1, %k0|%k0, %k1} 
8104    test{l}\t{%k1, %k0|%k0, %k1} 
8105    test{q}\t{%1, %0|%0, %1} 
8106    test{q}\t{%1, %0|%0, %1} 
8107    test{q}\t{%1, %0|%0, %1}"
8108   [(set_attr "type" "test")
8109    (set_attr "modrm" "0,1,0,1,1")
8110    (set_attr "mode" "SI,SI,DI,DI,DI")
8111    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8112
8113 (define_insn "testsi_1"
8114   [(set (reg 17)
8115         (compare
8116           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8117                   (match_operand:SI 1 "general_operand" "in,in,rin"))
8118           (const_int 0)))]
8119   "ix86_match_ccmode (insn, CCNOmode)
8120    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8121   "test{l}\t{%1, %0|%0, %1}"
8122   [(set_attr "type" "test")
8123    (set_attr "modrm" "0,1,1")
8124    (set_attr "mode" "SI")
8125    (set_attr "pent_pair" "uv,np,uv")])
8126
8127 (define_expand "testsi_ccno_1"
8128   [(set (reg:CCNO 17)
8129         (compare:CCNO
8130           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8131                   (match_operand:SI 1 "nonmemory_operand" ""))
8132           (const_int 0)))]
8133   ""
8134   "")
8135
8136 (define_insn "*testhi_1"
8137   [(set (reg 17)
8138         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8139                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8140                  (const_int 0)))]
8141   "ix86_match_ccmode (insn, CCNOmode)
8142    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8143   "test{w}\t{%1, %0|%0, %1}"
8144   [(set_attr "type" "test")
8145    (set_attr "modrm" "0,1,1")
8146    (set_attr "mode" "HI")
8147    (set_attr "pent_pair" "uv,np,uv")])
8148
8149 (define_expand "testqi_ccz_1"
8150   [(set (reg:CCZ 17)
8151         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8152                              (match_operand:QI 1 "nonmemory_operand" ""))
8153                  (const_int 0)))]
8154   ""
8155   "")
8156
8157 (define_insn "*testqi_1"
8158   [(set (reg 17)
8159         (compare (and:QI (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8160                          (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8161                  (const_int 0)))]
8162   "ix86_match_ccmode (insn, CCNOmode)
8163    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8164 {
8165   if (which_alternative == 3)
8166     {
8167       if (GET_CODE (operands[1]) == CONST_INT
8168           && (INTVAL (operands[1]) & 0xffffff00))
8169         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8170       return "test{l}\t{%1, %k0|%k0, %1}";
8171     }
8172   return "test{b}\t{%1, %0|%0, %1}";
8173 }
8174   [(set_attr "type" "test")
8175    (set_attr "modrm" "0,1,1,1")
8176    (set_attr "mode" "QI,QI,QI,SI")
8177    (set_attr "pent_pair" "uv,np,uv,np")])
8178
8179 (define_expand "testqi_ext_ccno_0"
8180   [(set (reg:CCNO 17)
8181         (compare:CCNO
8182           (and:SI
8183             (zero_extract:SI
8184               (match_operand 0 "ext_register_operand" "")
8185               (const_int 8)
8186               (const_int 8))
8187             (match_operand 1 "const_int_operand" ""))
8188           (const_int 0)))]
8189   ""
8190   "")
8191
8192 (define_insn "*testqi_ext_0"
8193   [(set (reg 17)
8194         (compare
8195           (and:SI
8196             (zero_extract:SI
8197               (match_operand 0 "ext_register_operand" "Q")
8198               (const_int 8)
8199               (const_int 8))
8200             (match_operand 1 "const_int_operand" "n"))
8201           (const_int 0)))]
8202   "ix86_match_ccmode (insn, CCNOmode)"
8203   "test{b}\t{%1, %h0|%h0, %1}"
8204   [(set_attr "type" "test")
8205    (set_attr "mode" "QI")
8206    (set_attr "length_immediate" "1")
8207    (set_attr "pent_pair" "np")])
8208
8209 (define_insn "*testqi_ext_1"
8210   [(set (reg 17)
8211         (compare
8212           (and:SI
8213             (zero_extract:SI
8214               (match_operand 0 "ext_register_operand" "Q")
8215               (const_int 8)
8216               (const_int 8))
8217             (zero_extend:SI
8218               (match_operand:QI 1 "general_operand" "Qm")))
8219           (const_int 0)))]
8220   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8221    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8222   "test{b}\t{%1, %h0|%h0, %1}"
8223   [(set_attr "type" "test")
8224    (set_attr "mode" "QI")])
8225
8226 (define_insn "*testqi_ext_1_rex64"
8227   [(set (reg 17)
8228         (compare
8229           (and:SI
8230             (zero_extract:SI
8231               (match_operand 0 "ext_register_operand" "Q")
8232               (const_int 8)
8233               (const_int 8))
8234             (zero_extend:SI
8235               (match_operand:QI 1 "register_operand" "Q")))
8236           (const_int 0)))]
8237   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8238   "test{b}\t{%1, %h0|%h0, %1}"
8239   [(set_attr "type" "test")
8240    (set_attr "mode" "QI")])
8241
8242 (define_insn "*testqi_ext_2"
8243   [(set (reg 17)
8244         (compare
8245           (and:SI
8246             (zero_extract:SI
8247               (match_operand 0 "ext_register_operand" "Q")
8248               (const_int 8)
8249               (const_int 8))
8250             (zero_extract:SI
8251               (match_operand 1 "ext_register_operand" "Q")
8252               (const_int 8)
8253               (const_int 8)))
8254           (const_int 0)))]
8255   "ix86_match_ccmode (insn, CCNOmode)"
8256   "test{b}\t{%h1, %h0|%h0, %h1}"
8257   [(set_attr "type" "test")
8258    (set_attr "mode" "QI")])
8259
8260 ;; Combine likes to form bit extractions for some tests.  Humor it.
8261 (define_insn "*testqi_ext_3"
8262   [(set (reg 17)
8263         (compare (zero_extract:SI
8264                    (match_operand 0 "nonimmediate_operand" "rm")
8265                    (match_operand:SI 1 "const_int_operand" "")
8266                    (match_operand:SI 2 "const_int_operand" ""))
8267                  (const_int 0)))]
8268   "ix86_match_ccmode (insn, CCNOmode)
8269    && (GET_MODE (operands[0]) == SImode
8270        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8271        || GET_MODE (operands[0]) == HImode
8272        || GET_MODE (operands[0]) == QImode)"
8273   "#")
8274
8275 (define_insn "*testqi_ext_3_rex64"
8276   [(set (reg 17)
8277         (compare (zero_extract:DI
8278                    (match_operand 0 "nonimmediate_operand" "rm")
8279                    (match_operand:DI 1 "const_int_operand" "")
8280                    (match_operand:DI 2 "const_int_operand" ""))
8281                  (const_int 0)))]
8282   "TARGET_64BIT
8283    && ix86_match_ccmode (insn, CCNOmode)
8284    /* The code below cannot deal with constants outside HOST_WIDE_INT.  */
8285    && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
8286    /* Ensure that resulting mask is zero or sign extended operand.  */
8287    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8288        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8289            && INTVAL (operands[1]) > 32))
8290    && (GET_MODE (operands[0]) == SImode
8291        || GET_MODE (operands[0]) == DImode
8292        || GET_MODE (operands[0]) == HImode
8293        || GET_MODE (operands[0]) == QImode)"
8294   "#")
8295
8296 (define_split
8297   [(set (reg 17)
8298         (compare (zero_extract
8299                    (match_operand 0 "nonimmediate_operand" "")
8300                    (match_operand 1 "const_int_operand" "")
8301                    (match_operand 2 "const_int_operand" ""))
8302                  (const_int 0)))]
8303   "ix86_match_ccmode (insn, CCNOmode)"
8304   [(set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
8305 {
8306   HOST_WIDE_INT len = INTVAL (operands[1]);
8307   HOST_WIDE_INT pos = INTVAL (operands[2]);
8308   HOST_WIDE_INT mask;
8309   enum machine_mode mode, submode;
8310
8311   mode = GET_MODE (operands[0]);
8312   if (GET_CODE (operands[0]) == MEM)
8313     {
8314       /* ??? Combine likes to put non-volatile mem extractions in QImode
8315          no matter the size of the test.  So find a mode that works.  */
8316       if (! MEM_VOLATILE_P (operands[0]))
8317         {
8318           mode = smallest_mode_for_size (pos + len, MODE_INT);
8319           operands[0] = adjust_address (operands[0], mode, 0);
8320         }
8321     }
8322   else if (GET_CODE (operands[0]) == SUBREG
8323            && (submode = GET_MODE (SUBREG_REG (operands[0])),
8324                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8325            && pos + len <= GET_MODE_BITSIZE (submode))
8326     {
8327       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8328       mode = submode;
8329       operands[0] = SUBREG_REG (operands[0]);
8330     }
8331   else if (mode == HImode && pos + len <= 8)
8332     {
8333       /* Small HImode tests can be converted to QImode.  */
8334       mode = QImode;
8335       operands[0] = gen_lowpart (QImode, operands[0]);
8336     }
8337
8338   mask  = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
8339   mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
8340
8341   operands[3] = gen_rtx_AND (mode, operands[0], gen_int_mode (mask, mode));
8342 })
8343
8344 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8345 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8346 ;; this is relatively important trick.
8347 ;; Do the conversion only post-reload to avoid limiting of the register class
8348 ;; to QI regs.
8349 (define_split
8350   [(set (reg 17)
8351         (compare
8352           (and (match_operand 0 "register_operand" "")
8353                (match_operand 1 "const_int_operand" ""))
8354           (const_int 0)))]
8355    "reload_completed
8356     && QI_REG_P (operands[0])
8357     && ((ix86_match_ccmode (insn, CCZmode)
8358          && !(INTVAL (operands[1]) & ~(255 << 8)))
8359         || (ix86_match_ccmode (insn, CCNOmode)
8360             && !(INTVAL (operands[1]) & ~(127 << 8))))
8361     && GET_MODE (operands[0]) != QImode"
8362   [(set (reg:CCNO 17)
8363         (compare:CCNO
8364           (and:SI (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8365                   (match_dup 1))
8366           (const_int 0)))]
8367   "operands[0] = gen_lowpart (SImode, operands[0]);
8368    operands[1] = gen_int_mode (INTVAL (operands[1]) >> 8, SImode);")
8369
8370 (define_split
8371   [(set (reg 17)
8372         (compare
8373           (and (match_operand 0 "nonimmediate_operand" "")
8374                (match_operand 1 "const_int_operand" ""))
8375           (const_int 0)))]
8376    "reload_completed
8377     && (!REG_P (operands[0]) || ANY_QI_REG_P (operands[0]))
8378     && ((ix86_match_ccmode (insn, CCZmode)
8379          && !(INTVAL (operands[1]) & ~255))
8380         || (ix86_match_ccmode (insn, CCNOmode)
8381             && !(INTVAL (operands[1]) & ~127)))
8382     && GET_MODE (operands[0]) != QImode"
8383   [(set (reg:CCNO 17)
8384         (compare:CCNO
8385           (and:QI (match_dup 0)
8386                   (match_dup 1))
8387           (const_int 0)))]
8388   "operands[0] = gen_lowpart (QImode, operands[0]);
8389    operands[1] = gen_lowpart (QImode, operands[1]);")
8390
8391
8392 ;; %%% This used to optimize known byte-wide and operations to memory,
8393 ;; and sometimes to QImode registers.  If this is considered useful,
8394 ;; it should be done with splitters.
8395
8396 (define_expand "anddi3"
8397   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8398         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8399                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8400    (clobber (reg:CC 17))]
8401   "TARGET_64BIT"
8402   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8403
8404 (define_insn "*anddi_1_rex64"
8405   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8406         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8407                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8408    (clobber (reg:CC 17))]
8409   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8410 {
8411   switch (get_attr_type (insn))
8412     {
8413     case TYPE_IMOVX:
8414       {
8415         enum machine_mode mode;
8416
8417         if (GET_CODE (operands[2]) != CONST_INT)
8418           abort ();
8419         if (INTVAL (operands[2]) == 0xff)
8420           mode = QImode;
8421         else if (INTVAL (operands[2]) == 0xffff)
8422           mode = HImode;
8423         else
8424           abort ();
8425         
8426         operands[1] = gen_lowpart (mode, operands[1]);
8427         if (mode == QImode)
8428           return "movz{bq|x}\t{%1,%0|%0, %1}";
8429         else
8430           return "movz{wq|x}\t{%1,%0|%0, %1}";
8431       }
8432
8433     default:
8434       if (! rtx_equal_p (operands[0], operands[1]))
8435         abort ();
8436       if (get_attr_mode (insn) == MODE_SI)
8437         return "and{l}\t{%k2, %k0|%k0, %k2}";
8438       else
8439         return "and{q}\t{%2, %0|%0, %2}";
8440     }
8441 }
8442   [(set_attr "type" "alu,alu,alu,imovx")
8443    (set_attr "length_immediate" "*,*,*,0")
8444    (set_attr "mode" "SI,DI,DI,DI")])
8445
8446 (define_insn "*anddi_2"
8447   [(set (reg 17)
8448         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8449                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8450                  (const_int 0)))
8451    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8452         (and:DI (match_dup 1) (match_dup 2)))]
8453   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8454    && ix86_binary_operator_ok (AND, DImode, operands)"
8455   "@
8456    and{l}\t{%k2, %k0|%k0, %k2} 
8457    and{q}\t{%2, %0|%0, %2} 
8458    and{q}\t{%2, %0|%0, %2}"
8459   [(set_attr "type" "alu")
8460    (set_attr "mode" "SI,DI,DI")])
8461
8462 (define_expand "andsi3"
8463   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8464         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8465                 (match_operand:SI 2 "general_operand" "")))
8466    (clobber (reg:CC 17))]
8467   ""
8468   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8469
8470 (define_insn "*andsi_1"
8471   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8472         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8473                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8474    (clobber (reg:CC 17))]
8475   "ix86_binary_operator_ok (AND, SImode, operands)"
8476 {
8477   switch (get_attr_type (insn))
8478     {
8479     case TYPE_IMOVX:
8480       {
8481         enum machine_mode mode;
8482
8483         if (GET_CODE (operands[2]) != CONST_INT)
8484           abort ();
8485         if (INTVAL (operands[2]) == 0xff)
8486           mode = QImode;
8487         else if (INTVAL (operands[2]) == 0xffff)
8488           mode = HImode;
8489         else
8490           abort ();
8491         
8492         operands[1] = gen_lowpart (mode, operands[1]);
8493         if (mode == QImode)
8494           return "movz{bl|x}\t{%1,%0|%0, %1}";
8495         else
8496           return "movz{wl|x}\t{%1,%0|%0, %1}";
8497       }
8498
8499     default:
8500       if (! rtx_equal_p (operands[0], operands[1]))
8501         abort ();
8502       return "and{l}\t{%2, %0|%0, %2}";
8503     }
8504 }
8505   [(set_attr "type" "alu,alu,imovx")
8506    (set_attr "length_immediate" "*,*,0")
8507    (set_attr "mode" "SI")])
8508
8509 (define_split
8510   [(set (match_operand 0 "register_operand" "")
8511         (and (match_dup 0)
8512              (const_int -65536)))
8513    (clobber (reg:CC 17))]
8514   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8515   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8516   "operands[1] = gen_lowpart (HImode, operands[0]);")
8517
8518 (define_split
8519   [(set (match_operand 0 "ext_register_operand" "")
8520         (and (match_dup 0)
8521              (const_int -256)))
8522    (clobber (reg:CC 17))]
8523   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8524   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8525   "operands[1] = gen_lowpart (QImode, operands[0]);")
8526
8527 (define_split
8528   [(set (match_operand 0 "ext_register_operand" "")
8529         (and (match_dup 0)
8530              (const_int -65281)))
8531    (clobber (reg:CC 17))]
8532   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8533   [(parallel [(set (zero_extract:SI (match_dup 0)
8534                                     (const_int 8)
8535                                     (const_int 8))
8536                    (xor:SI 
8537                      (zero_extract:SI (match_dup 0)
8538                                       (const_int 8)
8539                                       (const_int 8))
8540                      (zero_extract:SI (match_dup 0)
8541                                       (const_int 8)
8542                                       (const_int 8))))
8543               (clobber (reg:CC 17))])]
8544   "operands[0] = gen_lowpart (SImode, operands[0]);")
8545
8546 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8547 (define_insn "*andsi_1_zext"
8548   [(set (match_operand:DI 0 "register_operand" "=r")
8549         (zero_extend:DI
8550           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8551                   (match_operand:SI 2 "general_operand" "rim"))))
8552    (clobber (reg:CC 17))]
8553   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8554   "and{l}\t{%2, %k0|%k0, %2}"
8555   [(set_attr "type" "alu")
8556    (set_attr "mode" "SI")])
8557
8558 (define_insn "*andsi_2"
8559   [(set (reg 17)
8560         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8561                          (match_operand:SI 2 "general_operand" "rim,ri"))
8562                  (const_int 0)))
8563    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8564         (and:SI (match_dup 1) (match_dup 2)))]
8565   "ix86_match_ccmode (insn, CCNOmode)
8566    && ix86_binary_operator_ok (AND, SImode, operands)"
8567   "and{l}\t{%2, %0|%0, %2}"
8568   [(set_attr "type" "alu")
8569    (set_attr "mode" "SI")])
8570
8571 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8572 (define_insn "*andsi_2_zext"
8573   [(set (reg 17)
8574         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8575                          (match_operand:SI 2 "general_operand" "rim"))
8576                  (const_int 0)))
8577    (set (match_operand:DI 0 "register_operand" "=r")
8578         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8579   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8580    && ix86_binary_operator_ok (AND, SImode, operands)"
8581   "and{l}\t{%2, %k0|%k0, %2}"
8582   [(set_attr "type" "alu")
8583    (set_attr "mode" "SI")])
8584
8585 (define_expand "andhi3"
8586   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8587         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8588                 (match_operand:HI 2 "general_operand" "")))
8589    (clobber (reg:CC 17))]
8590   "TARGET_HIMODE_MATH"
8591   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8592
8593 (define_insn "*andhi_1"
8594   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8595         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8596                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8597    (clobber (reg:CC 17))]
8598   "ix86_binary_operator_ok (AND, HImode, operands)"
8599 {
8600   switch (get_attr_type (insn))
8601     {
8602     case TYPE_IMOVX:
8603       if (GET_CODE (operands[2]) != CONST_INT)
8604         abort ();
8605       if (INTVAL (operands[2]) == 0xff)
8606         return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8607       abort ();
8608
8609     default:
8610       if (! rtx_equal_p (operands[0], operands[1]))
8611         abort ();
8612
8613       return "and{w}\t{%2, %0|%0, %2}";
8614     }
8615 }
8616   [(set_attr "type" "alu,alu,imovx")
8617    (set_attr "length_immediate" "*,*,0")
8618    (set_attr "mode" "HI,HI,SI")])
8619
8620 (define_insn "*andhi_2"
8621   [(set (reg 17)
8622         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8623                          (match_operand:HI 2 "general_operand" "rim,ri"))
8624                  (const_int 0)))
8625    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8626         (and:HI (match_dup 1) (match_dup 2)))]
8627   "ix86_match_ccmode (insn, CCNOmode)
8628    && ix86_binary_operator_ok (AND, HImode, operands)"
8629   "and{w}\t{%2, %0|%0, %2}"
8630   [(set_attr "type" "alu")
8631    (set_attr "mode" "HI")])
8632
8633 (define_expand "andqi3"
8634   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8635         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8636                 (match_operand:QI 2 "general_operand" "")))
8637    (clobber (reg:CC 17))]
8638   "TARGET_QIMODE_MATH"
8639   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8640
8641 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8642 (define_insn "*andqi_1"
8643   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8644         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8645                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8646    (clobber (reg:CC 17))]
8647   "ix86_binary_operator_ok (AND, QImode, operands)"
8648   "@
8649    and{b}\t{%2, %0|%0, %2}
8650    and{b}\t{%2, %0|%0, %2}
8651    and{l}\t{%k2, %k0|%k0, %k2}"
8652   [(set_attr "type" "alu")
8653    (set_attr "mode" "QI,QI,SI")])
8654
8655 (define_insn "*andqi_1_slp"
8656   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8657         (and:QI (match_dup 0)
8658                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8659    (clobber (reg:CC 17))]
8660   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8661    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8662   "and{b}\t{%1, %0|%0, %1}"
8663   [(set_attr "type" "alu1")
8664    (set_attr "mode" "QI")])
8665
8666 (define_insn "*andqi_2"
8667   [(set (reg 17)
8668         (compare (and:QI
8669                    (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8670                    (match_operand:QI 2 "general_operand" "qim,qi,i"))
8671                  (const_int 0)))
8672    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8673         (and:QI (match_dup 1) (match_dup 2)))]
8674   "ix86_match_ccmode (insn, CCNOmode)
8675    && ix86_binary_operator_ok (AND, QImode, operands)"
8676 {
8677   if (which_alternative == 2)
8678     {
8679       if (GET_CODE (operands[2]) == CONST_INT
8680           && (INTVAL (operands[2]) & 0xffffff00))
8681         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8682       return "and{l}\t{%2, %k0|%k0, %2}";
8683     }
8684   return "and{b}\t{%2, %0|%0, %2}";
8685 }
8686   [(set_attr "type" "alu")
8687    (set_attr "mode" "QI,QI,SI")])
8688
8689 (define_insn "*andqi_2_slp"
8690   [(set (reg 17)
8691         (compare (and:QI
8692                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8693                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8694                  (const_int 0)))
8695    (set (strict_low_part (match_dup 0))
8696         (and:QI (match_dup 0) (match_dup 1)))]
8697   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8698    && ix86_match_ccmode (insn, CCNOmode)
8699    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8700   "and{b}\t{%1, %0|%0, %1}"
8701   [(set_attr "type" "alu1")
8702    (set_attr "mode" "QI")])
8703
8704 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8705 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8706 ;; for a QImode operand, which of course failed.
8707
8708 (define_insn "andqi_ext_0"
8709   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8710                          (const_int 8)
8711                          (const_int 8))
8712         (and:SI 
8713           (zero_extract:SI
8714             (match_operand 1 "ext_register_operand" "0")
8715             (const_int 8)
8716             (const_int 8))
8717           (match_operand 2 "const_int_operand" "n")))
8718    (clobber (reg:CC 17))]
8719   ""
8720   "and{b}\t{%2, %h0|%h0, %2}"
8721   [(set_attr "type" "alu")
8722    (set_attr "length_immediate" "1")
8723    (set_attr "mode" "QI")])
8724
8725 ;; Generated by peephole translating test to and.  This shows up
8726 ;; often in fp comparisons.
8727
8728 (define_insn "*andqi_ext_0_cc"
8729   [(set (reg 17)
8730         (compare
8731           (and:SI
8732             (zero_extract:SI
8733               (match_operand 1 "ext_register_operand" "0")
8734               (const_int 8)
8735               (const_int 8))
8736             (match_operand 2 "const_int_operand" "n"))
8737           (const_int 0)))
8738    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8739                          (const_int 8)
8740                          (const_int 8))
8741         (and:SI 
8742           (zero_extract:SI
8743             (match_dup 1)
8744             (const_int 8)
8745             (const_int 8))
8746           (match_dup 2)))]
8747   "ix86_match_ccmode (insn, CCNOmode)"
8748   "and{b}\t{%2, %h0|%h0, %2}"
8749   [(set_attr "type" "alu")
8750    (set_attr "length_immediate" "1")
8751    (set_attr "mode" "QI")])
8752
8753 (define_insn "*andqi_ext_1"
8754   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8755                          (const_int 8)
8756                          (const_int 8))
8757         (and:SI 
8758           (zero_extract:SI
8759             (match_operand 1 "ext_register_operand" "0")
8760             (const_int 8)
8761             (const_int 8))
8762           (zero_extend:SI
8763             (match_operand:QI 2 "general_operand" "Qm"))))
8764    (clobber (reg:CC 17))]
8765   "!TARGET_64BIT"
8766   "and{b}\t{%2, %h0|%h0, %2}"
8767   [(set_attr "type" "alu")
8768    (set_attr "length_immediate" "0")
8769    (set_attr "mode" "QI")])
8770
8771 (define_insn "*andqi_ext_1_rex64"
8772   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8773                          (const_int 8)
8774                          (const_int 8))
8775         (and:SI 
8776           (zero_extract:SI
8777             (match_operand 1 "ext_register_operand" "0")
8778             (const_int 8)
8779             (const_int 8))
8780           (zero_extend:SI
8781             (match_operand 2 "ext_register_operand" "Q"))))
8782    (clobber (reg:CC 17))]
8783   "TARGET_64BIT"
8784   "and{b}\t{%2, %h0|%h0, %2}"
8785   [(set_attr "type" "alu")
8786    (set_attr "length_immediate" "0")
8787    (set_attr "mode" "QI")])
8788
8789 (define_insn "*andqi_ext_2"
8790   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8791                          (const_int 8)
8792                          (const_int 8))
8793         (and:SI
8794           (zero_extract:SI
8795             (match_operand 1 "ext_register_operand" "%0")
8796             (const_int 8)
8797             (const_int 8))
8798           (zero_extract:SI
8799             (match_operand 2 "ext_register_operand" "Q")
8800             (const_int 8)
8801             (const_int 8))))
8802    (clobber (reg:CC 17))]
8803   ""
8804   "and{b}\t{%h2, %h0|%h0, %h2}"
8805   [(set_attr "type" "alu")
8806    (set_attr "length_immediate" "0")
8807    (set_attr "mode" "QI")])
8808
8809 ;; Convert wide AND instructions with immediate operand to shorter QImode
8810 ;; equivalents when possible.
8811 ;; Don't do the splitting with memory operands, since it introduces risk
8812 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8813 ;; for size, but that can (should?) be handled by generic code instead.
8814 (define_split
8815   [(set (match_operand 0 "register_operand" "")
8816         (and (match_operand 1 "register_operand" "")
8817              (match_operand 2 "const_int_operand" "")))
8818    (clobber (reg:CC 17))]
8819    "reload_completed
8820     && QI_REG_P (operands[0])
8821     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8822     && !(~INTVAL (operands[2]) & ~(255 << 8))
8823     && GET_MODE (operands[0]) != QImode"
8824   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8825                    (and:SI (zero_extract:SI (match_dup 1)
8826                                             (const_int 8) (const_int 8))
8827                            (match_dup 2)))
8828               (clobber (reg:CC 17))])]
8829   "operands[0] = gen_lowpart (SImode, operands[0]);
8830    operands[1] = gen_lowpart (SImode, operands[1]);
8831    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8832
8833 ;; Since AND can be encoded with sign extended immediate, this is only
8834 ;; profitable when 7th bit is not set.
8835 (define_split
8836   [(set (match_operand 0 "register_operand" "")
8837         (and (match_operand 1 "general_operand" "")
8838              (match_operand 2 "const_int_operand" "")))
8839    (clobber (reg:CC 17))]
8840    "reload_completed
8841     && ANY_QI_REG_P (operands[0])
8842     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8843     && !(~INTVAL (operands[2]) & ~255)
8844     && !(INTVAL (operands[2]) & 128)
8845     && GET_MODE (operands[0]) != QImode"
8846   [(parallel [(set (strict_low_part (match_dup 0))
8847                    (and:QI (match_dup 1)
8848                            (match_dup 2)))
8849               (clobber (reg:CC 17))])]
8850   "operands[0] = gen_lowpart (QImode, operands[0]);
8851    operands[1] = gen_lowpart (QImode, operands[1]);
8852    operands[2] = gen_lowpart (QImode, operands[2]);")
8853 \f
8854 ;; Logical inclusive OR instructions
8855
8856 ;; %%% This used to optimize known byte-wide and operations to memory.
8857 ;; If this is considered useful, it should be done with splitters.
8858
8859 (define_expand "iordi3"
8860   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8861         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8862                 (match_operand:DI 2 "x86_64_general_operand" "")))
8863    (clobber (reg:CC 17))]
8864   "TARGET_64BIT"
8865   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8866
8867 (define_insn "*iordi_1_rex64"
8868   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8869         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8870                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8871    (clobber (reg:CC 17))]
8872   "TARGET_64BIT
8873    && ix86_binary_operator_ok (IOR, DImode, operands)"
8874   "or{q}\t{%2, %0|%0, %2}"
8875   [(set_attr "type" "alu")
8876    (set_attr "mode" "DI")])
8877
8878 (define_insn "*iordi_2_rex64"
8879   [(set (reg 17)
8880         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8881                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8882                  (const_int 0)))
8883    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8884         (ior:DI (match_dup 1) (match_dup 2)))]
8885   "TARGET_64BIT
8886    && ix86_match_ccmode (insn, CCNOmode)
8887    && ix86_binary_operator_ok (IOR, DImode, operands)"
8888   "or{q}\t{%2, %0|%0, %2}"
8889   [(set_attr "type" "alu")
8890    (set_attr "mode" "DI")])
8891
8892 (define_insn "*iordi_3_rex64"
8893   [(set (reg 17)
8894         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8895                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8896                  (const_int 0)))
8897    (clobber (match_scratch:DI 0 "=r"))]
8898   "TARGET_64BIT
8899    && ix86_match_ccmode (insn, CCNOmode)
8900    && ix86_binary_operator_ok (IOR, DImode, operands)"
8901   "or{q}\t{%2, %0|%0, %2}"
8902   [(set_attr "type" "alu")
8903    (set_attr "mode" "DI")])
8904
8905
8906 (define_expand "iorsi3"
8907   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8908         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8909                 (match_operand:SI 2 "general_operand" "")))
8910    (clobber (reg:CC 17))]
8911   ""
8912   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8913
8914 (define_insn "*iorsi_1"
8915   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8916         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8917                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8918    (clobber (reg:CC 17))]
8919   "ix86_binary_operator_ok (IOR, SImode, operands)"
8920   "or{l}\t{%2, %0|%0, %2}"
8921   [(set_attr "type" "alu")
8922    (set_attr "mode" "SI")])
8923
8924 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8925 (define_insn "*iorsi_1_zext"
8926   [(set (match_operand:DI 0 "register_operand" "=rm")
8927         (zero_extend:DI
8928           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8929                   (match_operand:SI 2 "general_operand" "rim"))))
8930    (clobber (reg:CC 17))]
8931   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8932   "or{l}\t{%2, %k0|%k0, %2}"
8933   [(set_attr "type" "alu")
8934    (set_attr "mode" "SI")])
8935
8936 (define_insn "*iorsi_1_zext_imm"
8937   [(set (match_operand:DI 0 "register_operand" "=rm")
8938         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8939                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8940    (clobber (reg:CC 17))]
8941   "TARGET_64BIT"
8942   "or{l}\t{%2, %k0|%k0, %2}"
8943   [(set_attr "type" "alu")
8944    (set_attr "mode" "SI")])
8945
8946 (define_insn "*iorsi_2"
8947   [(set (reg 17)
8948         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8949                          (match_operand:SI 2 "general_operand" "rim,ri"))
8950                  (const_int 0)))
8951    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8952         (ior:SI (match_dup 1) (match_dup 2)))]
8953   "ix86_match_ccmode (insn, CCNOmode)
8954    && ix86_binary_operator_ok (IOR, SImode, operands)"
8955   "or{l}\t{%2, %0|%0, %2}"
8956   [(set_attr "type" "alu")
8957    (set_attr "mode" "SI")])
8958
8959 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8960 ;; ??? Special case for immediate operand is missing - it is tricky.
8961 (define_insn "*iorsi_2_zext"
8962   [(set (reg 17)
8963         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8964                          (match_operand:SI 2 "general_operand" "rim"))
8965                  (const_int 0)))
8966    (set (match_operand:DI 0 "register_operand" "=r")
8967         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8968   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8969    && ix86_binary_operator_ok (IOR, SImode, operands)"
8970   "or{l}\t{%2, %k0|%k0, %2}"
8971   [(set_attr "type" "alu")
8972    (set_attr "mode" "SI")])
8973
8974 (define_insn "*iorsi_2_zext_imm"
8975   [(set (reg 17)
8976         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8977                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8978                  (const_int 0)))
8979    (set (match_operand:DI 0 "register_operand" "=r")
8980         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8981   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8982    && ix86_binary_operator_ok (IOR, SImode, operands)"
8983   "or{l}\t{%2, %k0|%k0, %2}"
8984   [(set_attr "type" "alu")
8985    (set_attr "mode" "SI")])
8986
8987 (define_insn "*iorsi_3"
8988   [(set (reg 17)
8989         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8990                          (match_operand:SI 2 "general_operand" "rim"))
8991                  (const_int 0)))
8992    (clobber (match_scratch:SI 0 "=r"))]
8993   "ix86_match_ccmode (insn, CCNOmode)
8994    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8995   "or{l}\t{%2, %0|%0, %2}"
8996   [(set_attr "type" "alu")
8997    (set_attr "mode" "SI")])
8998
8999 (define_expand "iorhi3"
9000   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9001         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9002                 (match_operand:HI 2 "general_operand" "")))
9003    (clobber (reg:CC 17))]
9004   "TARGET_HIMODE_MATH"
9005   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9006
9007 (define_insn "*iorhi_1"
9008   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9009         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9010                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9011    (clobber (reg:CC 17))]
9012   "ix86_binary_operator_ok (IOR, HImode, operands)"
9013   "or{w}\t{%2, %0|%0, %2}"
9014   [(set_attr "type" "alu")
9015    (set_attr "mode" "HI")])
9016
9017 (define_insn "*iorhi_2"
9018   [(set (reg 17)
9019         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9020                          (match_operand:HI 2 "general_operand" "rim,ri"))
9021                  (const_int 0)))
9022    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9023         (ior:HI (match_dup 1) (match_dup 2)))]
9024   "ix86_match_ccmode (insn, CCNOmode)
9025    && ix86_binary_operator_ok (IOR, HImode, operands)"
9026   "or{w}\t{%2, %0|%0, %2}"
9027   [(set_attr "type" "alu")
9028    (set_attr "mode" "HI")])
9029
9030 (define_insn "*iorhi_3"
9031   [(set (reg 17)
9032         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9033                          (match_operand:HI 2 "general_operand" "rim"))
9034                  (const_int 0)))
9035    (clobber (match_scratch:HI 0 "=r"))]
9036   "ix86_match_ccmode (insn, CCNOmode)
9037    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9038   "or{w}\t{%2, %0|%0, %2}"
9039   [(set_attr "type" "alu")
9040    (set_attr "mode" "HI")])
9041
9042 (define_expand "iorqi3"
9043   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9044         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9045                 (match_operand:QI 2 "general_operand" "")))
9046    (clobber (reg:CC 17))]
9047   "TARGET_QIMODE_MATH"
9048   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9049
9050 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9051 (define_insn "*iorqi_1"
9052   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9053         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9054                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9055    (clobber (reg:CC 17))]
9056   "ix86_binary_operator_ok (IOR, QImode, operands)"
9057   "@
9058    or{b}\t{%2, %0|%0, %2}
9059    or{b}\t{%2, %0|%0, %2}
9060    or{l}\t{%k2, %k0|%k0, %k2}"
9061   [(set_attr "type" "alu")
9062    (set_attr "mode" "QI,QI,SI")])
9063
9064 (define_insn "*iorqi_1_slp"
9065   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9066         (ior:QI (match_dup 0)
9067                 (match_operand:QI 1 "general_operand" "qmi,qi")))
9068    (clobber (reg:CC 17))]
9069   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9070    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9071   "or{b}\t{%1, %0|%0, %1}"
9072   [(set_attr "type" "alu1")
9073    (set_attr "mode" "QI")])
9074
9075 (define_insn "*iorqi_2"
9076   [(set (reg 17)
9077         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9078                          (match_operand:QI 2 "general_operand" "qim,qi"))
9079                  (const_int 0)))
9080    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9081         (ior:QI (match_dup 1) (match_dup 2)))]
9082   "ix86_match_ccmode (insn, CCNOmode)
9083    && ix86_binary_operator_ok (IOR, QImode, operands)"
9084   "or{b}\t{%2, %0|%0, %2}"
9085   [(set_attr "type" "alu")
9086    (set_attr "mode" "QI")])
9087
9088 (define_insn "*iorqi_2_slp"
9089   [(set (reg 17)
9090         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9091                          (match_operand:QI 1 "general_operand" "qim,qi"))
9092                  (const_int 0)))
9093    (set (strict_low_part (match_dup 0))
9094         (ior:QI (match_dup 0) (match_dup 1)))]
9095   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9096    && ix86_match_ccmode (insn, CCNOmode)
9097    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9098   "or{b}\t{%1, %0|%0, %1}"
9099   [(set_attr "type" "alu1")
9100    (set_attr "mode" "QI")])
9101
9102 (define_insn "*iorqi_3"
9103   [(set (reg 17)
9104         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9105                          (match_operand:QI 2 "general_operand" "qim"))
9106                  (const_int 0)))
9107    (clobber (match_scratch:QI 0 "=q"))]
9108   "ix86_match_ccmode (insn, CCNOmode)
9109    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9110   "or{b}\t{%2, %0|%0, %2}"
9111   [(set_attr "type" "alu")
9112    (set_attr "mode" "QI")])
9113
9114 (define_insn "iorqi_ext_0"
9115   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9116                          (const_int 8)
9117                          (const_int 8))
9118         (ior:SI 
9119           (zero_extract:SI
9120             (match_operand 1 "ext_register_operand" "0")
9121             (const_int 8)
9122             (const_int 8))
9123           (match_operand 2 "const_int_operand" "n")))
9124    (clobber (reg:CC 17))]
9125   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9126   "or{b}\t{%2, %h0|%h0, %2}"
9127   [(set_attr "type" "alu")
9128    (set_attr "length_immediate" "1")
9129    (set_attr "mode" "QI")])
9130
9131 (define_insn "*iorqi_ext_1"
9132   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9133                          (const_int 8)
9134                          (const_int 8))
9135         (ior:SI 
9136           (zero_extract:SI
9137             (match_operand 1 "ext_register_operand" "0")
9138             (const_int 8)
9139             (const_int 8))
9140           (zero_extend:SI
9141             (match_operand:QI 2 "general_operand" "Qm"))))
9142    (clobber (reg:CC 17))]
9143   "!TARGET_64BIT
9144    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9145   "or{b}\t{%2, %h0|%h0, %2}"
9146   [(set_attr "type" "alu")
9147    (set_attr "length_immediate" "0")
9148    (set_attr "mode" "QI")])
9149
9150 (define_insn "*iorqi_ext_1_rex64"
9151   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9152                          (const_int 8)
9153                          (const_int 8))
9154         (ior:SI 
9155           (zero_extract:SI
9156             (match_operand 1 "ext_register_operand" "0")
9157             (const_int 8)
9158             (const_int 8))
9159           (zero_extend:SI
9160             (match_operand 2 "ext_register_operand" "Q"))))
9161    (clobber (reg:CC 17))]
9162   "TARGET_64BIT
9163    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9164   "or{b}\t{%2, %h0|%h0, %2}"
9165   [(set_attr "type" "alu")
9166    (set_attr "length_immediate" "0")
9167    (set_attr "mode" "QI")])
9168
9169 (define_insn "*iorqi_ext_2"
9170   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9171                          (const_int 8)
9172                          (const_int 8))
9173         (ior:SI 
9174           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9175                            (const_int 8)
9176                            (const_int 8))
9177           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9178                            (const_int 8)
9179                            (const_int 8))))
9180    (clobber (reg:CC 17))]
9181   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9182   "ior{b}\t{%h2, %h0|%h0, %h2}"
9183   [(set_attr "type" "alu")
9184    (set_attr "length_immediate" "0")
9185    (set_attr "mode" "QI")])
9186
9187 (define_split
9188   [(set (match_operand 0 "register_operand" "")
9189         (ior (match_operand 1 "register_operand" "")
9190              (match_operand 2 "const_int_operand" "")))
9191    (clobber (reg:CC 17))]
9192    "reload_completed
9193     && QI_REG_P (operands[0])
9194     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9195     && !(INTVAL (operands[2]) & ~(255 << 8))
9196     && GET_MODE (operands[0]) != QImode"
9197   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9198                    (ior:SI (zero_extract:SI (match_dup 1)
9199                                             (const_int 8) (const_int 8))
9200                            (match_dup 2)))
9201               (clobber (reg:CC 17))])]
9202   "operands[0] = gen_lowpart (SImode, operands[0]);
9203    operands[1] = gen_lowpart (SImode, operands[1]);
9204    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9205
9206 ;; Since OR can be encoded with sign extended immediate, this is only
9207 ;; profitable when 7th bit is set.
9208 (define_split
9209   [(set (match_operand 0 "register_operand" "")
9210         (ior (match_operand 1 "general_operand" "")
9211              (match_operand 2 "const_int_operand" "")))
9212    (clobber (reg:CC 17))]
9213    "reload_completed
9214     && ANY_QI_REG_P (operands[0])
9215     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9216     && !(INTVAL (operands[2]) & ~255)
9217     && (INTVAL (operands[2]) & 128)
9218     && GET_MODE (operands[0]) != QImode"
9219   [(parallel [(set (strict_low_part (match_dup 0))
9220                    (ior:QI (match_dup 1)
9221                            (match_dup 2)))
9222               (clobber (reg:CC 17))])]
9223   "operands[0] = gen_lowpart (QImode, operands[0]);
9224    operands[1] = gen_lowpart (QImode, operands[1]);
9225    operands[2] = gen_lowpart (QImode, operands[2]);")
9226 \f
9227 ;; Logical XOR instructions
9228
9229 ;; %%% This used to optimize known byte-wide and operations to memory.
9230 ;; If this is considered useful, it should be done with splitters.
9231
9232 (define_expand "xordi3"
9233   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9234         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9235                 (match_operand:DI 2 "x86_64_general_operand" "")))
9236    (clobber (reg:CC 17))]
9237   "TARGET_64BIT"
9238   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9239
9240 (define_insn "*xordi_1_rex64"
9241   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9242         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9243                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9244    (clobber (reg:CC 17))]
9245   "TARGET_64BIT
9246    && ix86_binary_operator_ok (XOR, DImode, operands)"
9247   "@
9248    xor{q}\t{%2, %0|%0, %2} 
9249    xor{q}\t{%2, %0|%0, %2}"
9250   [(set_attr "type" "alu")
9251    (set_attr "mode" "DI,DI")])
9252
9253 (define_insn "*xordi_2_rex64"
9254   [(set (reg 17)
9255         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9256                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9257                  (const_int 0)))
9258    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9259         (xor:DI (match_dup 1) (match_dup 2)))]
9260   "TARGET_64BIT
9261    && ix86_match_ccmode (insn, CCNOmode)
9262    && ix86_binary_operator_ok (XOR, DImode, operands)"
9263   "@
9264    xor{q}\t{%2, %0|%0, %2} 
9265    xor{q}\t{%2, %0|%0, %2}"
9266   [(set_attr "type" "alu")
9267    (set_attr "mode" "DI,DI")])
9268
9269 (define_insn "*xordi_3_rex64"
9270   [(set (reg 17)
9271         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9272                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9273                  (const_int 0)))
9274    (clobber (match_scratch:DI 0 "=r"))]
9275   "TARGET_64BIT
9276    && ix86_match_ccmode (insn, CCNOmode)
9277    && ix86_binary_operator_ok (XOR, DImode, operands)"
9278   "xor{q}\t{%2, %0|%0, %2}"
9279   [(set_attr "type" "alu")
9280    (set_attr "mode" "DI")])
9281
9282 (define_expand "xorsi3"
9283   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9284         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9285                 (match_operand:SI 2 "general_operand" "")))
9286    (clobber (reg:CC 17))]
9287   ""
9288   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9289
9290 (define_insn "*xorsi_1"
9291   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9292         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9293                 (match_operand:SI 2 "general_operand" "ri,rm")))
9294    (clobber (reg:CC 17))]
9295   "ix86_binary_operator_ok (XOR, SImode, operands)"
9296   "xor{l}\t{%2, %0|%0, %2}"
9297   [(set_attr "type" "alu")
9298    (set_attr "mode" "SI")])
9299
9300 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9301 ;; Add speccase for immediates
9302 (define_insn "*xorsi_1_zext"
9303   [(set (match_operand:DI 0 "register_operand" "=r")
9304         (zero_extend:DI
9305           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9306                   (match_operand:SI 2 "general_operand" "rim"))))
9307    (clobber (reg:CC 17))]
9308   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9309   "xor{l}\t{%2, %k0|%k0, %2}"
9310   [(set_attr "type" "alu")
9311    (set_attr "mode" "SI")])
9312
9313 (define_insn "*xorsi_1_zext_imm"
9314   [(set (match_operand:DI 0 "register_operand" "=r")
9315         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9316                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9317    (clobber (reg:CC 17))]
9318   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9319   "xor{l}\t{%2, %k0|%k0, %2}"
9320   [(set_attr "type" "alu")
9321    (set_attr "mode" "SI")])
9322
9323 (define_insn "*xorsi_2"
9324   [(set (reg 17)
9325         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9326                          (match_operand:SI 2 "general_operand" "rim,ri"))
9327                  (const_int 0)))
9328    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9329         (xor:SI (match_dup 1) (match_dup 2)))]
9330   "ix86_match_ccmode (insn, CCNOmode)
9331    && ix86_binary_operator_ok (XOR, SImode, operands)"
9332   "xor{l}\t{%2, %0|%0, %2}"
9333   [(set_attr "type" "alu")
9334    (set_attr "mode" "SI")])
9335
9336 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9337 ;; ??? Special case for immediate operand is missing - it is tricky.
9338 (define_insn "*xorsi_2_zext"
9339   [(set (reg 17)
9340         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9341                          (match_operand:SI 2 "general_operand" "rim"))
9342                  (const_int 0)))
9343    (set (match_operand:DI 0 "register_operand" "=r")
9344         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9345   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9346    && ix86_binary_operator_ok (XOR, SImode, operands)"
9347   "xor{l}\t{%2, %k0|%k0, %2}"
9348   [(set_attr "type" "alu")
9349    (set_attr "mode" "SI")])
9350
9351 (define_insn "*xorsi_2_zext_imm"
9352   [(set (reg 17)
9353         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9354                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9355                  (const_int 0)))
9356    (set (match_operand:DI 0 "register_operand" "=r")
9357         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9358   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9359    && ix86_binary_operator_ok (XOR, SImode, operands)"
9360   "xor{l}\t{%2, %k0|%k0, %2}"
9361   [(set_attr "type" "alu")
9362    (set_attr "mode" "SI")])
9363
9364 (define_insn "*xorsi_3"
9365   [(set (reg 17)
9366         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9367                          (match_operand:SI 2 "general_operand" "rim"))
9368                  (const_int 0)))
9369    (clobber (match_scratch:SI 0 "=r"))]
9370   "ix86_match_ccmode (insn, CCNOmode)
9371    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9372   "xor{l}\t{%2, %0|%0, %2}"
9373   [(set_attr "type" "alu")
9374    (set_attr "mode" "SI")])
9375
9376 (define_expand "xorhi3"
9377   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9378         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9379                 (match_operand:HI 2 "general_operand" "")))
9380    (clobber (reg:CC 17))]
9381   "TARGET_HIMODE_MATH"
9382   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9383
9384 (define_insn "*xorhi_1"
9385   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9386         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9387                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9388    (clobber (reg:CC 17))]
9389   "ix86_binary_operator_ok (XOR, HImode, operands)"
9390   "xor{w}\t{%2, %0|%0, %2}"
9391   [(set_attr "type" "alu")
9392    (set_attr "mode" "HI")])
9393
9394 (define_insn "*xorhi_2"
9395   [(set (reg 17)
9396         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9397                          (match_operand:HI 2 "general_operand" "rim,ri"))
9398                  (const_int 0)))
9399    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9400         (xor:HI (match_dup 1) (match_dup 2)))]
9401   "ix86_match_ccmode (insn, CCNOmode)
9402    && ix86_binary_operator_ok (XOR, HImode, operands)"
9403   "xor{w}\t{%2, %0|%0, %2}"
9404   [(set_attr "type" "alu")
9405    (set_attr "mode" "HI")])
9406
9407 (define_insn "*xorhi_3"
9408   [(set (reg 17)
9409         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9410                          (match_operand:HI 2 "general_operand" "rim"))
9411                  (const_int 0)))
9412    (clobber (match_scratch:HI 0 "=r"))]
9413   "ix86_match_ccmode (insn, CCNOmode)
9414    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9415   "xor{w}\t{%2, %0|%0, %2}"
9416   [(set_attr "type" "alu")
9417    (set_attr "mode" "HI")])
9418
9419 (define_expand "xorqi3"
9420   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9421         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9422                 (match_operand:QI 2 "general_operand" "")))
9423    (clobber (reg:CC 17))]
9424   "TARGET_QIMODE_MATH"
9425   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9426
9427 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9428 (define_insn "*xorqi_1"
9429   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9430         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9431                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9432    (clobber (reg:CC 17))]
9433   "ix86_binary_operator_ok (XOR, QImode, operands)"
9434   "@
9435    xor{b}\t{%2, %0|%0, %2}
9436    xor{b}\t{%2, %0|%0, %2}
9437    xor{l}\t{%k2, %k0|%k0, %k2}"
9438   [(set_attr "type" "alu")
9439    (set_attr "mode" "QI,QI,SI")])
9440
9441 (define_insn "*xorqi_1_slp"
9442   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9443         (xor:QI (match_dup 0)
9444                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9445    (clobber (reg:CC 17))]
9446   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9447    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9448   "xor{b}\t{%1, %0|%0, %1}"
9449   [(set_attr "type" "alu1")
9450    (set_attr "mode" "QI")])
9451
9452 (define_insn "xorqi_ext_0"
9453   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9454                          (const_int 8)
9455                          (const_int 8))
9456         (xor:SI 
9457           (zero_extract:SI
9458             (match_operand 1 "ext_register_operand" "0")
9459             (const_int 8)
9460             (const_int 8))
9461           (match_operand 2 "const_int_operand" "n")))
9462    (clobber (reg:CC 17))]
9463   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9464   "xor{b}\t{%2, %h0|%h0, %2}"
9465   [(set_attr "type" "alu")
9466    (set_attr "length_immediate" "1")
9467    (set_attr "mode" "QI")])
9468
9469 (define_insn "*xorqi_ext_1"
9470   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9471                          (const_int 8)
9472                          (const_int 8))
9473         (xor:SI 
9474           (zero_extract:SI
9475             (match_operand 1 "ext_register_operand" "0")
9476             (const_int 8)
9477             (const_int 8))
9478           (zero_extend:SI
9479             (match_operand:QI 2 "general_operand" "Qm"))))
9480    (clobber (reg:CC 17))]
9481   "!TARGET_64BIT
9482    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9483   "xor{b}\t{%2, %h0|%h0, %2}"
9484   [(set_attr "type" "alu")
9485    (set_attr "length_immediate" "0")
9486    (set_attr "mode" "QI")])
9487
9488 (define_insn "*xorqi_ext_1_rex64"
9489   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9490                          (const_int 8)
9491                          (const_int 8))
9492         (xor:SI 
9493           (zero_extract:SI
9494             (match_operand 1 "ext_register_operand" "0")
9495             (const_int 8)
9496             (const_int 8))
9497           (zero_extend:SI
9498             (match_operand 2 "ext_register_operand" "Q"))))
9499    (clobber (reg:CC 17))]
9500   "TARGET_64BIT
9501    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9502   "xor{b}\t{%2, %h0|%h0, %2}"
9503   [(set_attr "type" "alu")
9504    (set_attr "length_immediate" "0")
9505    (set_attr "mode" "QI")])
9506
9507 (define_insn "*xorqi_ext_2"
9508   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9509                          (const_int 8)
9510                          (const_int 8))
9511         (xor:SI 
9512           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9513                            (const_int 8)
9514                            (const_int 8))
9515           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9516                            (const_int 8)
9517                            (const_int 8))))
9518    (clobber (reg:CC 17))]
9519   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9520   "xor{b}\t{%h2, %h0|%h0, %h2}"
9521   [(set_attr "type" "alu")
9522    (set_attr "length_immediate" "0")
9523    (set_attr "mode" "QI")])
9524
9525 (define_insn "*xorqi_cc_1"
9526   [(set (reg 17)
9527         (compare
9528           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9529                   (match_operand:QI 2 "general_operand" "qim,qi"))
9530           (const_int 0)))
9531    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9532         (xor:QI (match_dup 1) (match_dup 2)))]
9533   "ix86_match_ccmode (insn, CCNOmode)
9534    && ix86_binary_operator_ok (XOR, QImode, operands)"
9535   "xor{b}\t{%2, %0|%0, %2}"
9536   [(set_attr "type" "alu")
9537    (set_attr "mode" "QI")])
9538
9539 (define_insn "*xorqi_2_slp"
9540   [(set (reg 17)
9541         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9542                          (match_operand:QI 1 "general_operand" "qim,qi"))
9543                  (const_int 0)))
9544    (set (strict_low_part (match_dup 0))
9545         (xor:QI (match_dup 0) (match_dup 1)))]
9546   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9547    && ix86_match_ccmode (insn, CCNOmode)
9548    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9549   "xor{b}\t{%1, %0|%0, %1}"
9550   [(set_attr "type" "alu1")
9551    (set_attr "mode" "QI")])
9552
9553 (define_insn "*xorqi_cc_2"
9554   [(set (reg 17)
9555         (compare
9556           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9557                   (match_operand:QI 2 "general_operand" "qim"))
9558           (const_int 0)))
9559    (clobber (match_scratch:QI 0 "=q"))]
9560   "ix86_match_ccmode (insn, CCNOmode)
9561    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9562   "xor{b}\t{%2, %0|%0, %2}"
9563   [(set_attr "type" "alu")
9564    (set_attr "mode" "QI")])
9565
9566 (define_insn "*xorqi_cc_ext_1"
9567   [(set (reg 17)
9568         (compare
9569           (xor:SI
9570             (zero_extract:SI
9571               (match_operand 1 "ext_register_operand" "0")
9572               (const_int 8)
9573               (const_int 8))
9574             (match_operand:QI 2 "general_operand" "qmn"))
9575           (const_int 0)))
9576    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9577                          (const_int 8)
9578                          (const_int 8))
9579         (xor:SI 
9580           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9581           (match_dup 2)))]
9582   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9583   "xor{b}\t{%2, %h0|%h0, %2}"
9584   [(set_attr "type" "alu")
9585    (set_attr "mode" "QI")])
9586
9587 (define_insn "*xorqi_cc_ext_1_rex64"
9588   [(set (reg 17)
9589         (compare
9590           (xor:SI
9591             (zero_extract:SI
9592               (match_operand 1 "ext_register_operand" "0")
9593               (const_int 8)
9594               (const_int 8))
9595             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9596           (const_int 0)))
9597    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9598                          (const_int 8)
9599                          (const_int 8))
9600         (xor:SI 
9601           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9602           (match_dup 2)))]
9603   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9604   "xor{b}\t{%2, %h0|%h0, %2}"
9605   [(set_attr "type" "alu")
9606    (set_attr "mode" "QI")])
9607
9608 (define_expand "xorqi_cc_ext_1"
9609   [(parallel [
9610      (set (reg:CCNO 17)
9611           (compare:CCNO
9612             (xor:SI
9613               (zero_extract:SI
9614                 (match_operand 1 "ext_register_operand" "")
9615                 (const_int 8)
9616                 (const_int 8))
9617               (match_operand:QI 2 "general_operand" ""))
9618             (const_int 0)))
9619      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9620                            (const_int 8)
9621                            (const_int 8))
9622           (xor:SI 
9623             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9624             (match_dup 2)))])]
9625   ""
9626   "")
9627
9628 (define_split
9629   [(set (match_operand 0 "register_operand" "")
9630         (xor (match_operand 1 "register_operand" "")
9631              (match_operand 2 "const_int_operand" "")))
9632    (clobber (reg:CC 17))]
9633    "reload_completed
9634     && QI_REG_P (operands[0])
9635     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9636     && !(INTVAL (operands[2]) & ~(255 << 8))
9637     && GET_MODE (operands[0]) != QImode"
9638   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9639                    (xor:SI (zero_extract:SI (match_dup 1)
9640                                             (const_int 8) (const_int 8))
9641                            (match_dup 2)))
9642               (clobber (reg:CC 17))])]
9643   "operands[0] = gen_lowpart (SImode, operands[0]);
9644    operands[1] = gen_lowpart (SImode, operands[1]);
9645    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9646
9647 ;; Since XOR can be encoded with sign extended immediate, this is only
9648 ;; profitable when 7th bit is set.
9649 (define_split
9650   [(set (match_operand 0 "register_operand" "")
9651         (xor (match_operand 1 "general_operand" "")
9652              (match_operand 2 "const_int_operand" "")))
9653    (clobber (reg:CC 17))]
9654    "reload_completed
9655     && ANY_QI_REG_P (operands[0])
9656     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9657     && !(INTVAL (operands[2]) & ~255)
9658     && (INTVAL (operands[2]) & 128)
9659     && GET_MODE (operands[0]) != QImode"
9660   [(parallel [(set (strict_low_part (match_dup 0))
9661                    (xor:QI (match_dup 1)
9662                            (match_dup 2)))
9663               (clobber (reg:CC 17))])]
9664   "operands[0] = gen_lowpart (QImode, operands[0]);
9665    operands[1] = gen_lowpart (QImode, operands[1]);
9666    operands[2] = gen_lowpart (QImode, operands[2]);")
9667 \f
9668 ;; Negation instructions
9669
9670 (define_expand "negdi2"
9671   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9672                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9673               (clobber (reg:CC 17))])]
9674   ""
9675   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9676
9677 (define_insn "*negdi2_1"
9678   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9679         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9680    (clobber (reg:CC 17))]
9681   "!TARGET_64BIT
9682    && ix86_unary_operator_ok (NEG, DImode, operands)"
9683   "#")
9684
9685 (define_split
9686   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9687         (neg:DI (match_operand:DI 1 "general_operand" "")))
9688    (clobber (reg:CC 17))]
9689   "!TARGET_64BIT && reload_completed"
9690   [(parallel
9691     [(set (reg:CCZ 17)
9692           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9693      (set (match_dup 0) (neg:SI (match_dup 2)))])
9694    (parallel
9695     [(set (match_dup 1)
9696           (plus:SI (plus:SI (ltu:SI (reg:CC 17) (const_int 0))
9697                             (match_dup 3))
9698                    (const_int 0)))
9699      (clobber (reg:CC 17))])
9700    (parallel
9701     [(set (match_dup 1)
9702           (neg:SI (match_dup 1)))
9703      (clobber (reg:CC 17))])]
9704   "split_di (operands+1, 1, operands+2, operands+3);
9705    split_di (operands+0, 1, operands+0, operands+1);")
9706
9707 (define_insn "*negdi2_1_rex64"
9708   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9709         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9710    (clobber (reg:CC 17))]
9711   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9712   "neg{q}\t%0"
9713   [(set_attr "type" "negnot")
9714    (set_attr "mode" "DI")])
9715
9716 ;; The problem with neg is that it does not perform (compare x 0),
9717 ;; it really performs (compare 0 x), which leaves us with the zero
9718 ;; flag being the only useful item.
9719
9720 (define_insn "*negdi2_cmpz_rex64"
9721   [(set (reg:CCZ 17)
9722         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9723                      (const_int 0)))
9724    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9725         (neg:DI (match_dup 1)))]
9726   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9727   "neg{q}\t%0"
9728   [(set_attr "type" "negnot")
9729    (set_attr "mode" "DI")])
9730
9731
9732 (define_expand "negsi2"
9733   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9734                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9735               (clobber (reg:CC 17))])]
9736   ""
9737   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9738
9739 (define_insn "*negsi2_1"
9740   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9741         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9742    (clobber (reg:CC 17))]
9743   "ix86_unary_operator_ok (NEG, SImode, operands)"
9744   "neg{l}\t%0"
9745   [(set_attr "type" "negnot")
9746    (set_attr "mode" "SI")])
9747
9748 ;; Combine is quite creative about this pattern.
9749 (define_insn "*negsi2_1_zext"
9750   [(set (match_operand:DI 0 "register_operand" "=r")
9751         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9752                                         (const_int 32)))
9753                      (const_int 32)))
9754    (clobber (reg:CC 17))]
9755   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9756   "neg{l}\t%k0"
9757   [(set_attr "type" "negnot")
9758    (set_attr "mode" "SI")])
9759
9760 ;; The problem with neg is that it does not perform (compare x 0),
9761 ;; it really performs (compare 0 x), which leaves us with the zero
9762 ;; flag being the only useful item.
9763
9764 (define_insn "*negsi2_cmpz"
9765   [(set (reg:CCZ 17)
9766         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9767                      (const_int 0)))
9768    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9769         (neg:SI (match_dup 1)))]
9770   "ix86_unary_operator_ok (NEG, SImode, operands)"
9771   "neg{l}\t%0"
9772   [(set_attr "type" "negnot")
9773    (set_attr "mode" "SI")])
9774
9775 (define_insn "*negsi2_cmpz_zext"
9776   [(set (reg:CCZ 17)
9777         (compare:CCZ (lshiftrt:DI
9778                        (neg:DI (ashift:DI
9779                                  (match_operand:DI 1 "register_operand" "0")
9780                                  (const_int 32)))
9781                        (const_int 32))
9782                      (const_int 0)))
9783    (set (match_operand:DI 0 "register_operand" "=r")
9784         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9785                                         (const_int 32)))
9786                      (const_int 32)))]
9787   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9788   "neg{l}\t%k0"
9789   [(set_attr "type" "negnot")
9790    (set_attr "mode" "SI")])
9791
9792 (define_expand "neghi2"
9793   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9794                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9795               (clobber (reg:CC 17))])]
9796   "TARGET_HIMODE_MATH"
9797   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9798
9799 (define_insn "*neghi2_1"
9800   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9801         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9802    (clobber (reg:CC 17))]
9803   "ix86_unary_operator_ok (NEG, HImode, operands)"
9804   "neg{w}\t%0"
9805   [(set_attr "type" "negnot")
9806    (set_attr "mode" "HI")])
9807
9808 (define_insn "*neghi2_cmpz"
9809   [(set (reg:CCZ 17)
9810         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9811                      (const_int 0)))
9812    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9813         (neg:HI (match_dup 1)))]
9814   "ix86_unary_operator_ok (NEG, HImode, operands)"
9815   "neg{w}\t%0"
9816   [(set_attr "type" "negnot")
9817    (set_attr "mode" "HI")])
9818
9819 (define_expand "negqi2"
9820   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9821                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9822               (clobber (reg:CC 17))])]
9823   "TARGET_QIMODE_MATH"
9824   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9825
9826 (define_insn "*negqi2_1"
9827   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9828         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9829    (clobber (reg:CC 17))]
9830   "ix86_unary_operator_ok (NEG, QImode, operands)"
9831   "neg{b}\t%0"
9832   [(set_attr "type" "negnot")
9833    (set_attr "mode" "QI")])
9834
9835 (define_insn "*negqi2_cmpz"
9836   [(set (reg:CCZ 17)
9837         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9838                      (const_int 0)))
9839    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9840         (neg:QI (match_dup 1)))]
9841   "ix86_unary_operator_ok (NEG, QImode, operands)"
9842   "neg{b}\t%0"
9843   [(set_attr "type" "negnot")
9844    (set_attr "mode" "QI")])
9845
9846 ;; Changing of sign for FP values is doable using integer unit too.
9847
9848 (define_expand "negsf2"
9849   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
9850                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
9851               (clobber (reg:CC 17))])]
9852   "TARGET_80387"
9853   "if (TARGET_SSE)
9854      {
9855        /* In case operand is in memory,  we will not use SSE.  */
9856        if (memory_operand (operands[0], VOIDmode)
9857            && rtx_equal_p (operands[0], operands[1]))
9858          emit_insn (gen_negsf2_memory (operands[0], operands[1]));
9859        else
9860         {
9861           /* Using SSE is tricky, since we need bitwise negation of -0
9862              in register.  */
9863           rtx reg = gen_reg_rtx (SFmode);
9864           rtx dest = operands[0];
9865           rtx imm = gen_lowpart (SFmode, gen_int_mode (0x80000000, SImode));
9866
9867           operands[1] = force_reg (SFmode, operands[1]);
9868           operands[0] = force_reg (SFmode, operands[0]);
9869           reg = force_reg (V4SFmode,
9870                            gen_rtx_CONST_VECTOR (V4SFmode,
9871                              gen_rtvec (4, imm, CONST0_RTX (SFmode),
9872                                         CONST0_RTX (SFmode),
9873                                         CONST0_RTX (SFmode))));
9874           emit_insn (gen_negsf2_ifs (operands[0], operands[1], reg));
9875           if (dest != operands[0])
9876             emit_move_insn (dest, operands[0]);
9877         }
9878        DONE;
9879      }
9880    ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
9881
9882 (define_insn "negsf2_memory"
9883   [(set (match_operand:SF 0 "memory_operand" "=m")
9884         (neg:SF (match_operand:SF 1 "memory_operand" "0")))
9885    (clobber (reg:CC 17))]
9886   "ix86_unary_operator_ok (NEG, SFmode, operands)"
9887   "#")
9888
9889 (define_insn "negsf2_ifs"
9890   [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
9891         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
9892    (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
9893    (clobber (reg:CC 17))]
9894   "TARGET_SSE
9895    && (reload_in_progress || reload_completed
9896        || (register_operand (operands[0], VOIDmode)
9897            && register_operand (operands[1], VOIDmode)))"
9898   "#")
9899
9900 (define_split
9901   [(set (match_operand:SF 0 "memory_operand" "")
9902         (neg:SF (match_operand:SF 1 "memory_operand" "")))
9903    (use (match_operand:SF 2 "" ""))
9904    (clobber (reg:CC 17))]
9905   ""
9906   [(parallel [(set (match_dup 0)
9907                    (neg:SF (match_dup 1)))
9908               (clobber (reg:CC 17))])])
9909
9910 (define_split
9911   [(set (match_operand:SF 0 "register_operand" "")
9912         (neg:SF (match_operand:SF 1 "register_operand" "")))
9913    (use (match_operand:V4SF 2 "" ""))
9914    (clobber (reg:CC 17))]
9915   "reload_completed && !SSE_REG_P (operands[0])"
9916   [(parallel [(set (match_dup 0)
9917                    (neg:SF (match_dup 1)))
9918               (clobber (reg:CC 17))])])
9919
9920 (define_split
9921   [(set (match_operand:SF 0 "register_operand" "")
9922         (neg:SF (match_operand:SF 1 "register_operand" "")))
9923    (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
9924    (clobber (reg:CC 17))]
9925   "reload_completed && SSE_REG_P (operands[0])"
9926   [(set (subreg:TI (match_dup 0) 0)
9927         (xor:TI (match_dup 1)
9928                 (match_dup 2)))]
9929 {
9930   operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
9931   operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
9932   if (operands_match_p (operands[0], operands[2]))
9933     {
9934       rtx tmp;
9935       tmp = operands[1];
9936       operands[1] = operands[2];
9937       operands[2] = tmp;
9938     }
9939 })
9940
9941
9942 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
9943 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
9944 ;; to itself.
9945 (define_insn "*negsf2_if"
9946   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
9947         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
9948    (clobber (reg:CC 17))]
9949   "TARGET_80387 && !TARGET_SSE
9950    && ix86_unary_operator_ok (NEG, SFmode, operands)"
9951   "#")
9952
9953 (define_split
9954   [(set (match_operand:SF 0 "fp_register_operand" "")
9955         (neg:SF (match_operand:SF 1 "register_operand" "")))
9956    (clobber (reg:CC 17))]
9957   "TARGET_80387 && reload_completed"
9958   [(set (match_dup 0)
9959         (neg:SF (match_dup 1)))]
9960   "")
9961
9962 (define_split
9963   [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
9964         (neg:SF (match_operand:SF 1 "register_operand" "")))
9965    (clobber (reg:CC 17))]
9966   "TARGET_80387 && reload_completed"
9967   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
9968               (clobber (reg:CC 17))])]
9969   "operands[1] = gen_int_mode (0x80000000, SImode);
9970    operands[0] = gen_lowpart (SImode, operands[0]);")
9971
9972 (define_split
9973   [(set (match_operand 0 "memory_operand" "")
9974         (neg (match_operand 1 "memory_operand" "")))
9975    (clobber (reg:CC 17))]
9976   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
9977   [(parallel [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1)))
9978               (clobber (reg:CC 17))])]
9979 {
9980   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
9981
9982   /* XFmode's size is 12, TFmode 16, but only 10 bytes are used.  */
9983   if (size >= 12)
9984     size = 10;
9985   operands[0] = adjust_address (operands[0], QImode, size - 1);
9986   operands[1] = gen_int_mode (0x80, QImode);
9987 })
9988
9989 (define_expand "negdf2"
9990   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
9991                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
9992               (clobber (reg:CC 17))])]
9993   "TARGET_80387"
9994   "if (TARGET_SSE2)
9995      {
9996        /* In case operand is in memory,  we will not use SSE.  */
9997        if (memory_operand (operands[0], VOIDmode)
9998            && rtx_equal_p (operands[0], operands[1]))
9999          emit_insn (gen_negdf2_memory (operands[0], operands[1]));
10000        else
10001         {
10002           /* Using SSE is tricky, since we need bitwise negation of -0
10003              in register.  */
10004           rtx reg;
10005 #if HOST_BITS_PER_WIDE_INT >= 64
10006           rtx imm = gen_int_mode (((HOST_WIDE_INT)1) << 63, DImode);
10007 #else
10008           rtx imm = immed_double_const (0, 0x80000000, DImode);
10009 #endif
10010           rtx dest = operands[0];
10011
10012           operands[1] = force_reg (DFmode, operands[1]);
10013           operands[0] = force_reg (DFmode, operands[0]);
10014           imm = gen_lowpart (DFmode, imm);
10015           reg = force_reg (V2DFmode,
10016                            gen_rtx_CONST_VECTOR (V2DFmode,
10017                              gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10018           emit_insn (gen_negdf2_ifs (operands[0], operands[1], reg));
10019           if (dest != operands[0])
10020             emit_move_insn (dest, operands[0]);
10021         }
10022        DONE;
10023      }
10024    ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
10025
10026 (define_insn "negdf2_memory"
10027   [(set (match_operand:DF 0 "memory_operand" "=m")
10028         (neg:DF (match_operand:DF 1 "memory_operand" "0")))
10029    (clobber (reg:CC 17))]
10030   "ix86_unary_operator_ok (NEG, DFmode, operands)"
10031   "#")
10032
10033 (define_insn "negdf2_ifs"
10034   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,f#Yr,rm#Yf")
10035         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10036    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10037    (clobber (reg:CC 17))]
10038   "!TARGET_64BIT && TARGET_SSE2
10039    && (reload_in_progress || reload_completed
10040        || (register_operand (operands[0], VOIDmode)
10041            && register_operand (operands[1], VOIDmode)))"
10042   "#")
10043
10044 (define_insn "*negdf2_ifs_rex64"
10045   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,fm#Y")
10046         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10047    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10048    (clobber (reg:CC 17))]
10049   "TARGET_64BIT && TARGET_SSE2
10050    && (reload_in_progress || reload_completed
10051        || (register_operand (operands[0], VOIDmode)
10052            && register_operand (operands[1], VOIDmode)))"
10053   "#")
10054
10055 (define_split
10056   [(set (match_operand:DF 0 "memory_operand" "")
10057         (neg:DF (match_operand:DF 1 "memory_operand" "")))
10058    (use (match_operand:V2DF 2 "" ""))
10059    (clobber (reg:CC 17))]
10060   ""
10061   [(parallel [(set (match_dup 0)
10062                    (neg:DF (match_dup 1)))
10063               (clobber (reg:CC 17))])])
10064
10065 (define_split
10066   [(set (match_operand:DF 0 "register_operand" "")
10067         (neg:DF (match_operand:DF 1 "register_operand" "")))
10068    (use (match_operand:V2DF 2 "" ""))
10069    (clobber (reg:CC 17))]
10070   "reload_completed && !SSE_REG_P (operands[0])
10071    && (!TARGET_64BIT || FP_REG_P (operands[0]))"
10072   [(parallel [(set (match_dup 0)
10073                    (neg:DF (match_dup 1)))
10074               (clobber (reg:CC 17))])])
10075
10076 (define_split
10077   [(set (match_operand:DF 0 "register_operand" "")
10078         (neg:DF (match_operand:DF 1 "register_operand" "")))
10079    (use (match_operand:V2DF 2 "" ""))
10080    (clobber (reg:CC 17))]
10081   "TARGET_64BIT && reload_completed && GENERAL_REG_P (operands[0])"
10082   [(parallel [(set (match_dup 0)
10083                    (xor:DI (match_dup 1) (match_dup 2)))
10084               (clobber (reg:CC 17))])]
10085    "operands[0] = gen_lowpart (DImode, operands[0]);
10086     operands[1] = gen_lowpart (DImode, operands[1]);
10087     operands[2] = gen_lowpart (DImode, operands[2]);")
10088
10089 (define_split
10090   [(set (match_operand:DF 0 "register_operand" "")
10091         (neg:DF (match_operand:DF 1 "register_operand" "")))
10092    (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10093    (clobber (reg:CC 17))]
10094   "reload_completed && SSE_REG_P (operands[0])"
10095   [(set (subreg:TI (match_dup 0) 0)
10096         (xor:TI (match_dup 1)
10097                 (match_dup 2)))]
10098 {
10099   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10100   operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
10101   operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
10102   /* Avoid possible reformatting on the operands.  */
10103   if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10104     emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10105   if (operands_match_p (operands[0], operands[2]))
10106     {
10107       rtx tmp;
10108       tmp = operands[1];
10109       operands[1] = operands[2];
10110       operands[2] = tmp;
10111     }
10112 })
10113
10114 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10115 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10116 ;; to itself.
10117 (define_insn "*negdf2_if"
10118   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10119         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10120    (clobber (reg:CC 17))]
10121   "!TARGET_64BIT && TARGET_80387
10122    && ix86_unary_operator_ok (NEG, DFmode, operands)"
10123   "#")
10124
10125 ;; FIXME: We should to allow integer registers here.  Problem is that
10126 ;; we need another scratch register to get constant from.
10127 ;; Forcing constant to mem if no register available in peep2 should be
10128 ;; safe even for PIC mode, because of RIP relative addressing.
10129 (define_insn "*negdf2_if_rex64"
10130   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10131         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10132    (clobber (reg:CC 17))]
10133   "TARGET_64BIT && TARGET_80387
10134    && ix86_unary_operator_ok (NEG, DFmode, operands)"
10135   "#")
10136
10137 (define_split
10138   [(set (match_operand:DF 0 "fp_register_operand" "")
10139         (neg:DF (match_operand:DF 1 "register_operand" "")))
10140    (clobber (reg:CC 17))]
10141   "TARGET_80387 && reload_completed"
10142   [(set (match_dup 0)
10143         (neg:DF (match_dup 1)))]
10144   "")
10145
10146 (define_split
10147   [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10148         (neg:DF (match_operand:DF 1 "register_operand" "")))
10149    (clobber (reg:CC 17))]
10150   "!TARGET_64BIT && TARGET_80387 && reload_completed"
10151   [(parallel [(set (match_dup 3) (xor:SI (match_dup 3) (match_dup 4)))
10152               (clobber (reg:CC 17))])]
10153   "operands[4] = gen_int_mode (0x80000000, SImode);
10154    split_di (operands+0, 1, operands+2, operands+3);")
10155
10156 (define_expand "negxf2"
10157   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10158                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10159               (clobber (reg:CC 17))])]
10160   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10161   "ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
10162
10163 (define_expand "negtf2"
10164   [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
10165                    (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
10166               (clobber (reg:CC 17))])]
10167   "TARGET_80387"
10168   "ix86_expand_unary_operator (NEG, TFmode, operands); DONE;")
10169
10170 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10171 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10172 ;; to itself.
10173 (define_insn "*negxf2_if"
10174   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10175         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10176    (clobber (reg:CC 17))]
10177   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
10178    && ix86_unary_operator_ok (NEG, XFmode, operands)"
10179   "#")
10180
10181 (define_split
10182   [(set (match_operand:XF 0 "fp_register_operand" "")
10183         (neg:XF (match_operand:XF 1 "register_operand" "")))
10184    (clobber (reg:CC 17))]
10185   "TARGET_80387 && reload_completed"
10186   [(set (match_dup 0)
10187         (neg:XF (match_dup 1)))]
10188   "")
10189
10190 (define_split
10191   [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10192         (neg:XF (match_operand:XF 1 "register_operand" "")))
10193    (clobber (reg:CC 17))]
10194   "TARGET_80387 && reload_completed"
10195   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
10196               (clobber (reg:CC 17))])]
10197   "operands[1] = GEN_INT (0x8000);
10198    operands[0] = gen_rtx_REG (SImode,
10199                               true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10200
10201 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10202 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10203 ;; to itself.
10204 (define_insn "*negtf2_if"
10205   [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
10206         (neg:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
10207    (clobber (reg:CC 17))]
10208   "TARGET_80387 && ix86_unary_operator_ok (NEG, TFmode, operands)"
10209   "#")
10210
10211 (define_split
10212   [(set (match_operand:TF 0 "fp_register_operand" "")
10213         (neg:TF (match_operand:TF 1 "register_operand" "")))
10214    (clobber (reg:CC 17))]
10215   "TARGET_80387 && reload_completed"
10216   [(set (match_dup 0)
10217         (neg:TF (match_dup 1)))]
10218   "")
10219
10220 (define_split
10221   [(set (match_operand:TF 0 "register_and_not_fp_reg_operand" "")
10222         (neg:TF (match_operand:TF 1 "register_operand" "")))
10223    (clobber (reg:CC 17))]
10224   "TARGET_80387 && reload_completed"
10225   [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
10226               (clobber (reg:CC 17))])]
10227   "operands[1] = GEN_INT (0x8000);
10228    operands[0] = gen_rtx_REG (SImode,
10229                               true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10230
10231 ;; Conditionalize these after reload. If they matches before reload, we 
10232 ;; lose the clobber and ability to use integer instructions.
10233
10234 (define_insn "*negsf2_1"
10235   [(set (match_operand:SF 0 "register_operand" "=f")
10236         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10237   "TARGET_80387 && reload_completed"
10238   "fchs"
10239   [(set_attr "type" "fsgn")
10240    (set_attr "mode" "SF")
10241    (set_attr "ppro_uops" "few")])
10242
10243 (define_insn "*negdf2_1"
10244   [(set (match_operand:DF 0 "register_operand" "=f")
10245         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10246   "TARGET_80387 && reload_completed"
10247   "fchs"
10248   [(set_attr "type" "fsgn")
10249    (set_attr "mode" "DF")
10250    (set_attr "ppro_uops" "few")])
10251
10252 (define_insn "*negextendsfdf2"
10253   [(set (match_operand:DF 0 "register_operand" "=f")
10254         (neg:DF (float_extend:DF
10255                   (match_operand:SF 1 "register_operand" "0"))))]
10256   "TARGET_80387"
10257   "fchs"
10258   [(set_attr "type" "fsgn")
10259    (set_attr "mode" "DF")
10260    (set_attr "ppro_uops" "few")])
10261
10262 (define_insn "*negxf2_1"
10263   [(set (match_operand:XF 0 "register_operand" "=f")
10264         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10265   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && reload_completed"
10266   "fchs"
10267   [(set_attr "type" "fsgn")
10268    (set_attr "mode" "XF")
10269    (set_attr "ppro_uops" "few")])
10270
10271 (define_insn "*negextenddfxf2"
10272   [(set (match_operand:XF 0 "register_operand" "=f")
10273         (neg:XF (float_extend:XF
10274                   (match_operand:DF 1 "register_operand" "0"))))]
10275   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10276   "fchs"
10277   [(set_attr "type" "fsgn")
10278    (set_attr "mode" "XF")
10279    (set_attr "ppro_uops" "few")])
10280
10281 (define_insn "*negextendsfxf2"
10282   [(set (match_operand:XF 0 "register_operand" "=f")
10283         (neg:XF (float_extend:XF
10284                   (match_operand:SF 1 "register_operand" "0"))))]
10285   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10286   "fchs"
10287   [(set_attr "type" "fsgn")
10288    (set_attr "mode" "XF")
10289    (set_attr "ppro_uops" "few")])
10290
10291 (define_insn "*negtf2_1"
10292   [(set (match_operand:TF 0 "register_operand" "=f")
10293         (neg:TF (match_operand:TF 1 "register_operand" "0")))]
10294   "TARGET_80387 && reload_completed"
10295   "fchs"
10296   [(set_attr "type" "fsgn")
10297    (set_attr "mode" "XF")
10298    (set_attr "ppro_uops" "few")])
10299
10300 (define_insn "*negextenddftf2"
10301   [(set (match_operand:TF 0 "register_operand" "=f")
10302         (neg:TF (float_extend:TF
10303                   (match_operand:DF 1 "register_operand" "0"))))]
10304   "TARGET_80387"
10305   "fchs"
10306   [(set_attr "type" "fsgn")
10307    (set_attr "mode" "XF")
10308    (set_attr "ppro_uops" "few")])
10309
10310 (define_insn "*negextendsftf2"
10311   [(set (match_operand:TF 0 "register_operand" "=f")
10312         (neg:TF (float_extend:TF
10313                   (match_operand:SF 1 "register_operand" "0"))))]
10314   "TARGET_80387"
10315   "fchs"
10316   [(set_attr "type" "fsgn")
10317    (set_attr "mode" "XF")
10318    (set_attr "ppro_uops" "few")])
10319 \f
10320 ;; Absolute value instructions
10321
10322 (define_expand "abssf2"
10323   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
10324                    (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))
10325               (clobber (reg:CC 17))])]
10326   "TARGET_80387"
10327   "if (TARGET_SSE)
10328      {
10329        /* In case operand is in memory,  we will not use SSE.  */
10330        if (memory_operand (operands[0], VOIDmode)
10331            && rtx_equal_p (operands[0], operands[1]))
10332          emit_insn (gen_abssf2_memory (operands[0], operands[1]));
10333        else
10334         {
10335           /* Using SSE is tricky, since we need bitwise negation of -0
10336              in register.  */
10337           rtx reg = gen_reg_rtx (V4SFmode);
10338           rtx dest = operands[0];
10339           rtx imm;
10340
10341           operands[1] = force_reg (SFmode, operands[1]);
10342           operands[0] = force_reg (SFmode, operands[0]);
10343           imm = gen_lowpart (SFmode, gen_int_mode(~0x80000000, SImode));
10344           reg = force_reg (V4SFmode,
10345                            gen_rtx_CONST_VECTOR (V4SFmode,
10346                            gen_rtvec (4, imm, CONST0_RTX (SFmode),
10347                                       CONST0_RTX (SFmode),
10348                                       CONST0_RTX (SFmode))));
10349           emit_insn (gen_abssf2_ifs (operands[0], operands[1], reg));
10350           if (dest != operands[0])
10351             emit_move_insn (dest, operands[0]);
10352         }
10353        DONE;
10354      }
10355    ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
10356
10357 (define_insn "abssf2_memory"
10358   [(set (match_operand:SF 0 "memory_operand" "=m")
10359         (abs:SF (match_operand:SF 1 "memory_operand" "0")))
10360    (clobber (reg:CC 17))]
10361   "ix86_unary_operator_ok (ABS, SFmode, operands)"
10362   "#")
10363
10364 (define_insn "abssf2_ifs"
10365   [(set (match_operand:SF 0 "nonimmediate_operand" "=x#fr,x#fr,f#xr,rm#xf")
10366         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,x#fr,0,0")))
10367    (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,xm*r,xm*r"))
10368    (clobber (reg:CC 17))]
10369   "TARGET_SSE
10370    && (reload_in_progress || reload_completed
10371        || (register_operand (operands[0], VOIDmode)
10372             && register_operand (operands[1], VOIDmode)))"
10373   "#")
10374
10375 (define_split
10376   [(set (match_operand:SF 0 "memory_operand" "")
10377         (abs:SF (match_operand:SF 1 "memory_operand" "")))
10378    (use (match_operand:V4SF 2 "" ""))
10379    (clobber (reg:CC 17))]
10380   ""
10381   [(parallel [(set (match_dup 0)
10382                    (abs:SF (match_dup 1)))
10383               (clobber (reg:CC 17))])])
10384
10385 (define_split
10386   [(set (match_operand:SF 0 "register_operand" "")
10387         (abs:SF (match_operand:SF 1 "register_operand" "")))
10388    (use (match_operand:V4SF 2 "" ""))
10389    (clobber (reg:CC 17))]
10390   "reload_completed && !SSE_REG_P (operands[0])"
10391   [(parallel [(set (match_dup 0)
10392                    (abs:SF (match_dup 1)))
10393               (clobber (reg:CC 17))])])
10394
10395 (define_split
10396   [(set (match_operand:SF 0 "register_operand" "")
10397         (abs:SF (match_operand:SF 1 "register_operand" "")))
10398    (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
10399    (clobber (reg:CC 17))]
10400   "reload_completed && SSE_REG_P (operands[0])"
10401   [(set (subreg:TI (match_dup 0) 0)
10402         (and:TI (match_dup 1)
10403                 (match_dup 2)))]
10404 {
10405   operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
10406   operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
10407   if (operands_match_p (operands[0], operands[2]))
10408     {
10409       rtx tmp;
10410       tmp = operands[1];
10411       operands[1] = operands[2];
10412       operands[2] = tmp;
10413     }
10414 })
10415
10416 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10417 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10418 ;; to itself.
10419 (define_insn "*abssf2_if"
10420   [(set (match_operand:SF 0 "nonimmediate_operand" "=f#r,rm#f")
10421         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "0,0")))
10422    (clobber (reg:CC 17))]
10423   "TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands) && !TARGET_SSE"
10424   "#")
10425
10426 (define_split
10427   [(set (match_operand:SF 0 "fp_register_operand" "")
10428         (abs:SF (match_operand:SF 1 "register_operand" "")))
10429    (clobber (reg:CC 17))]
10430   "TARGET_80387 && reload_completed"
10431   [(set (match_dup 0)
10432         (abs:SF (match_dup 1)))]
10433   "")
10434
10435 (define_split
10436   [(set (match_operand:SF 0 "register_and_not_fp_reg_operand" "")
10437         (abs:SF (match_operand:SF 1 "register_operand" "")))
10438    (clobber (reg:CC 17))]
10439   "TARGET_80387 && reload_completed"
10440   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10441               (clobber (reg:CC 17))])]
10442   "operands[1] = gen_int_mode (~0x80000000, SImode);
10443    operands[0] = gen_lowpart (SImode, operands[0]);")
10444
10445 (define_split
10446   [(set (match_operand 0 "memory_operand" "")
10447         (abs (match_operand 1 "memory_operand" "")))
10448    (clobber (reg:CC 17))]
10449   "TARGET_80387 && reload_completed && FLOAT_MODE_P (GET_MODE (operands[0]))"
10450   [(parallel [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))
10451               (clobber (reg:CC 17))])]
10452 {
10453   int size = GET_MODE_SIZE (GET_MODE (operands[1]));
10454
10455   /* XFmode's size is 12, TFmode 16, but only 10 bytes are used.  */
10456   if (size >= 12)
10457     size = 10;
10458   operands[0] = adjust_address (operands[0], QImode, size - 1);
10459   operands[1] = gen_int_mode (~0x80, QImode);
10460 })
10461
10462 (define_expand "absdf2"
10463   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
10464                    (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))
10465               (clobber (reg:CC 17))])]
10466   "TARGET_80387"
10467   "if (TARGET_SSE2)
10468      {
10469        /* In case operand is in memory,  we will not use SSE.  */
10470        if (memory_operand (operands[0], VOIDmode)
10471            && rtx_equal_p (operands[0], operands[1]))
10472          emit_insn (gen_absdf2_memory (operands[0], operands[1]));
10473        else
10474         {
10475           /* Using SSE is tricky, since we need bitwise negation of -0
10476              in register.  */
10477           rtx reg = gen_reg_rtx (V2DFmode);
10478 #if HOST_BITS_PER_WIDE_INT >= 64
10479           rtx imm = gen_int_mode (~(((HOST_WIDE_INT)1) << 63), DImode);
10480 #else
10481           rtx imm = immed_double_const (~0, ~0x80000000, DImode);
10482 #endif
10483           rtx dest = operands[0];
10484
10485           operands[1] = force_reg (DFmode, operands[1]);
10486           operands[0] = force_reg (DFmode, operands[0]);
10487
10488           /* Produce LONG_DOUBLE with the proper immediate argument.  */
10489           imm = gen_lowpart (DFmode, imm);
10490           reg = force_reg (V2DFmode,
10491                            gen_rtx_CONST_VECTOR (V2DFmode,
10492                            gen_rtvec (2, imm, CONST0_RTX (DFmode))));
10493           emit_insn (gen_absdf2_ifs (operands[0], operands[1], reg));
10494           if (dest != operands[0])
10495             emit_move_insn (dest, operands[0]);
10496         }
10497        DONE;
10498      }
10499    ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
10500
10501 (define_insn "absdf2_memory"
10502   [(set (match_operand:DF 0 "memory_operand" "=m")
10503         (abs:DF (match_operand:DF 1 "memory_operand" "0")))
10504    (clobber (reg:CC 17))]
10505   "ix86_unary_operator_ok (ABS, DFmode, operands)"
10506   "#")
10507
10508 (define_insn "absdf2_ifs"
10509   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr,mr#Yf")
10510         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0,0")))
10511    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r,Ym*r"))
10512    (clobber (reg:CC 17))]
10513   "!TARGET_64BIT && TARGET_SSE2
10514    && (reload_in_progress || reload_completed
10515        || (register_operand (operands[0], VOIDmode)
10516            && register_operand (operands[1], VOIDmode)))"
10517   "#")
10518
10519 (define_insn "*absdf2_ifs_rex64"
10520   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#fr,Y#fr,mf#Yr")
10521         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,Y#fr,0")))
10522    (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,Ym*r"))
10523    (clobber (reg:CC 17))]
10524   "TARGET_64BIT && TARGET_SSE2
10525    && (reload_in_progress || reload_completed
10526        || (register_operand (operands[0], VOIDmode)
10527            && register_operand (operands[1], VOIDmode)))"
10528   "#")
10529
10530 (define_split
10531   [(set (match_operand:DF 0 "memory_operand" "")
10532         (abs:DF (match_operand:DF 1 "memory_operand" "")))
10533    (use (match_operand:V2DF 2 "" ""))
10534    (clobber (reg:CC 17))]
10535   ""
10536   [(parallel [(set (match_dup 0)
10537                    (abs:DF (match_dup 1)))
10538               (clobber (reg:CC 17))])])
10539
10540 (define_split
10541   [(set (match_operand:DF 0 "register_operand" "")
10542         (abs:DF (match_operand:DF 1 "register_operand" "")))
10543    (use (match_operand:V2DF 2 "" ""))
10544    (clobber (reg:CC 17))]
10545   "reload_completed && !SSE_REG_P (operands[0])"
10546   [(parallel [(set (match_dup 0)
10547                    (abs:DF (match_dup 1)))
10548               (clobber (reg:CC 17))])])
10549
10550 (define_split
10551   [(set (match_operand:DF 0 "register_operand" "")
10552         (abs:DF (match_operand:DF 1 "register_operand" "")))
10553    (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
10554    (clobber (reg:CC 17))]
10555   "reload_completed && SSE_REG_P (operands[0])"
10556   [(set (subreg:TI (match_dup 0) 0)
10557         (and:TI (match_dup 1)
10558                 (match_dup 2)))]
10559 {
10560   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
10561   operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
10562   operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
10563   /* Avoid possible reformatting on the operands.  */
10564   if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
10565     emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
10566   if (operands_match_p (operands[0], operands[2]))
10567     {
10568       rtx tmp;
10569       tmp = operands[1];
10570       operands[1] = operands[2];
10571       operands[2] = tmp;
10572     }
10573 })
10574
10575
10576 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10577 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10578 ;; to itself.
10579 (define_insn "*absdf2_if"
10580   [(set (match_operand:DF 0 "nonimmediate_operand" "=f#r,rm#f")
10581         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10582    (clobber (reg:CC 17))]
10583   "!TARGET_64BIT && TARGET_80387
10584    && ix86_unary_operator_ok (ABS, DFmode, operands)"
10585   "#")
10586
10587 ;; FIXME: We should to allow integer registers here.  Problem is that
10588 ;; we need another scratch register to get constant from.
10589 ;; Forcing constant to mem if no register available in peep2 should be
10590 ;; safe even for PIC mode, because of RIP relative addressing.
10591 (define_insn "*absdf2_if_rex64"
10592   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,mf")
10593         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "0,0")))
10594    (clobber (reg:CC 17))]
10595   "TARGET_64BIT && TARGET_80387
10596    && ix86_unary_operator_ok (ABS, DFmode, operands)"
10597   "#")
10598
10599 (define_split
10600   [(set (match_operand:DF 0 "fp_register_operand" "")
10601         (abs:DF (match_operand:DF 1 "register_operand" "")))
10602    (clobber (reg:CC 17))]
10603   "TARGET_80387 && reload_completed"
10604   [(set (match_dup 0)
10605         (abs:DF (match_dup 1)))]
10606   "")
10607
10608 (define_split
10609   [(set (match_operand:DF 0 "register_and_not_fp_reg_operand" "")
10610         (abs:DF (match_operand:DF 1 "register_operand" "")))
10611    (clobber (reg:CC 17))]
10612   "!TARGET_64BIT && TARGET_80387 && reload_completed"
10613   [(parallel [(set (match_dup 3) (and:SI (match_dup 3) (match_dup 4)))
10614               (clobber (reg:CC 17))])]
10615   "operands[4] = gen_int_mode (~0x80000000, SImode);
10616    split_di (operands+0, 1, operands+2, operands+3);")
10617
10618 (define_expand "absxf2"
10619   [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
10620                    (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))
10621               (clobber (reg:CC 17))])]
10622   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10623   "ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
10624
10625 (define_expand "abstf2"
10626   [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
10627                    (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
10628               (clobber (reg:CC 17))])]
10629   "TARGET_80387"
10630   "ix86_expand_unary_operator (ABS, TFmode, operands); DONE;")
10631
10632 ;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
10633 ;; because of secondary memory needed to reload from class FLOAT_INT_REGS
10634 ;; to itself.
10635 (define_insn "*absxf2_if"
10636   [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,rm#f")
10637         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "0,0")))
10638    (clobber (reg:CC 17))]
10639   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
10640    && ix86_unary_operator_ok (ABS, XFmode, operands)"
10641   "#")
10642
10643 (define_split
10644   [(set (match_operand:XF 0 "fp_register_operand" "")
10645         (abs:XF (match_operand:XF 1 "register_operand" "")))
10646    (clobber (reg:CC 17))]
10647   "TARGET_80387 && reload_completed"
10648   [(set (match_dup 0)
10649         (abs:XF (match_dup 1)))]
10650   "")
10651
10652 (define_split
10653   [(set (match_operand:XF 0 "register_and_not_fp_reg_operand" "")
10654         (abs:XF (match_operand:XF 1 "register_operand" "")))
10655    (clobber (reg:CC 17))]
10656   "TARGET_80387 && reload_completed"
10657   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10658               (clobber (reg:CC 17))])]
10659   "operands[1] = GEN_INT (~0x8000);
10660    operands[0] = gen_rtx_REG (SImode,
10661                               true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10662
10663 (define_insn "*abstf2_if"
10664   [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
10665         (abs:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
10666    (clobber (reg:CC 17))]
10667   "TARGET_80387 && ix86_unary_operator_ok (ABS, TFmode, operands)"
10668   "#")
10669
10670 (define_split
10671   [(set (match_operand:TF 0 "fp_register_operand" "")
10672         (abs:TF (match_operand:TF 1 "register_operand" "")))
10673    (clobber (reg:CC 17))]
10674   "TARGET_80387 && reload_completed"
10675   [(set (match_dup 0)
10676         (abs:TF (match_dup 1)))]
10677   "")
10678
10679 (define_split
10680   [(set (match_operand:TF 0 "register_and_not_any_fp_reg_operand" "")
10681         (abs:TF (match_operand:TF 1 "register_operand" "")))
10682    (clobber (reg:CC 17))]
10683   "TARGET_80387 && reload_completed"
10684   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
10685               (clobber (reg:CC 17))])]
10686   "operands[1] = GEN_INT (~0x8000);
10687    operands[0] = gen_rtx_REG (SImode,
10688                               true_regnum (operands[0]) + (TARGET_64BIT ? 1 : 2));")
10689
10690 (define_insn "*abssf2_1"
10691   [(set (match_operand:SF 0 "register_operand" "=f")
10692         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10693   "TARGET_80387 && reload_completed"
10694   "fabs"
10695   [(set_attr "type" "fsgn")
10696    (set_attr "mode" "SF")])
10697
10698 (define_insn "*absdf2_1"
10699   [(set (match_operand:DF 0 "register_operand" "=f")
10700         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10701   "TARGET_80387 && reload_completed"
10702   "fabs"
10703   [(set_attr "type" "fsgn")
10704    (set_attr "mode" "DF")])
10705
10706 (define_insn "*absextendsfdf2"
10707   [(set (match_operand:DF 0 "register_operand" "=f")
10708         (abs:DF (float_extend:DF
10709                   (match_operand:SF 1 "register_operand" "0"))))]
10710   "TARGET_80387"
10711   "fabs"
10712   [(set_attr "type" "fsgn")
10713    (set_attr "mode" "DF")])
10714
10715 (define_insn "*absxf2_1"
10716   [(set (match_operand:XF 0 "register_operand" "=f")
10717         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10718   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && reload_completed"
10719   "fabs"
10720   [(set_attr "type" "fsgn")
10721    (set_attr "mode" "DF")])
10722
10723 (define_insn "*absextenddfxf2"
10724   [(set (match_operand:XF 0 "register_operand" "=f")
10725         (abs:XF (float_extend:XF
10726           (match_operand:DF 1 "register_operand" "0"))))]
10727   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10728   "fabs"
10729   [(set_attr "type" "fsgn")
10730    (set_attr "mode" "XF")])
10731
10732 (define_insn "*absextendsfxf2"
10733   [(set (match_operand:XF 0 "register_operand" "=f")
10734         (abs:XF (float_extend:XF
10735           (match_operand:SF 1 "register_operand" "0"))))]
10736   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
10737   "fabs"
10738   [(set_attr "type" "fsgn")
10739    (set_attr "mode" "XF")])
10740
10741 (define_insn "*abstf2_1"
10742   [(set (match_operand:TF 0 "register_operand" "=f")
10743         (abs:TF (match_operand:TF 1 "register_operand" "0")))]
10744   "TARGET_80387 && reload_completed"
10745   "fabs"
10746   [(set_attr "type" "fsgn")
10747    (set_attr "mode" "DF")])
10748
10749 (define_insn "*absextenddftf2"
10750   [(set (match_operand:TF 0 "register_operand" "=f")
10751         (abs:TF (float_extend:TF
10752           (match_operand:DF 1 "register_operand" "0"))))]
10753   "TARGET_80387"
10754   "fabs"
10755   [(set_attr "type" "fsgn")
10756    (set_attr "mode" "XF")])
10757
10758 (define_insn "*absextendsftf2"
10759   [(set (match_operand:TF 0 "register_operand" "=f")
10760         (abs:TF (float_extend:TF
10761           (match_operand:SF 1 "register_operand" "0"))))]
10762   "TARGET_80387"
10763   "fabs"
10764   [(set_attr "type" "fsgn")
10765    (set_attr "mode" "XF")])
10766 \f
10767 ;; One complement instructions
10768
10769 (define_expand "one_cmpldi2"
10770   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10771         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10772   "TARGET_64BIT"
10773   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10774
10775 (define_insn "*one_cmpldi2_1_rex64"
10776   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10777         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10778   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10779   "not{q}\t%0"
10780   [(set_attr "type" "negnot")
10781    (set_attr "mode" "DI")])
10782
10783 (define_insn "*one_cmpldi2_2_rex64"
10784   [(set (reg 17)
10785         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10786                  (const_int 0)))
10787    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10788         (not:DI (match_dup 1)))]
10789   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10790    && ix86_unary_operator_ok (NOT, DImode, operands)"
10791   "#"
10792   [(set_attr "type" "alu1")
10793    (set_attr "mode" "DI")])
10794
10795 (define_split
10796   [(set (reg 17)
10797         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" ""))
10798                  (const_int 0)))
10799    (set (match_operand:DI 0 "nonimmediate_operand" "")
10800         (not:DI (match_dup 1)))]
10801   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10802   [(parallel [(set (reg:CCNO 17)
10803                    (compare:CCNO (xor:DI (match_dup 1) (const_int -1))
10804                                  (const_int 0)))
10805               (set (match_dup 0)
10806                    (xor:DI (match_dup 1) (const_int -1)))])]
10807   "")
10808
10809 (define_expand "one_cmplsi2"
10810   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10811         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10812   ""
10813   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10814
10815 (define_insn "*one_cmplsi2_1"
10816   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10817         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10818   "ix86_unary_operator_ok (NOT, SImode, operands)"
10819   "not{l}\t%0"
10820   [(set_attr "type" "negnot")
10821    (set_attr "mode" "SI")])
10822
10823 ;; ??? Currently never generated - xor is used instead.
10824 (define_insn "*one_cmplsi2_1_zext"
10825   [(set (match_operand:DI 0 "register_operand" "=r")
10826         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10827   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10828   "not{l}\t%k0"
10829   [(set_attr "type" "negnot")
10830    (set_attr "mode" "SI")])
10831
10832 (define_insn "*one_cmplsi2_2"
10833   [(set (reg 17)
10834         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10835                  (const_int 0)))
10836    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10837         (not:SI (match_dup 1)))]
10838   "ix86_match_ccmode (insn, CCNOmode)
10839    && ix86_unary_operator_ok (NOT, SImode, operands)"
10840   "#"
10841   [(set_attr "type" "alu1")
10842    (set_attr "mode" "SI")])
10843
10844 (define_split
10845   [(set (reg 17)
10846         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" ""))
10847                  (const_int 0)))
10848    (set (match_operand:SI 0 "nonimmediate_operand" "")
10849         (not:SI (match_dup 1)))]
10850   "ix86_match_ccmode (insn, CCNOmode)"
10851   [(parallel [(set (reg:CCNO 17)
10852                    (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10853                                  (const_int 0)))
10854               (set (match_dup 0)
10855                    (xor:SI (match_dup 1) (const_int -1)))])]
10856   "")
10857
10858 ;; ??? Currently never generated - xor is used instead.
10859 (define_insn "*one_cmplsi2_2_zext"
10860   [(set (reg 17)
10861         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10862                  (const_int 0)))
10863    (set (match_operand:DI 0 "register_operand" "=r")
10864         (zero_extend:DI (not:SI (match_dup 1))))]
10865   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10866    && ix86_unary_operator_ok (NOT, SImode, operands)"
10867   "#"
10868   [(set_attr "type" "alu1")
10869    (set_attr "mode" "SI")])
10870
10871 (define_split
10872   [(set (reg 17)
10873         (compare (not:SI (match_operand:SI 1 "register_operand" ""))
10874                  (const_int 0)))
10875    (set (match_operand:DI 0 "register_operand" "")
10876         (zero_extend:DI (not:SI (match_dup 1))))]
10877   "ix86_match_ccmode (insn, CCNOmode)"
10878   [(parallel [(set (reg:CCNO 17)
10879                    (compare:CCNO (xor:SI (match_dup 1) (const_int -1))
10880                                  (const_int 0)))
10881               (set (match_dup 0)
10882                    (zero_extend:DI (xor:SI (match_dup 1) (const_int -1))))])]
10883   "")
10884
10885 (define_expand "one_cmplhi2"
10886   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10887         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10888   "TARGET_HIMODE_MATH"
10889   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10890
10891 (define_insn "*one_cmplhi2_1"
10892   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10893         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10894   "ix86_unary_operator_ok (NOT, HImode, operands)"
10895   "not{w}\t%0"
10896   [(set_attr "type" "negnot")
10897    (set_attr "mode" "HI")])
10898
10899 (define_insn "*one_cmplhi2_2"
10900   [(set (reg 17)
10901         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10902                  (const_int 0)))
10903    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10904         (not:HI (match_dup 1)))]
10905   "ix86_match_ccmode (insn, CCNOmode)
10906    && ix86_unary_operator_ok (NEG, HImode, operands)"
10907   "#"
10908   [(set_attr "type" "alu1")
10909    (set_attr "mode" "HI")])
10910
10911 (define_split
10912   [(set (reg 17)
10913         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" ""))
10914                  (const_int 0)))
10915    (set (match_operand:HI 0 "nonimmediate_operand" "")
10916         (not:HI (match_dup 1)))]
10917   "ix86_match_ccmode (insn, CCNOmode)"
10918   [(parallel [(set (reg:CCNO 17)
10919                    (compare:CCNO (xor:HI (match_dup 1) (const_int -1))
10920                                  (const_int 0)))
10921               (set (match_dup 0)
10922                    (xor:HI (match_dup 1) (const_int -1)))])]
10923   "")
10924
10925 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10926 (define_expand "one_cmplqi2"
10927   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10928         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10929   "TARGET_QIMODE_MATH"
10930   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10931
10932 (define_insn "*one_cmplqi2_1"
10933   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10934         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10935   "ix86_unary_operator_ok (NOT, QImode, operands)"
10936   "@
10937    not{b}\t%0
10938    not{l}\t%k0"
10939   [(set_attr "type" "negnot")
10940    (set_attr "mode" "QI,SI")])
10941
10942 (define_insn "*one_cmplqi2_2"
10943   [(set (reg 17)
10944         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10945                  (const_int 0)))
10946    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10947         (not:QI (match_dup 1)))]
10948   "ix86_match_ccmode (insn, CCNOmode)
10949    && ix86_unary_operator_ok (NOT, QImode, operands)"
10950   "#"
10951   [(set_attr "type" "alu1")
10952    (set_attr "mode" "QI")])
10953
10954 (define_split
10955   [(set (reg 17)
10956         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" ""))
10957                  (const_int 0)))
10958    (set (match_operand:QI 0 "nonimmediate_operand" "")
10959         (not:QI (match_dup 1)))]
10960   "ix86_match_ccmode (insn, CCNOmode)"
10961   [(parallel [(set (reg:CCNO 17)
10962                    (compare:CCNO (xor:QI (match_dup 1) (const_int -1))
10963                                  (const_int 0)))
10964               (set (match_dup 0)
10965                    (xor:QI (match_dup 1) (const_int -1)))])]
10966   "")
10967 \f
10968 ;; Arithmetic shift instructions
10969
10970 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10971 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10972 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10973 ;; from the assembler input.
10974 ;;
10975 ;; This instruction shifts the target reg/mem as usual, but instead of
10976 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10977 ;; is a left shift double, bits are taken from the high order bits of
10978 ;; reg, else if the insn is a shift right double, bits are taken from the
10979 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10980 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10981 ;;
10982 ;; Since sh[lr]d does not change the `reg' operand, that is done
10983 ;; separately, making all shifts emit pairs of shift double and normal
10984 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10985 ;; support a 63 bit shift, each shift where the count is in a reg expands
10986 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10987 ;;
10988 ;; If the shift count is a constant, we need never emit more than one
10989 ;; shift pair, instead using moves and sign extension for counts greater
10990 ;; than 31.
10991
10992 (define_expand "ashldi3"
10993   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
10994                    (ashift:DI (match_operand:DI 1 "shiftdi_operand" "")
10995                               (match_operand:QI 2 "nonmemory_operand" "")))
10996               (clobber (reg:CC 17))])]
10997   ""
10998 {
10999   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11000     {
11001       emit_insn (gen_ashldi3_1 (operands[0], operands[1], operands[2]));
11002       DONE;
11003     }
11004   ix86_expand_binary_operator (ASHIFT, DImode, operands);
11005   DONE;
11006 })
11007
11008 (define_insn "*ashldi3_1_rex64"
11009   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11010         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,r")
11011                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11012    (clobber (reg:CC 17))]
11013   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11014 {
11015   switch (get_attr_type (insn))
11016     {
11017     case TYPE_ALU:
11018       if (operands[2] != const1_rtx)
11019         abort ();
11020       if (!rtx_equal_p (operands[0], operands[1]))
11021         abort ();
11022       return "add{q}\t{%0, %0|%0, %0}";
11023
11024     case TYPE_LEA:
11025       if (GET_CODE (operands[2]) != CONST_INT
11026           || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
11027         abort ();
11028       operands[1] = gen_rtx_MULT (DImode, operands[1],
11029                                   GEN_INT (1 << INTVAL (operands[2])));
11030       return "lea{q}\t{%a1, %0|%0, %a1}";
11031
11032     default:
11033       if (REG_P (operands[2]))
11034         return "sal{q}\t{%b2, %0|%0, %b2}";
11035       else if (GET_CODE (operands[2]) == CONST_INT
11036                && INTVAL (operands[2]) == 1
11037                && (TARGET_SHIFT1 || optimize_size))
11038         return "sal{q}\t%0";
11039       else
11040         return "sal{q}\t{%2, %0|%0, %2}";
11041     }
11042 }
11043   [(set (attr "type")
11044      (cond [(eq_attr "alternative" "1")
11045               (const_string "lea")
11046             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11047                           (const_int 0))
11048                       (match_operand 0 "register_operand" ""))
11049                  (match_operand 2 "const1_operand" ""))
11050               (const_string "alu")
11051            ]
11052            (const_string "ishift")))
11053    (set_attr "mode" "DI")])
11054
11055 ;; Convert lea to the lea pattern to avoid flags dependency.
11056 (define_split
11057   [(set (match_operand:DI 0 "register_operand" "")
11058         (ashift:DI (match_operand:DI 1 "register_operand" "")
11059                    (match_operand:QI 2 "immediate_operand" "")))
11060    (clobber (reg:CC 17))]
11061   "TARGET_64BIT && reload_completed
11062    && true_regnum (operands[0]) != true_regnum (operands[1])"
11063   [(set (match_dup 0)
11064         (mult:DI (match_dup 1)
11065                  (match_dup 2)))]
11066   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11067
11068 ;; This pattern can't accept a variable shift count, since shifts by
11069 ;; zero don't affect the flags.  We assume that shifts by constant
11070 ;; zero are optimized away.
11071 (define_insn "*ashldi3_cmp_rex64"
11072   [(set (reg 17)
11073         (compare
11074           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11075                      (match_operand:QI 2 "immediate_operand" "e"))
11076           (const_int 0)))
11077    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11078         (ashift:DI (match_dup 1) (match_dup 2)))]
11079   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11080    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11081 {
11082   switch (get_attr_type (insn))
11083     {
11084     case TYPE_ALU:
11085       if (operands[2] != const1_rtx)
11086         abort ();
11087       return "add{q}\t{%0, %0|%0, %0}";
11088
11089     default:
11090       if (REG_P (operands[2]))
11091         return "sal{q}\t{%b2, %0|%0, %b2}";
11092       else if (GET_CODE (operands[2]) == CONST_INT
11093                && INTVAL (operands[2]) == 1
11094                && (TARGET_SHIFT1 || optimize_size))
11095         return "sal{q}\t%0";
11096       else
11097         return "sal{q}\t{%2, %0|%0, %2}";
11098     }
11099 }
11100   [(set (attr "type")
11101      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11102                           (const_int 0))
11103                       (match_operand 0 "register_operand" ""))
11104                  (match_operand 2 "const1_operand" ""))
11105               (const_string "alu")
11106            ]
11107            (const_string "ishift")))
11108    (set_attr "mode" "DI")])
11109
11110 (define_insn "ashldi3_1"
11111   [(set (match_operand:DI 0 "register_operand" "=r")
11112         (ashift:DI (match_operand:DI 1 "register_operand" "0")
11113                    (match_operand:QI 2 "nonmemory_operand" "Jc")))
11114    (clobber (match_scratch:SI 3 "=&r"))
11115    (clobber (reg:CC 17))]
11116   "!TARGET_64BIT && TARGET_CMOVE"
11117   "#"
11118   [(set_attr "type" "multi")])
11119
11120 (define_insn "*ashldi3_2"
11121   [(set (match_operand:DI 0 "register_operand" "=r")
11122         (ashift:DI (match_operand:DI 1 "register_operand" "0")
11123                    (match_operand:QI 2 "nonmemory_operand" "Jc")))
11124    (clobber (reg:CC 17))]
11125   "!TARGET_64BIT"
11126   "#"
11127   [(set_attr "type" "multi")])
11128
11129 (define_split
11130   [(set (match_operand:DI 0 "register_operand" "")
11131         (ashift:DI (match_operand:DI 1 "register_operand" "")
11132                    (match_operand:QI 2 "nonmemory_operand" "")))
11133    (clobber (match_scratch:SI 3 ""))
11134    (clobber (reg:CC 17))]
11135   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11136   [(const_int 0)]
11137   "ix86_split_ashldi (operands, operands[3]); DONE;")
11138
11139 (define_split
11140   [(set (match_operand:DI 0 "register_operand" "")
11141         (ashift:DI (match_operand:DI 1 "register_operand" "")
11142                    (match_operand:QI 2 "nonmemory_operand" "")))
11143    (clobber (reg:CC 17))]
11144   "!TARGET_64BIT && reload_completed"
11145   [(const_int 0)]
11146   "ix86_split_ashldi (operands, NULL_RTX); DONE;")
11147
11148 (define_insn "x86_shld_1"
11149   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11150         (ior:SI (ashift:SI (match_dup 0)
11151                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11152                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11153                   (minus:QI (const_int 32) (match_dup 2)))))
11154    (clobber (reg:CC 17))]
11155   ""
11156   "@
11157    shld{l}\t{%2, %1, %0|%0, %1, %2}
11158    shld{l}\t{%s2%1, %0|%0, %1, %2}"
11159   [(set_attr "type" "ishift")
11160    (set_attr "prefix_0f" "1")
11161    (set_attr "mode" "SI")
11162    (set_attr "pent_pair" "np")
11163    (set_attr "athlon_decode" "vector")
11164    (set_attr "ppro_uops" "few")])
11165
11166 (define_expand "x86_shift_adj_1"
11167   [(set (reg:CCZ 17)
11168         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11169                              (const_int 32))
11170                      (const_int 0)))
11171    (set (match_operand:SI 0 "register_operand" "")
11172         (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
11173                          (match_operand:SI 1 "register_operand" "")
11174                          (match_dup 0)))
11175    (set (match_dup 1)
11176         (if_then_else:SI (ne (reg:CCZ 17) (const_int 0))
11177                          (match_operand:SI 3 "register_operand" "r")
11178                          (match_dup 1)))]
11179   "TARGET_CMOVE"
11180   "")
11181
11182 (define_expand "x86_shift_adj_2"
11183   [(use (match_operand:SI 0 "register_operand" ""))
11184    (use (match_operand:SI 1 "register_operand" ""))
11185    (use (match_operand:QI 2 "register_operand" ""))]
11186   ""
11187 {
11188   rtx label = gen_label_rtx ();
11189   rtx tmp;
11190
11191   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11192
11193   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11194   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11195   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11196                               gen_rtx_LABEL_REF (VOIDmode, label),
11197                               pc_rtx);
11198   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11199   JUMP_LABEL (tmp) = label;
11200
11201   emit_move_insn (operands[0], operands[1]);
11202   emit_move_insn (operands[1], const0_rtx);
11203
11204   emit_label (label);
11205   LABEL_NUSES (label) = 1;
11206
11207   DONE;
11208 })
11209
11210 (define_expand "ashlsi3"
11211   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11212         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11213                    (match_operand:QI 2 "nonmemory_operand" "")))
11214    (clobber (reg:CC 17))]
11215   ""
11216   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11217
11218 (define_insn "*ashlsi3_1"
11219   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11220         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r")
11221                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11222    (clobber (reg:CC 17))]
11223   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11224 {
11225   switch (get_attr_type (insn))
11226     {
11227     case TYPE_ALU:
11228       if (operands[2] != const1_rtx)
11229         abort ();
11230       if (!rtx_equal_p (operands[0], operands[1]))
11231         abort ();
11232       return "add{l}\t{%0, %0|%0, %0}";
11233
11234     case TYPE_LEA:
11235       return "#";
11236
11237     default:
11238       if (REG_P (operands[2]))
11239         return "sal{l}\t{%b2, %0|%0, %b2}";
11240       else if (GET_CODE (operands[2]) == CONST_INT
11241                && INTVAL (operands[2]) == 1
11242                && (TARGET_SHIFT1 || optimize_size))
11243         return "sal{l}\t%0";
11244       else
11245         return "sal{l}\t{%2, %0|%0, %2}";
11246     }
11247 }
11248   [(set (attr "type")
11249      (cond [(eq_attr "alternative" "1")
11250               (const_string "lea")
11251             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11252                           (const_int 0))
11253                       (match_operand 0 "register_operand" ""))
11254                  (match_operand 2 "const1_operand" ""))
11255               (const_string "alu")
11256            ]
11257            (const_string "ishift")))
11258    (set_attr "mode" "SI")])
11259
11260 ;; Convert lea to the lea pattern to avoid flags dependency.
11261 (define_split
11262   [(set (match_operand 0 "register_operand" "")
11263         (ashift (match_operand 1 "index_register_operand" "")
11264                 (match_operand:QI 2 "const_int_operand" "")))
11265    (clobber (reg:CC 17))]
11266   "reload_completed
11267    && true_regnum (operands[0]) != true_regnum (operands[1])"
11268   [(const_int 0)]
11269 {
11270   rtx pat;
11271   operands[0] = gen_lowpart (SImode, operands[0]);
11272   operands[1] = gen_lowpart (Pmode, operands[1]);
11273   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11274   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11275   if (Pmode != SImode)
11276     pat = gen_rtx_SUBREG (SImode, pat, 0);
11277   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11278   DONE;
11279 })
11280
11281 ;; Rare case of shifting RSP is handled by generating move and shift
11282 (define_split
11283   [(set (match_operand 0 "register_operand" "")
11284         (ashift (match_operand 1 "register_operand" "")
11285                 (match_operand:QI 2 "const_int_operand" "")))
11286    (clobber (reg:CC 17))]
11287   "reload_completed
11288    && true_regnum (operands[0]) != true_regnum (operands[1])"
11289   [(const_int 0)]
11290 {
11291   rtx pat, clob;
11292   emit_move_insn (operands[1], operands[0]);
11293   pat = gen_rtx_SET (VOIDmode, operands[0],
11294                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11295                                      operands[0], operands[2]));
11296   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11297   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11298   DONE;
11299 })
11300
11301 (define_insn "*ashlsi3_1_zext"
11302   [(set (match_operand:DI 0 "register_operand" "=r,r")
11303         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,r")
11304                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11305    (clobber (reg:CC 17))]
11306   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11307 {
11308   switch (get_attr_type (insn))
11309     {
11310     case TYPE_ALU:
11311       if (operands[2] != const1_rtx)
11312         abort ();
11313       return "add{l}\t{%k0, %k0|%k0, %k0}";
11314
11315     case TYPE_LEA:
11316       return "#";
11317
11318     default:
11319       if (REG_P (operands[2]))
11320         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11321       else if (GET_CODE (operands[2]) == CONST_INT
11322                && INTVAL (operands[2]) == 1
11323                && (TARGET_SHIFT1 || optimize_size))
11324         return "sal{l}\t%k0";
11325       else
11326         return "sal{l}\t{%2, %k0|%k0, %2}";
11327     }
11328 }
11329   [(set (attr "type")
11330      (cond [(eq_attr "alternative" "1")
11331               (const_string "lea")
11332             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11333                      (const_int 0))
11334                  (match_operand 2 "const1_operand" ""))
11335               (const_string "alu")
11336            ]
11337            (const_string "ishift")))
11338    (set_attr "mode" "SI")])
11339
11340 ;; Convert lea to the lea pattern to avoid flags dependency.
11341 (define_split
11342   [(set (match_operand:DI 0 "register_operand" "")
11343         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11344                                 (match_operand:QI 2 "const_int_operand" ""))))
11345    (clobber (reg:CC 17))]
11346   "TARGET_64BIT && reload_completed
11347    && true_regnum (operands[0]) != true_regnum (operands[1])"
11348   [(set (match_dup 0) (zero_extend:DI
11349                         (subreg:SI (mult:SI (match_dup 1)
11350                                             (match_dup 2)) 0)))]
11351 {
11352   operands[1] = gen_lowpart (Pmode, operands[1]);
11353   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11354 })
11355
11356 ;; This pattern can't accept a variable shift count, since shifts by
11357 ;; zero don't affect the flags.  We assume that shifts by constant
11358 ;; zero are optimized away.
11359 (define_insn "*ashlsi3_cmp"
11360   [(set (reg 17)
11361         (compare
11362           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11363                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11364           (const_int 0)))
11365    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11366         (ashift:SI (match_dup 1) (match_dup 2)))]
11367   "ix86_match_ccmode (insn, CCGOCmode)
11368    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11369 {
11370   switch (get_attr_type (insn))
11371     {
11372     case TYPE_ALU:
11373       if (operands[2] != const1_rtx)
11374         abort ();
11375       return "add{l}\t{%0, %0|%0, %0}";
11376
11377     default:
11378       if (REG_P (operands[2]))
11379         return "sal{l}\t{%b2, %0|%0, %b2}";
11380       else if (GET_CODE (operands[2]) == CONST_INT
11381                && INTVAL (operands[2]) == 1
11382                && (TARGET_SHIFT1 || optimize_size))
11383         return "sal{l}\t%0";
11384       else
11385         return "sal{l}\t{%2, %0|%0, %2}";
11386     }
11387 }
11388   [(set (attr "type")
11389      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11390                           (const_int 0))
11391                       (match_operand 0 "register_operand" ""))
11392                  (match_operand 2 "const1_operand" ""))
11393               (const_string "alu")
11394            ]
11395            (const_string "ishift")))
11396    (set_attr "mode" "SI")])
11397
11398 (define_insn "*ashlsi3_cmp_zext"
11399   [(set (reg 17)
11400         (compare
11401           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11402                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11403           (const_int 0)))
11404    (set (match_operand:DI 0 "register_operand" "=r")
11405         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11406   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11407    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11408 {
11409   switch (get_attr_type (insn))
11410     {
11411     case TYPE_ALU:
11412       if (operands[2] != const1_rtx)
11413         abort ();
11414       return "add{l}\t{%k0, %k0|%k0, %k0}";
11415
11416     default:
11417       if (REG_P (operands[2]))
11418         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11419       else if (GET_CODE (operands[2]) == CONST_INT
11420                && INTVAL (operands[2]) == 1
11421                && (TARGET_SHIFT1 || optimize_size))
11422         return "sal{l}\t%k0";
11423       else
11424         return "sal{l}\t{%2, %k0|%k0, %2}";
11425     }
11426 }
11427   [(set (attr "type")
11428      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11429                      (const_int 0))
11430                  (match_operand 2 "const1_operand" ""))
11431               (const_string "alu")
11432            ]
11433            (const_string "ishift")))
11434    (set_attr "mode" "SI")])
11435
11436 (define_expand "ashlhi3"
11437   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11438         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11439                    (match_operand:QI 2 "nonmemory_operand" "")))
11440    (clobber (reg:CC 17))]
11441   "TARGET_HIMODE_MATH"
11442   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11443
11444 (define_insn "*ashlhi3_1_lea"
11445   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11446         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r")
11447                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11448    (clobber (reg:CC 17))]
11449   "!TARGET_PARTIAL_REG_STALL
11450    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11451 {
11452   switch (get_attr_type (insn))
11453     {
11454     case TYPE_LEA:
11455       return "#";
11456     case TYPE_ALU:
11457       if (operands[2] != const1_rtx)
11458         abort ();
11459       return "add{w}\t{%0, %0|%0, %0}";
11460
11461     default:
11462       if (REG_P (operands[2]))
11463         return "sal{w}\t{%b2, %0|%0, %b2}";
11464       else if (GET_CODE (operands[2]) == CONST_INT
11465                && INTVAL (operands[2]) == 1
11466                && (TARGET_SHIFT1 || optimize_size))
11467         return "sal{w}\t%0";
11468       else
11469         return "sal{w}\t{%2, %0|%0, %2}";
11470     }
11471 }
11472   [(set (attr "type")
11473      (cond [(eq_attr "alternative" "1")
11474               (const_string "lea")
11475             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11476                           (const_int 0))
11477                       (match_operand 0 "register_operand" ""))
11478                  (match_operand 2 "const1_operand" ""))
11479               (const_string "alu")
11480            ]
11481            (const_string "ishift")))
11482    (set_attr "mode" "HI,SI")])
11483
11484 (define_insn "*ashlhi3_1"
11485   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11486         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11487                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11488    (clobber (reg:CC 17))]
11489   "TARGET_PARTIAL_REG_STALL
11490    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11491 {
11492   switch (get_attr_type (insn))
11493     {
11494     case TYPE_ALU:
11495       if (operands[2] != const1_rtx)
11496         abort ();
11497       return "add{w}\t{%0, %0|%0, %0}";
11498
11499     default:
11500       if (REG_P (operands[2]))
11501         return "sal{w}\t{%b2, %0|%0, %b2}";
11502       else if (GET_CODE (operands[2]) == CONST_INT
11503                && INTVAL (operands[2]) == 1
11504                && (TARGET_SHIFT1 || optimize_size))
11505         return "sal{w}\t%0";
11506       else
11507         return "sal{w}\t{%2, %0|%0, %2}";
11508     }
11509 }
11510   [(set (attr "type")
11511      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11512                           (const_int 0))
11513                       (match_operand 0 "register_operand" ""))
11514                  (match_operand 2 "const1_operand" ""))
11515               (const_string "alu")
11516            ]
11517            (const_string "ishift")))
11518    (set_attr "mode" "HI")])
11519
11520 ;; This pattern can't accept a variable shift count, since shifts by
11521 ;; zero don't affect the flags.  We assume that shifts by constant
11522 ;; zero are optimized away.
11523 (define_insn "*ashlhi3_cmp"
11524   [(set (reg 17)
11525         (compare
11526           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11527                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11528           (const_int 0)))
11529    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11530         (ashift:HI (match_dup 1) (match_dup 2)))]
11531   "ix86_match_ccmode (insn, CCGOCmode)
11532    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11533 {
11534   switch (get_attr_type (insn))
11535     {
11536     case TYPE_ALU:
11537       if (operands[2] != const1_rtx)
11538         abort ();
11539       return "add{w}\t{%0, %0|%0, %0}";
11540
11541     default:
11542       if (REG_P (operands[2]))
11543         return "sal{w}\t{%b2, %0|%0, %b2}";
11544       else if (GET_CODE (operands[2]) == CONST_INT
11545                && INTVAL (operands[2]) == 1
11546                && (TARGET_SHIFT1 || optimize_size))
11547         return "sal{w}\t%0";
11548       else
11549         return "sal{w}\t{%2, %0|%0, %2}";
11550     }
11551 }
11552   [(set (attr "type")
11553      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11554                           (const_int 0))
11555                       (match_operand 0 "register_operand" ""))
11556                  (match_operand 2 "const1_operand" ""))
11557               (const_string "alu")
11558            ]
11559            (const_string "ishift")))
11560    (set_attr "mode" "HI")])
11561
11562 (define_expand "ashlqi3"
11563   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11564         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11565                    (match_operand:QI 2 "nonmemory_operand" "")))
11566    (clobber (reg:CC 17))]
11567   "TARGET_QIMODE_MATH"
11568   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11569
11570 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11571
11572 (define_insn "*ashlqi3_1_lea"
11573   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11574         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,r")
11575                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11576    (clobber (reg:CC 17))]
11577   "!TARGET_PARTIAL_REG_STALL
11578    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11579 {
11580   switch (get_attr_type (insn))
11581     {
11582     case TYPE_LEA:
11583       return "#";
11584     case TYPE_ALU:
11585       if (operands[2] != const1_rtx)
11586         abort ();
11587       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11588         return "add{l}\t{%k0, %k0|%k0, %k0}";
11589       else
11590         return "add{b}\t{%0, %0|%0, %0}";
11591
11592     default:
11593       if (REG_P (operands[2]))
11594         {
11595           if (get_attr_mode (insn) == MODE_SI)
11596             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11597           else
11598             return "sal{b}\t{%b2, %0|%0, %b2}";
11599         }
11600       else if (GET_CODE (operands[2]) == CONST_INT
11601                && INTVAL (operands[2]) == 1
11602                && (TARGET_SHIFT1 || optimize_size))
11603         {
11604           if (get_attr_mode (insn) == MODE_SI)
11605             return "sal{l}\t%0";
11606           else
11607             return "sal{b}\t%0";
11608         }
11609       else
11610         {
11611           if (get_attr_mode (insn) == MODE_SI)
11612             return "sal{l}\t{%2, %k0|%k0, %2}";
11613           else
11614             return "sal{b}\t{%2, %0|%0, %2}";
11615         }
11616     }
11617 }
11618   [(set (attr "type")
11619      (cond [(eq_attr "alternative" "2")
11620               (const_string "lea")
11621             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11622                           (const_int 0))
11623                       (match_operand 0 "register_operand" ""))
11624                  (match_operand 2 "const1_operand" ""))
11625               (const_string "alu")
11626            ]
11627            (const_string "ishift")))
11628    (set_attr "mode" "QI,SI,SI")])
11629
11630 (define_insn "*ashlqi3_1"
11631   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11632         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11633                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11634    (clobber (reg:CC 17))]
11635   "TARGET_PARTIAL_REG_STALL
11636    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11637 {
11638   switch (get_attr_type (insn))
11639     {
11640     case TYPE_ALU:
11641       if (operands[2] != const1_rtx)
11642         abort ();
11643       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11644         return "add{l}\t{%k0, %k0|%k0, %k0}";
11645       else
11646         return "add{b}\t{%0, %0|%0, %0}";
11647
11648     default:
11649       if (REG_P (operands[2]))
11650         {
11651           if (get_attr_mode (insn) == MODE_SI)
11652             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11653           else
11654             return "sal{b}\t{%b2, %0|%0, %b2}";
11655         }
11656       else if (GET_CODE (operands[2]) == CONST_INT
11657                && INTVAL (operands[2]) == 1
11658                && (TARGET_SHIFT1 || optimize_size))
11659         {
11660           if (get_attr_mode (insn) == MODE_SI)
11661             return "sal{l}\t%0";
11662           else
11663             return "sal{b}\t%0";
11664         }
11665       else
11666         {
11667           if (get_attr_mode (insn) == MODE_SI)
11668             return "sal{l}\t{%2, %k0|%k0, %2}";
11669           else
11670             return "sal{b}\t{%2, %0|%0, %2}";
11671         }
11672     }
11673 }
11674   [(set (attr "type")
11675      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11676                           (const_int 0))
11677                       (match_operand 0 "register_operand" ""))
11678                  (match_operand 2 "const1_operand" ""))
11679               (const_string "alu")
11680            ]
11681            (const_string "ishift")))
11682    (set_attr "mode" "QI,SI")])
11683
11684 ;; This pattern can't accept a variable shift count, since shifts by
11685 ;; zero don't affect the flags.  We assume that shifts by constant
11686 ;; zero are optimized away.
11687 (define_insn "*ashlqi3_cmp"
11688   [(set (reg 17)
11689         (compare
11690           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11691                      (match_operand:QI 2 "const_int_1_31_operand" "I"))
11692           (const_int 0)))
11693    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11694         (ashift:QI (match_dup 1) (match_dup 2)))]
11695   "ix86_match_ccmode (insn, CCGOCmode)
11696    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11697 {
11698   switch (get_attr_type (insn))
11699     {
11700     case TYPE_ALU:
11701       if (operands[2] != const1_rtx)
11702         abort ();
11703       return "add{b}\t{%0, %0|%0, %0}";
11704
11705     default:
11706       if (REG_P (operands[2]))
11707         return "sal{b}\t{%b2, %0|%0, %b2}";
11708       else if (GET_CODE (operands[2]) == CONST_INT
11709                && INTVAL (operands[2]) == 1
11710                && (TARGET_SHIFT1 || optimize_size))
11711         return "sal{b}\t%0";
11712       else
11713         return "sal{b}\t{%2, %0|%0, %2}";
11714     }
11715 }
11716   [(set (attr "type")
11717      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11718                           (const_int 0))
11719                       (match_operand 0 "register_operand" ""))
11720                  (match_operand 2 "const1_operand" ""))
11721               (const_string "alu")
11722            ]
11723            (const_string "ishift")))
11724    (set_attr "mode" "QI")])
11725
11726 ;; See comment above `ashldi3' about how this works.
11727
11728 (define_expand "ashrdi3"
11729   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
11730                    (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11731                                 (match_operand:QI 2 "nonmemory_operand" "")))
11732               (clobber (reg:CC 17))])]
11733   ""
11734 {
11735   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
11736     {
11737       emit_insn (gen_ashrdi3_1 (operands[0], operands[1], operands[2]));
11738       DONE;
11739     }
11740   ix86_expand_binary_operator (ASHIFTRT, DImode, operands);
11741   DONE;
11742 })
11743
11744 (define_insn "ashrdi3_63_rex64"
11745   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11746         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11747                      (match_operand:DI 2 "const_int_operand" "i,i")))
11748    (clobber (reg:CC 17))]
11749   "TARGET_64BIT && INTVAL (operands[2]) == 63 && (TARGET_USE_CLTD || optimize_size)
11750    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11751   "@
11752    {cqto|cqo}
11753    sar{q}\t{%2, %0|%0, %2}"
11754   [(set_attr "type" "imovx,ishift")
11755    (set_attr "prefix_0f" "0,*")
11756    (set_attr "length_immediate" "0,*")
11757    (set_attr "modrm" "0,1")
11758    (set_attr "mode" "DI")])
11759
11760 (define_insn "*ashrdi3_1_one_bit_rex64"
11761   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11762         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11763                      (match_operand:QI 2 "const_int_1_operand" "")))
11764    (clobber (reg:CC 17))]
11765   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11766    && (TARGET_SHIFT1 || optimize_size)"
11767   "sar{q}\t%0"
11768   [(set_attr "type" "ishift")
11769    (set (attr "length") 
11770      (if_then_else (match_operand:DI 0 "register_operand" "") 
11771         (const_string "2")
11772         (const_string "*")))])
11773
11774 (define_insn "*ashrdi3_1_rex64"
11775   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11776         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11777                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11778    (clobber (reg:CC 17))]
11779   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11780   "@
11781    sar{q}\t{%2, %0|%0, %2}
11782    sar{q}\t{%b2, %0|%0, %b2}"
11783   [(set_attr "type" "ishift")
11784    (set_attr "mode" "DI")])
11785
11786 ;; This pattern can't accept a variable shift count, since shifts by
11787 ;; zero don't affect the flags.  We assume that shifts by constant
11788 ;; zero are optimized away.
11789 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11790   [(set (reg 17)
11791         (compare
11792           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11793                        (match_operand:QI 2 "const_int_1_operand" ""))
11794           (const_int 0)))
11795    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11796         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11797   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11798    && (TARGET_SHIFT1 || optimize_size)
11799    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11800   "sar{q}\t%0"
11801   [(set_attr "type" "ishift")
11802    (set (attr "length") 
11803      (if_then_else (match_operand:DI 0 "register_operand" "") 
11804         (const_string "2")
11805         (const_string "*")))])
11806
11807 ;; This pattern can't accept a variable shift count, since shifts by
11808 ;; zero don't affect the flags.  We assume that shifts by constant
11809 ;; zero are optimized away.
11810 (define_insn "*ashrdi3_cmp_rex64"
11811   [(set (reg 17)
11812         (compare
11813           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11814                        (match_operand:QI 2 "const_int_operand" "n"))
11815           (const_int 0)))
11816    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11817         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11818   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11819    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11820   "sar{q}\t{%2, %0|%0, %2}"
11821   [(set_attr "type" "ishift")
11822    (set_attr "mode" "DI")])
11823
11824
11825 (define_insn "ashrdi3_1"
11826   [(set (match_operand:DI 0 "register_operand" "=r")
11827         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11828                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11829    (clobber (match_scratch:SI 3 "=&r"))
11830    (clobber (reg:CC 17))]
11831   "!TARGET_64BIT && TARGET_CMOVE"
11832   "#"
11833   [(set_attr "type" "multi")])
11834
11835 (define_insn "*ashrdi3_2"
11836   [(set (match_operand:DI 0 "register_operand" "=r")
11837         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11838                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11839    (clobber (reg:CC 17))]
11840   "!TARGET_64BIT"
11841   "#"
11842   [(set_attr "type" "multi")])
11843
11844 (define_split
11845   [(set (match_operand:DI 0 "register_operand" "")
11846         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11847                      (match_operand:QI 2 "nonmemory_operand" "")))
11848    (clobber (match_scratch:SI 3 ""))
11849    (clobber (reg:CC 17))]
11850   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
11851   [(const_int 0)]
11852   "ix86_split_ashrdi (operands, operands[3]); DONE;")
11853
11854 (define_split
11855   [(set (match_operand:DI 0 "register_operand" "")
11856         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11857                      (match_operand:QI 2 "nonmemory_operand" "")))
11858    (clobber (reg:CC 17))]
11859   "!TARGET_64BIT && reload_completed"
11860   [(const_int 0)]
11861   "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
11862
11863 (define_insn "x86_shrd_1"
11864   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11865         (ior:SI (ashiftrt:SI (match_dup 0)
11866                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11867                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11868                   (minus:QI (const_int 32) (match_dup 2)))))
11869    (clobber (reg:CC 17))]
11870   ""
11871   "@
11872    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11873    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11874   [(set_attr "type" "ishift")
11875    (set_attr "prefix_0f" "1")
11876    (set_attr "pent_pair" "np")
11877    (set_attr "ppro_uops" "few")
11878    (set_attr "mode" "SI")])
11879
11880 (define_expand "x86_shift_adj_3"
11881   [(use (match_operand:SI 0 "register_operand" ""))
11882    (use (match_operand:SI 1 "register_operand" ""))
11883    (use (match_operand:QI 2 "register_operand" ""))]
11884   ""
11885 {
11886   rtx label = gen_label_rtx ();
11887   rtx tmp;
11888
11889   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11890
11891   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11892   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11893   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11894                               gen_rtx_LABEL_REF (VOIDmode, label),
11895                               pc_rtx);
11896   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11897   JUMP_LABEL (tmp) = label;
11898
11899   emit_move_insn (operands[0], operands[1]);
11900   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11901
11902   emit_label (label);
11903   LABEL_NUSES (label) = 1;
11904
11905   DONE;
11906 })
11907
11908 (define_insn "ashrsi3_31"
11909   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11910         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11911                      (match_operand:SI 2 "const_int_operand" "i,i")))
11912    (clobber (reg:CC 17))]
11913   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11914    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11915   "@
11916    {cltd|cdq}
11917    sar{l}\t{%2, %0|%0, %2}"
11918   [(set_attr "type" "imovx,ishift")
11919    (set_attr "prefix_0f" "0,*")
11920    (set_attr "length_immediate" "0,*")
11921    (set_attr "modrm" "0,1")
11922    (set_attr "mode" "SI")])
11923
11924 (define_insn "*ashrsi3_31_zext"
11925   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11926         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11927                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11928    (clobber (reg:CC 17))]
11929   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11930    && INTVAL (operands[2]) == 31
11931    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11932   "@
11933    {cltd|cdq}
11934    sar{l}\t{%2, %k0|%k0, %2}"
11935   [(set_attr "type" "imovx,ishift")
11936    (set_attr "prefix_0f" "0,*")
11937    (set_attr "length_immediate" "0,*")
11938    (set_attr "modrm" "0,1")
11939    (set_attr "mode" "SI")])
11940
11941 (define_expand "ashrsi3"
11942   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11943         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11944                      (match_operand:QI 2 "nonmemory_operand" "")))
11945    (clobber (reg:CC 17))]
11946   ""
11947   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11948
11949 (define_insn "*ashrsi3_1_one_bit"
11950   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11951         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11952                      (match_operand:QI 2 "const_int_1_operand" "")))
11953    (clobber (reg:CC 17))]
11954   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11955    && (TARGET_SHIFT1 || optimize_size)"
11956   "sar{l}\t%0"
11957   [(set_attr "type" "ishift")
11958    (set (attr "length") 
11959      (if_then_else (match_operand:SI 0 "register_operand" "") 
11960         (const_string "2")
11961         (const_string "*")))])
11962
11963 (define_insn "*ashrsi3_1_one_bit_zext"
11964   [(set (match_operand:DI 0 "register_operand" "=r")
11965         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11966                                      (match_operand:QI 2 "const_int_1_operand" ""))))
11967    (clobber (reg:CC 17))]
11968   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11969    && (TARGET_SHIFT1 || optimize_size)"
11970   "sar{l}\t%k0"
11971   [(set_attr "type" "ishift")
11972    (set_attr "length" "2")])
11973
11974 (define_insn "*ashrsi3_1"
11975   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11976         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11977                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11978    (clobber (reg:CC 17))]
11979   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11980   "@
11981    sar{l}\t{%2, %0|%0, %2}
11982    sar{l}\t{%b2, %0|%0, %b2}"
11983   [(set_attr "type" "ishift")
11984    (set_attr "mode" "SI")])
11985
11986 (define_insn "*ashrsi3_1_zext"
11987   [(set (match_operand:DI 0 "register_operand" "=r,r")
11988         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11989                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11990    (clobber (reg:CC 17))]
11991   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11992   "@
11993    sar{l}\t{%2, %k0|%k0, %2}
11994    sar{l}\t{%b2, %k0|%k0, %b2}"
11995   [(set_attr "type" "ishift")
11996    (set_attr "mode" "SI")])
11997
11998 ;; This pattern can't accept a variable shift count, since shifts by
11999 ;; zero don't affect the flags.  We assume that shifts by constant
12000 ;; zero are optimized away.
12001 (define_insn "*ashrsi3_one_bit_cmp"
12002   [(set (reg 17)
12003         (compare
12004           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12005                        (match_operand:QI 2 "const_int_1_operand" ""))
12006           (const_int 0)))
12007    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12008         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12009   "ix86_match_ccmode (insn, CCGOCmode)
12010    && (TARGET_SHIFT1 || optimize_size)
12011    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12012   "sar{l}\t%0"
12013   [(set_attr "type" "ishift")
12014    (set (attr "length") 
12015      (if_then_else (match_operand:SI 0 "register_operand" "") 
12016         (const_string "2")
12017         (const_string "*")))])
12018
12019 (define_insn "*ashrsi3_one_bit_cmp_zext"
12020   [(set (reg 17)
12021         (compare
12022           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12023                        (match_operand:QI 2 "const_int_1_operand" ""))
12024           (const_int 0)))
12025    (set (match_operand:DI 0 "register_operand" "=r")
12026         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12027   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
12028    && (TARGET_SHIFT1 || optimize_size)
12029    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12030   "sar{l}\t%k0"
12031   [(set_attr "type" "ishift")
12032    (set_attr "length" "2")])
12033
12034 ;; This pattern can't accept a variable shift count, since shifts by
12035 ;; zero don't affect the flags.  We assume that shifts by constant
12036 ;; zero are optimized away.
12037 (define_insn "*ashrsi3_cmp"
12038   [(set (reg 17)
12039         (compare
12040           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12041                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12042           (const_int 0)))
12043    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12044         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12045   "ix86_match_ccmode (insn, CCGOCmode)
12046    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12047   "sar{l}\t{%2, %0|%0, %2}"
12048   [(set_attr "type" "ishift")
12049    (set_attr "mode" "SI")])
12050
12051 (define_insn "*ashrsi3_cmp_zext"
12052   [(set (reg 17)
12053         (compare
12054           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12055                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12056           (const_int 0)))
12057    (set (match_operand:DI 0 "register_operand" "=r")
12058         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12059   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12060    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12061   "sar{l}\t{%2, %k0|%k0, %2}"
12062   [(set_attr "type" "ishift")
12063    (set_attr "mode" "SI")])
12064
12065 (define_expand "ashrhi3"
12066   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12067         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12068                      (match_operand:QI 2 "nonmemory_operand" "")))
12069    (clobber (reg:CC 17))]
12070   "TARGET_HIMODE_MATH"
12071   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12072
12073 (define_insn "*ashrhi3_1_one_bit"
12074   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12075         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12076                      (match_operand:QI 2 "const_int_1_operand" "")))
12077    (clobber (reg:CC 17))]
12078   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12079    && (TARGET_SHIFT1 || optimize_size)"
12080   "sar{w}\t%0"
12081   [(set_attr "type" "ishift")
12082    (set (attr "length") 
12083      (if_then_else (match_operand 0 "register_operand" "") 
12084         (const_string "2")
12085         (const_string "*")))])
12086
12087 (define_insn "*ashrhi3_1"
12088   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12089         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12090                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12091    (clobber (reg:CC 17))]
12092   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12093   "@
12094    sar{w}\t{%2, %0|%0, %2}
12095    sar{w}\t{%b2, %0|%0, %b2}"
12096   [(set_attr "type" "ishift")
12097    (set_attr "mode" "HI")])
12098
12099 ;; This pattern can't accept a variable shift count, since shifts by
12100 ;; zero don't affect the flags.  We assume that shifts by constant
12101 ;; zero are optimized away.
12102 (define_insn "*ashrhi3_one_bit_cmp"
12103   [(set (reg 17)
12104         (compare
12105           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12106                        (match_operand:QI 2 "const_int_1_operand" ""))
12107           (const_int 0)))
12108    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12109         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12110   "ix86_match_ccmode (insn, CCGOCmode)
12111    && (TARGET_SHIFT1 || optimize_size)
12112    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12113   "sar{w}\t%0"
12114   [(set_attr "type" "ishift")
12115    (set (attr "length") 
12116      (if_then_else (match_operand 0 "register_operand" "") 
12117         (const_string "2")
12118         (const_string "*")))])
12119
12120 ;; This pattern can't accept a variable shift count, since shifts by
12121 ;; zero don't affect the flags.  We assume that shifts by constant
12122 ;; zero are optimized away.
12123 (define_insn "*ashrhi3_cmp"
12124   [(set (reg 17)
12125         (compare
12126           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12127                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12128           (const_int 0)))
12129    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12130         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12131   "ix86_match_ccmode (insn, CCGOCmode)
12132    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12133   "sar{w}\t{%2, %0|%0, %2}"
12134   [(set_attr "type" "ishift")
12135    (set_attr "mode" "HI")])
12136
12137 (define_expand "ashrqi3"
12138   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12139         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12140                      (match_operand:QI 2 "nonmemory_operand" "")))
12141    (clobber (reg:CC 17))]
12142   "TARGET_QIMODE_MATH"
12143   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12144
12145 (define_insn "*ashrqi3_1_one_bit"
12146   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12147         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12148                      (match_operand:QI 2 "const_int_1_operand" "")))
12149    (clobber (reg:CC 17))]
12150   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12151    && (TARGET_SHIFT1 || optimize_size)"
12152   "sar{b}\t%0"
12153   [(set_attr "type" "ishift")
12154    (set (attr "length") 
12155      (if_then_else (match_operand 0 "register_operand" "") 
12156         (const_string "2")
12157         (const_string "*")))])
12158
12159 (define_insn "*ashrqi3_1_one_bit_slp"
12160   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12161         (ashiftrt:QI (match_dup 0)
12162                      (match_operand:QI 1 "const_int_1_operand" "")))
12163    (clobber (reg:CC 17))]
12164   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12165    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
12166    && (TARGET_SHIFT1 || optimize_size)"
12167   "sar{b}\t%0"
12168   [(set_attr "type" "ishift1")
12169    (set (attr "length") 
12170      (if_then_else (match_operand 0 "register_operand" "") 
12171         (const_string "2")
12172         (const_string "*")))])
12173
12174 (define_insn "*ashrqi3_1"
12175   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12176         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12177                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12178    (clobber (reg:CC 17))]
12179   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12180   "@
12181    sar{b}\t{%2, %0|%0, %2}
12182    sar{b}\t{%b2, %0|%0, %b2}"
12183   [(set_attr "type" "ishift")
12184    (set_attr "mode" "QI")])
12185
12186 (define_insn "*ashrqi3_1_slp"
12187   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12188         (ashiftrt:QI (match_dup 0)
12189                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12190    (clobber (reg:CC 17))]
12191   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12192    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12193   "@
12194    sar{b}\t{%1, %0|%0, %1}
12195    sar{b}\t{%b1, %0|%0, %b1}"
12196   [(set_attr "type" "ishift1")
12197    (set_attr "mode" "QI")])
12198
12199 ;; This pattern can't accept a variable shift count, since shifts by
12200 ;; zero don't affect the flags.  We assume that shifts by constant
12201 ;; zero are optimized away.
12202 (define_insn "*ashrqi3_one_bit_cmp"
12203   [(set (reg 17)
12204         (compare
12205           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12206                        (match_operand:QI 2 "const_int_1_operand" "I"))
12207           (const_int 0)))
12208    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12209         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12210   "ix86_match_ccmode (insn, CCGOCmode)
12211    && (TARGET_SHIFT1 || optimize_size)
12212    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12213   "sar{b}\t%0"
12214   [(set_attr "type" "ishift")
12215    (set (attr "length") 
12216      (if_then_else (match_operand 0 "register_operand" "") 
12217         (const_string "2")
12218         (const_string "*")))])
12219
12220 ;; This pattern can't accept a variable shift count, since shifts by
12221 ;; zero don't affect the flags.  We assume that shifts by constant
12222 ;; zero are optimized away.
12223 (define_insn "*ashrqi3_cmp"
12224   [(set (reg 17)
12225         (compare
12226           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12227                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12228           (const_int 0)))
12229    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12230         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12231   "ix86_match_ccmode (insn, CCGOCmode)
12232    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12233   "sar{b}\t{%2, %0|%0, %2}"
12234   [(set_attr "type" "ishift")
12235    (set_attr "mode" "QI")])
12236 \f
12237 ;; Logical shift instructions
12238
12239 ;; See comment above `ashldi3' about how this works.
12240
12241 (define_expand "lshrdi3"
12242   [(parallel [(set (match_operand:DI 0 "shiftdi_operand" "")
12243                    (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12244                                 (match_operand:QI 2 "nonmemory_operand" "")))
12245               (clobber (reg:CC 17))])]
12246   ""
12247 {
12248   if (!TARGET_64BIT && TARGET_CMOVE && ! immediate_operand (operands[2], QImode))
12249     {
12250       emit_insn (gen_lshrdi3_1 (operands[0], operands[1], operands[2]));
12251       DONE;
12252     }
12253   ix86_expand_binary_operator (LSHIFTRT, DImode, operands);
12254   DONE;
12255 })
12256
12257 (define_insn "*lshrdi3_1_one_bit_rex64"
12258   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12259         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12260                      (match_operand:QI 2 "const_int_1_operand" "")))
12261    (clobber (reg:CC 17))]
12262   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12263    && (TARGET_SHIFT1 || optimize_size)"
12264   "shr{q}\t%0"
12265   [(set_attr "type" "ishift")
12266    (set (attr "length") 
12267      (if_then_else (match_operand:DI 0 "register_operand" "") 
12268         (const_string "2")
12269         (const_string "*")))])
12270
12271 (define_insn "*lshrdi3_1_rex64"
12272   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12273         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12274                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12275    (clobber (reg:CC 17))]
12276   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12277   "@
12278    shr{q}\t{%2, %0|%0, %2}
12279    shr{q}\t{%b2, %0|%0, %b2}"
12280   [(set_attr "type" "ishift")
12281    (set_attr "mode" "DI")])
12282
12283 ;; This pattern can't accept a variable shift count, since shifts by
12284 ;; zero don't affect the flags.  We assume that shifts by constant
12285 ;; zero are optimized away.
12286 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12287   [(set (reg 17)
12288         (compare
12289           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12290                        (match_operand:QI 2 "const_int_1_operand" ""))
12291           (const_int 0)))
12292    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12293         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12294   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12295    && (TARGET_SHIFT1 || optimize_size)
12296    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12297   "shr{q}\t%0"
12298   [(set_attr "type" "ishift")
12299    (set (attr "length") 
12300      (if_then_else (match_operand:DI 0 "register_operand" "") 
12301         (const_string "2")
12302         (const_string "*")))])
12303
12304 ;; This pattern can't accept a variable shift count, since shifts by
12305 ;; zero don't affect the flags.  We assume that shifts by constant
12306 ;; zero are optimized away.
12307 (define_insn "*lshrdi3_cmp_rex64"
12308   [(set (reg 17)
12309         (compare
12310           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12311                        (match_operand:QI 2 "const_int_operand" "e"))
12312           (const_int 0)))
12313    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12314         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12315   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12316    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12317   "shr{q}\t{%2, %0|%0, %2}"
12318   [(set_attr "type" "ishift")
12319    (set_attr "mode" "DI")])
12320
12321 (define_insn "lshrdi3_1"
12322   [(set (match_operand:DI 0 "register_operand" "=r")
12323         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12324                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12325    (clobber (match_scratch:SI 3 "=&r"))
12326    (clobber (reg:CC 17))]
12327   "!TARGET_64BIT && TARGET_CMOVE"
12328   "#"
12329   [(set_attr "type" "multi")])
12330
12331 (define_insn "*lshrdi3_2"
12332   [(set (match_operand:DI 0 "register_operand" "=r")
12333         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12334                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12335    (clobber (reg:CC 17))]
12336   "!TARGET_64BIT"
12337   "#"
12338   [(set_attr "type" "multi")])
12339
12340 (define_split 
12341   [(set (match_operand:DI 0 "register_operand" "")
12342         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12343                      (match_operand:QI 2 "nonmemory_operand" "")))
12344    (clobber (match_scratch:SI 3 ""))
12345    (clobber (reg:CC 17))]
12346   "!TARGET_64BIT && TARGET_CMOVE && reload_completed"
12347   [(const_int 0)]
12348   "ix86_split_lshrdi (operands, operands[3]); DONE;")
12349
12350 (define_split 
12351   [(set (match_operand:DI 0 "register_operand" "")
12352         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12353                      (match_operand:QI 2 "nonmemory_operand" "")))
12354    (clobber (reg:CC 17))]
12355   "!TARGET_64BIT && reload_completed"
12356   [(const_int 0)]
12357   "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
12358
12359 (define_expand "lshrsi3"
12360   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12361         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12362                      (match_operand:QI 2 "nonmemory_operand" "")))
12363    (clobber (reg:CC 17))]
12364   ""
12365   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12366
12367 (define_insn "*lshrsi3_1_one_bit"
12368   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12369         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12370                      (match_operand:QI 2 "const_int_1_operand" "")))
12371    (clobber (reg:CC 17))]
12372   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12373    && (TARGET_SHIFT1 || optimize_size)"
12374   "shr{l}\t%0"
12375   [(set_attr "type" "ishift")
12376    (set (attr "length") 
12377      (if_then_else (match_operand:SI 0 "register_operand" "") 
12378         (const_string "2")
12379         (const_string "*")))])
12380
12381 (define_insn "*lshrsi3_1_one_bit_zext"
12382   [(set (match_operand:DI 0 "register_operand" "=r")
12383         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12384                      (match_operand:QI 2 "const_int_1_operand" "")))
12385    (clobber (reg:CC 17))]
12386   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12387    && (TARGET_SHIFT1 || optimize_size)"
12388   "shr{l}\t%k0"
12389   [(set_attr "type" "ishift")
12390    (set_attr "length" "2")])
12391
12392 (define_insn "*lshrsi3_1"
12393   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12394         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12395                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12396    (clobber (reg:CC 17))]
12397   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12398   "@
12399    shr{l}\t{%2, %0|%0, %2}
12400    shr{l}\t{%b2, %0|%0, %b2}"
12401   [(set_attr "type" "ishift")
12402    (set_attr "mode" "SI")])
12403
12404 (define_insn "*lshrsi3_1_zext"
12405   [(set (match_operand:DI 0 "register_operand" "=r,r")
12406         (zero_extend:DI
12407           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12408                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12409    (clobber (reg:CC 17))]
12410   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12411   "@
12412    shr{l}\t{%2, %k0|%k0, %2}
12413    shr{l}\t{%b2, %k0|%k0, %b2}"
12414   [(set_attr "type" "ishift")
12415    (set_attr "mode" "SI")])
12416
12417 ;; This pattern can't accept a variable shift count, since shifts by
12418 ;; zero don't affect the flags.  We assume that shifts by constant
12419 ;; zero are optimized away.
12420 (define_insn "*lshrsi3_one_bit_cmp"
12421   [(set (reg 17)
12422         (compare
12423           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12424                        (match_operand:QI 2 "const_int_1_operand" ""))
12425           (const_int 0)))
12426    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12427         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12428   "ix86_match_ccmode (insn, CCGOCmode)
12429    && (TARGET_SHIFT1 || optimize_size)
12430    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12431   "shr{l}\t%0"
12432   [(set_attr "type" "ishift")
12433    (set (attr "length") 
12434      (if_then_else (match_operand:SI 0 "register_operand" "") 
12435         (const_string "2")
12436         (const_string "*")))])
12437
12438 (define_insn "*lshrsi3_cmp_one_bit_zext"
12439   [(set (reg 17)
12440         (compare
12441           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12442                        (match_operand:QI 2 "const_int_1_operand" ""))
12443           (const_int 0)))
12444    (set (match_operand:DI 0 "register_operand" "=r")
12445         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12446   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12447    && (TARGET_SHIFT1 || optimize_size)
12448    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12449   "shr{l}\t%k0"
12450   [(set_attr "type" "ishift")
12451    (set_attr "length" "2")])
12452
12453 ;; This pattern can't accept a variable shift count, since shifts by
12454 ;; zero don't affect the flags.  We assume that shifts by constant
12455 ;; zero are optimized away.
12456 (define_insn "*lshrsi3_cmp"
12457   [(set (reg 17)
12458         (compare
12459           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12460                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12461           (const_int 0)))
12462    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12463         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12464   "ix86_match_ccmode (insn, CCGOCmode)
12465    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12466   "shr{l}\t{%2, %0|%0, %2}"
12467   [(set_attr "type" "ishift")
12468    (set_attr "mode" "SI")])
12469
12470 (define_insn "*lshrsi3_cmp_zext"
12471   [(set (reg 17)
12472         (compare
12473           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12474                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12475           (const_int 0)))
12476    (set (match_operand:DI 0 "register_operand" "=r")
12477         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12478   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12479    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12480   "shr{l}\t{%2, %k0|%k0, %2}"
12481   [(set_attr "type" "ishift")
12482    (set_attr "mode" "SI")])
12483
12484 (define_expand "lshrhi3"
12485   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12486         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12487                      (match_operand:QI 2 "nonmemory_operand" "")))
12488    (clobber (reg:CC 17))]
12489   "TARGET_HIMODE_MATH"
12490   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12491
12492 (define_insn "*lshrhi3_1_one_bit"
12493   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12494         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12495                      (match_operand:QI 2 "const_int_1_operand" "")))
12496    (clobber (reg:CC 17))]
12497   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12498    && (TARGET_SHIFT1 || optimize_size)"
12499   "shr{w}\t%0"
12500   [(set_attr "type" "ishift")
12501    (set (attr "length") 
12502      (if_then_else (match_operand 0 "register_operand" "") 
12503         (const_string "2")
12504         (const_string "*")))])
12505
12506 (define_insn "*lshrhi3_1"
12507   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12508         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12509                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12510    (clobber (reg:CC 17))]
12511   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12512   "@
12513    shr{w}\t{%2, %0|%0, %2}
12514    shr{w}\t{%b2, %0|%0, %b2}"
12515   [(set_attr "type" "ishift")
12516    (set_attr "mode" "HI")])
12517
12518 ;; This pattern can't accept a variable shift count, since shifts by
12519 ;; zero don't affect the flags.  We assume that shifts by constant
12520 ;; zero are optimized away.
12521 (define_insn "*lshrhi3_one_bit_cmp"
12522   [(set (reg 17)
12523         (compare
12524           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12525                        (match_operand:QI 2 "const_int_1_operand" ""))
12526           (const_int 0)))
12527    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12528         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12529   "ix86_match_ccmode (insn, CCGOCmode)
12530    && (TARGET_SHIFT1 || optimize_size)
12531    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12532   "shr{w}\t%0"
12533   [(set_attr "type" "ishift")
12534    (set (attr "length") 
12535      (if_then_else (match_operand:SI 0 "register_operand" "") 
12536         (const_string "2")
12537         (const_string "*")))])
12538
12539 ;; This pattern can't accept a variable shift count, since shifts by
12540 ;; zero don't affect the flags.  We assume that shifts by constant
12541 ;; zero are optimized away.
12542 (define_insn "*lshrhi3_cmp"
12543   [(set (reg 17)
12544         (compare
12545           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12546                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12547           (const_int 0)))
12548    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12549         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12550   "ix86_match_ccmode (insn, CCGOCmode)
12551    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12552   "shr{w}\t{%2, %0|%0, %2}"
12553   [(set_attr "type" "ishift")
12554    (set_attr "mode" "HI")])
12555
12556 (define_expand "lshrqi3"
12557   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12558         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12559                      (match_operand:QI 2 "nonmemory_operand" "")))
12560    (clobber (reg:CC 17))]
12561   "TARGET_QIMODE_MATH"
12562   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12563
12564 (define_insn "*lshrqi3_1_one_bit"
12565   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12566         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12567                      (match_operand:QI 2 "const_int_1_operand" "")))
12568    (clobber (reg:CC 17))]
12569   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12570    && (TARGET_SHIFT1 || optimize_size)"
12571   "shr{b}\t%0"
12572   [(set_attr "type" "ishift")
12573    (set (attr "length") 
12574      (if_then_else (match_operand 0 "register_operand" "") 
12575         (const_string "2")
12576         (const_string "*")))])
12577
12578 (define_insn "*lshrqi3_1_one_bit_slp"
12579   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12580         (lshiftrt:QI (match_dup 0)
12581                      (match_operand:QI 1 "const_int_1_operand" "")))
12582    (clobber (reg:CC 17))]
12583   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12584    && (TARGET_SHIFT1 || optimize_size)"
12585   "shr{b}\t%0"
12586   [(set_attr "type" "ishift1")
12587    (set (attr "length") 
12588      (if_then_else (match_operand 0 "register_operand" "") 
12589         (const_string "2")
12590         (const_string "*")))])
12591
12592 (define_insn "*lshrqi3_1"
12593   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12594         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12595                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12596    (clobber (reg:CC 17))]
12597   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12598   "@
12599    shr{b}\t{%2, %0|%0, %2}
12600    shr{b}\t{%b2, %0|%0, %b2}"
12601   [(set_attr "type" "ishift")
12602    (set_attr "mode" "QI")])
12603
12604 (define_insn "*lshrqi3_1_slp"
12605   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12606         (lshiftrt:QI (match_dup 0)
12607                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12608    (clobber (reg:CC 17))]
12609   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12610    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12611   "@
12612    shr{b}\t{%1, %0|%0, %1}
12613    shr{b}\t{%b1, %0|%0, %b1}"
12614   [(set_attr "type" "ishift1")
12615    (set_attr "mode" "QI")])
12616
12617 ;; This pattern can't accept a variable shift count, since shifts by
12618 ;; zero don't affect the flags.  We assume that shifts by constant
12619 ;; zero are optimized away.
12620 (define_insn "*lshrqi2_one_bit_cmp"
12621   [(set (reg 17)
12622         (compare
12623           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12624                        (match_operand:QI 2 "const_int_1_operand" ""))
12625           (const_int 0)))
12626    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12627         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12628   "ix86_match_ccmode (insn, CCGOCmode)
12629    && (TARGET_SHIFT1 || optimize_size)
12630    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12631   "shr{b}\t%0"
12632   [(set_attr "type" "ishift")
12633    (set (attr "length") 
12634      (if_then_else (match_operand:SI 0 "register_operand" "") 
12635         (const_string "2")
12636         (const_string "*")))])
12637
12638 ;; This pattern can't accept a variable shift count, since shifts by
12639 ;; zero don't affect the flags.  We assume that shifts by constant
12640 ;; zero are optimized away.
12641 (define_insn "*lshrqi2_cmp"
12642   [(set (reg 17)
12643         (compare
12644           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12645                        (match_operand:QI 2 "const_int_1_31_operand" "I"))
12646           (const_int 0)))
12647    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12648         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12649   "ix86_match_ccmode (insn, CCGOCmode)
12650    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12651   "shr{b}\t{%2, %0|%0, %2}"
12652   [(set_attr "type" "ishift")
12653    (set_attr "mode" "QI")])
12654 \f
12655 ;; Rotate instructions
12656
12657 (define_expand "rotldi3"
12658   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12659         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
12660                    (match_operand:QI 2 "nonmemory_operand" "")))
12661    (clobber (reg:CC 17))]
12662   "TARGET_64BIT"
12663   "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
12664
12665 (define_insn "*rotlsi3_1_one_bit_rex64"
12666   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12667         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12668                    (match_operand:QI 2 "const_int_1_operand" "")))
12669    (clobber (reg:CC 17))]
12670   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12671    && (TARGET_SHIFT1 || optimize_size)"
12672   "rol{q}\t%0"
12673   [(set_attr "type" "rotate")
12674    (set (attr "length") 
12675      (if_then_else (match_operand:DI 0 "register_operand" "") 
12676         (const_string "2")
12677         (const_string "*")))])
12678
12679 (define_insn "*rotldi3_1_rex64"
12680   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12681         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12682                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12683    (clobber (reg:CC 17))]
12684   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12685   "@
12686    rol{q}\t{%2, %0|%0, %2}
12687    rol{q}\t{%b2, %0|%0, %b2}"
12688   [(set_attr "type" "rotate")
12689    (set_attr "mode" "DI")])
12690
12691 (define_expand "rotlsi3"
12692   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12693         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12694                    (match_operand:QI 2 "nonmemory_operand" "")))
12695    (clobber (reg:CC 17))]
12696   ""
12697   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12698
12699 (define_insn "*rotlsi3_1_one_bit"
12700   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12701         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12702                    (match_operand:QI 2 "const_int_1_operand" "")))
12703    (clobber (reg:CC 17))]
12704   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12705    && (TARGET_SHIFT1 || optimize_size)"
12706   "rol{l}\t%0"
12707   [(set_attr "type" "rotate")
12708    (set (attr "length") 
12709      (if_then_else (match_operand:SI 0 "register_operand" "") 
12710         (const_string "2")
12711         (const_string "*")))])
12712
12713 (define_insn "*rotlsi3_1_one_bit_zext"
12714   [(set (match_operand:DI 0 "register_operand" "=r")
12715         (zero_extend:DI
12716           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12717                      (match_operand:QI 2 "const_int_1_operand" ""))))
12718    (clobber (reg:CC 17))]
12719   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12720    && (TARGET_SHIFT1 || optimize_size)"
12721   "rol{l}\t%k0"
12722   [(set_attr "type" "rotate")
12723    (set_attr "length" "2")])
12724
12725 (define_insn "*rotlsi3_1"
12726   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12727         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12728                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12729    (clobber (reg:CC 17))]
12730   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12731   "@
12732    rol{l}\t{%2, %0|%0, %2}
12733    rol{l}\t{%b2, %0|%0, %b2}"
12734   [(set_attr "type" "rotate")
12735    (set_attr "mode" "SI")])
12736
12737 (define_insn "*rotlsi3_1_zext"
12738   [(set (match_operand:DI 0 "register_operand" "=r,r")
12739         (zero_extend:DI
12740           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12741                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12742    (clobber (reg:CC 17))]
12743   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12744   "@
12745    rol{l}\t{%2, %k0|%k0, %2}
12746    rol{l}\t{%b2, %k0|%k0, %b2}"
12747   [(set_attr "type" "rotate")
12748    (set_attr "mode" "SI")])
12749
12750 (define_expand "rotlhi3"
12751   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12752         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12753                    (match_operand:QI 2 "nonmemory_operand" "")))
12754    (clobber (reg:CC 17))]
12755   "TARGET_HIMODE_MATH"
12756   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12757
12758 (define_insn "*rotlhi3_1_one_bit"
12759   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12760         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12761                    (match_operand:QI 2 "const_int_1_operand" "")))
12762    (clobber (reg:CC 17))]
12763   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12764    && (TARGET_SHIFT1 || optimize_size)"
12765   "rol{w}\t%0"
12766   [(set_attr "type" "rotate")
12767    (set (attr "length") 
12768      (if_then_else (match_operand 0 "register_operand" "") 
12769         (const_string "2")
12770         (const_string "*")))])
12771
12772 (define_insn "*rotlhi3_1"
12773   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12774         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12775                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12776    (clobber (reg:CC 17))]
12777   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12778   "@
12779    rol{w}\t{%2, %0|%0, %2}
12780    rol{w}\t{%b2, %0|%0, %b2}"
12781   [(set_attr "type" "rotate")
12782    (set_attr "mode" "HI")])
12783
12784 (define_expand "rotlqi3"
12785   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12786         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12787                    (match_operand:QI 2 "nonmemory_operand" "")))
12788    (clobber (reg:CC 17))]
12789   "TARGET_QIMODE_MATH"
12790   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12791
12792 (define_insn "*rotlqi3_1_one_bit_slp"
12793   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12794         (rotate:QI (match_dup 0)
12795                    (match_operand:QI 1 "const_int_1_operand" "")))
12796    (clobber (reg:CC 17))]
12797   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12798    && (TARGET_SHIFT1 || optimize_size)"
12799   "rol{b}\t%0"
12800   [(set_attr "type" "rotate1")
12801    (set (attr "length") 
12802      (if_then_else (match_operand 0 "register_operand" "") 
12803         (const_string "2")
12804         (const_string "*")))])
12805
12806 (define_insn "*rotlqi3_1_one_bit"
12807   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12808         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12809                    (match_operand:QI 2 "const_int_1_operand" "")))
12810    (clobber (reg:CC 17))]
12811   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12812    && (TARGET_SHIFT1 || optimize_size)"
12813   "rol{b}\t%0"
12814   [(set_attr "type" "rotate")
12815    (set (attr "length") 
12816      (if_then_else (match_operand 0 "register_operand" "") 
12817         (const_string "2")
12818         (const_string "*")))])
12819
12820 (define_insn "*rotlqi3_1_slp"
12821   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12822         (rotate:QI (match_dup 0)
12823                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12824    (clobber (reg:CC 17))]
12825   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12826    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12827   "@
12828    rol{b}\t{%1, %0|%0, %1}
12829    rol{b}\t{%b1, %0|%0, %b1}"
12830   [(set_attr "type" "rotate1")
12831    (set_attr "mode" "QI")])
12832
12833 (define_insn "*rotlqi3_1"
12834   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12835         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12836                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12837    (clobber (reg:CC 17))]
12838   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12839   "@
12840    rol{b}\t{%2, %0|%0, %2}
12841    rol{b}\t{%b2, %0|%0, %b2}"
12842   [(set_attr "type" "rotate")
12843    (set_attr "mode" "QI")])
12844
12845 (define_expand "rotrdi3"
12846   [(set (match_operand:DI 0 "nonimmediate_operand" "")
12847         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
12848                      (match_operand:QI 2 "nonmemory_operand" "")))
12849    (clobber (reg:CC 17))]
12850   "TARGET_64BIT"
12851   "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
12852
12853 (define_insn "*rotrdi3_1_one_bit_rex64"
12854   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12855         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12856                      (match_operand:QI 2 "const_int_1_operand" "")))
12857    (clobber (reg:CC 17))]
12858   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12859    && (TARGET_SHIFT1 || optimize_size)"
12860   "ror{q}\t%0"
12861   [(set_attr "type" "rotate")
12862    (set (attr "length") 
12863      (if_then_else (match_operand:DI 0 "register_operand" "") 
12864         (const_string "2")
12865         (const_string "*")))])
12866
12867 (define_insn "*rotrdi3_1_rex64"
12868   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12869         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12870                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12871    (clobber (reg:CC 17))]
12872   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12873   "@
12874    ror{q}\t{%2, %0|%0, %2}
12875    ror{q}\t{%b2, %0|%0, %b2}"
12876   [(set_attr "type" "rotate")
12877    (set_attr "mode" "DI")])
12878
12879 (define_expand "rotrsi3"
12880   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12881         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12882                      (match_operand:QI 2 "nonmemory_operand" "")))
12883    (clobber (reg:CC 17))]
12884   ""
12885   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12886
12887 (define_insn "*rotrsi3_1_one_bit"
12888   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12889         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12890                      (match_operand:QI 2 "const_int_1_operand" "")))
12891    (clobber (reg:CC 17))]
12892   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12893    && (TARGET_SHIFT1 || optimize_size)"
12894   "ror{l}\t%0"
12895   [(set_attr "type" "rotate")
12896    (set (attr "length") 
12897      (if_then_else (match_operand:SI 0 "register_operand" "") 
12898         (const_string "2")
12899         (const_string "*")))])
12900
12901 (define_insn "*rotrsi3_1_one_bit_zext"
12902   [(set (match_operand:DI 0 "register_operand" "=r")
12903         (zero_extend:DI
12904           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12905                        (match_operand:QI 2 "const_int_1_operand" ""))))
12906    (clobber (reg:CC 17))]
12907   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12908    && (TARGET_SHIFT1 || optimize_size)"
12909   "ror{l}\t%k0"
12910   [(set_attr "type" "rotate")
12911    (set (attr "length") 
12912      (if_then_else (match_operand:SI 0 "register_operand" "") 
12913         (const_string "2")
12914         (const_string "*")))])
12915
12916 (define_insn "*rotrsi3_1"
12917   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12918         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12919                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12920    (clobber (reg:CC 17))]
12921   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12922   "@
12923    ror{l}\t{%2, %0|%0, %2}
12924    ror{l}\t{%b2, %0|%0, %b2}"
12925   [(set_attr "type" "rotate")
12926    (set_attr "mode" "SI")])
12927
12928 (define_insn "*rotrsi3_1_zext"
12929   [(set (match_operand:DI 0 "register_operand" "=r,r")
12930         (zero_extend:DI
12931           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12932                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12933    (clobber (reg:CC 17))]
12934   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12935   "@
12936    ror{l}\t{%2, %k0|%k0, %2}
12937    ror{l}\t{%b2, %k0|%k0, %b2}"
12938   [(set_attr "type" "rotate")
12939    (set_attr "mode" "SI")])
12940
12941 (define_expand "rotrhi3"
12942   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12943         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12944                      (match_operand:QI 2 "nonmemory_operand" "")))
12945    (clobber (reg:CC 17))]
12946   "TARGET_HIMODE_MATH"
12947   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12948
12949 (define_insn "*rotrhi3_one_bit"
12950   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12951         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12952                      (match_operand:QI 2 "const_int_1_operand" "")))
12953    (clobber (reg:CC 17))]
12954   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12955    && (TARGET_SHIFT1 || optimize_size)"
12956   "ror{w}\t%0"
12957   [(set_attr "type" "rotate")
12958    (set (attr "length") 
12959      (if_then_else (match_operand 0 "register_operand" "") 
12960         (const_string "2")
12961         (const_string "*")))])
12962
12963 (define_insn "*rotrhi3"
12964   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12965         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12966                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12967    (clobber (reg:CC 17))]
12968   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12969   "@
12970    ror{w}\t{%2, %0|%0, %2}
12971    ror{w}\t{%b2, %0|%0, %b2}"
12972   [(set_attr "type" "rotate")
12973    (set_attr "mode" "HI")])
12974
12975 (define_expand "rotrqi3"
12976   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12977         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12978                      (match_operand:QI 2 "nonmemory_operand" "")))
12979    (clobber (reg:CC 17))]
12980   "TARGET_QIMODE_MATH"
12981   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12982
12983 (define_insn "*rotrqi3_1_one_bit"
12984   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12985         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12986                      (match_operand:QI 2 "const_int_1_operand" "")))
12987    (clobber (reg:CC 17))]
12988   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12989    && (TARGET_SHIFT1 || optimize_size)"
12990   "ror{b}\t%0"
12991   [(set_attr "type" "rotate")
12992    (set (attr "length") 
12993      (if_then_else (match_operand 0 "register_operand" "") 
12994         (const_string "2")
12995         (const_string "*")))])
12996
12997 (define_insn "*rotrqi3_1_one_bit_slp"
12998   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12999         (rotatert:QI (match_dup 0)
13000                      (match_operand:QI 1 "const_int_1_operand" "")))
13001    (clobber (reg:CC 17))]
13002   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13003    && (TARGET_SHIFT1 || optimize_size)"
13004   "ror{b}\t%0"
13005   [(set_attr "type" "rotate1")
13006    (set (attr "length") 
13007      (if_then_else (match_operand 0 "register_operand" "") 
13008         (const_string "2")
13009         (const_string "*")))])
13010
13011 (define_insn "*rotrqi3_1"
13012   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13013         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13014                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13015    (clobber (reg:CC 17))]
13016   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13017   "@
13018    ror{b}\t{%2, %0|%0, %2}
13019    ror{b}\t{%b2, %0|%0, %b2}"
13020   [(set_attr "type" "rotate")
13021    (set_attr "mode" "QI")])
13022
13023 (define_insn "*rotrqi3_1_slp"
13024   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13025         (rotatert:QI (match_dup 0)
13026                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13027    (clobber (reg:CC 17))]
13028   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13029    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
13030   "@
13031    ror{b}\t{%1, %0|%0, %1}
13032    ror{b}\t{%b1, %0|%0, %b1}"
13033   [(set_attr "type" "rotate1")
13034    (set_attr "mode" "QI")])
13035 \f
13036 ;; Bit set / bit test instructions
13037
13038 (define_expand "extv"
13039   [(set (match_operand:SI 0 "register_operand" "")
13040         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13041                          (match_operand:SI 2 "immediate_operand" "")
13042                          (match_operand:SI 3 "immediate_operand" "")))]
13043   ""
13044 {
13045   /* Handle extractions from %ah et al.  */
13046   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13047     FAIL;
13048
13049   /* From mips.md: extract_bit_field doesn't verify that our source
13050      matches the predicate, so check it again here.  */
13051   if (! register_operand (operands[1], VOIDmode))
13052     FAIL;
13053 })
13054
13055 (define_expand "extzv"
13056   [(set (match_operand:SI 0 "register_operand" "")
13057         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13058                          (match_operand:SI 2 "immediate_operand" "")
13059                          (match_operand:SI 3 "immediate_operand" "")))]
13060   ""
13061 {
13062   /* Handle extractions from %ah et al.  */
13063   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13064     FAIL;
13065
13066   /* From mips.md: extract_bit_field doesn't verify that our source
13067      matches the predicate, so check it again here.  */
13068   if (! register_operand (operands[1], VOIDmode))
13069     FAIL;
13070 })
13071
13072 (define_expand "insv"
13073   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
13074                          (match_operand:SI 1 "immediate_operand" "")
13075                          (match_operand:SI 2 "immediate_operand" ""))
13076         (match_operand:SI 3 "register_operand" ""))]
13077   ""
13078 {
13079   /* Handle extractions from %ah et al.  */
13080   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13081     FAIL;
13082
13083   /* From mips.md: insert_bit_field doesn't verify that our source
13084      matches the predicate, so check it again here.  */
13085   if (! register_operand (operands[0], VOIDmode))
13086     FAIL;
13087 })
13088
13089 ;; %%% bts, btr, btc, bt.
13090 \f
13091 ;; Store-flag instructions.
13092
13093 ;; For all sCOND expanders, also expand the compare or test insn that
13094 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13095
13096 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13097 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13098 ;; way, which can later delete the movzx if only QImode is needed.
13099
13100 (define_expand "seq"
13101   [(set (match_operand:QI 0 "register_operand" "")
13102         (eq:QI (reg:CC 17) (const_int 0)))]
13103   ""
13104   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13105
13106 (define_expand "sne"
13107   [(set (match_operand:QI 0 "register_operand" "")
13108         (ne:QI (reg:CC 17) (const_int 0)))]
13109   ""
13110   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13111
13112 (define_expand "sgt"
13113   [(set (match_operand:QI 0 "register_operand" "")
13114         (gt:QI (reg:CC 17) (const_int 0)))]
13115   ""
13116   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13117
13118 (define_expand "sgtu"
13119   [(set (match_operand:QI 0 "register_operand" "")
13120         (gtu:QI (reg:CC 17) (const_int 0)))]
13121   ""
13122   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13123
13124 (define_expand "slt"
13125   [(set (match_operand:QI 0 "register_operand" "")
13126         (lt:QI (reg:CC 17) (const_int 0)))]
13127   ""
13128   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13129
13130 (define_expand "sltu"
13131   [(set (match_operand:QI 0 "register_operand" "")
13132         (ltu:QI (reg:CC 17) (const_int 0)))]
13133   ""
13134   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13135
13136 (define_expand "sge"
13137   [(set (match_operand:QI 0 "register_operand" "")
13138         (ge:QI (reg:CC 17) (const_int 0)))]
13139   ""
13140   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13141
13142 (define_expand "sgeu"
13143   [(set (match_operand:QI 0 "register_operand" "")
13144         (geu:QI (reg:CC 17) (const_int 0)))]
13145   ""
13146   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13147
13148 (define_expand "sle"
13149   [(set (match_operand:QI 0 "register_operand" "")
13150         (le:QI (reg:CC 17) (const_int 0)))]
13151   ""
13152   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13153
13154 (define_expand "sleu"
13155   [(set (match_operand:QI 0 "register_operand" "")
13156         (leu:QI (reg:CC 17) (const_int 0)))]
13157   ""
13158   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13159
13160 (define_expand "sunordered"
13161   [(set (match_operand:QI 0 "register_operand" "")
13162         (unordered:QI (reg:CC 17) (const_int 0)))]
13163   "TARGET_80387 || TARGET_SSE"
13164   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13165
13166 (define_expand "sordered"
13167   [(set (match_operand:QI 0 "register_operand" "")
13168         (ordered:QI (reg:CC 17) (const_int 0)))]
13169   "TARGET_80387"
13170   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13171
13172 (define_expand "suneq"
13173   [(set (match_operand:QI 0 "register_operand" "")
13174         (uneq:QI (reg:CC 17) (const_int 0)))]
13175   "TARGET_80387 || TARGET_SSE"
13176   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13177
13178 (define_expand "sunge"
13179   [(set (match_operand:QI 0 "register_operand" "")
13180         (unge:QI (reg:CC 17) (const_int 0)))]
13181   "TARGET_80387 || TARGET_SSE"
13182   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13183
13184 (define_expand "sungt"
13185   [(set (match_operand:QI 0 "register_operand" "")
13186         (ungt:QI (reg:CC 17) (const_int 0)))]
13187   "TARGET_80387 || TARGET_SSE"
13188   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13189
13190 (define_expand "sunle"
13191   [(set (match_operand:QI 0 "register_operand" "")
13192         (unle:QI (reg:CC 17) (const_int 0)))]
13193   "TARGET_80387 || TARGET_SSE"
13194   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13195
13196 (define_expand "sunlt"
13197   [(set (match_operand:QI 0 "register_operand" "")
13198         (unlt:QI (reg:CC 17) (const_int 0)))]
13199   "TARGET_80387 || TARGET_SSE"
13200   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13201
13202 (define_expand "sltgt"
13203   [(set (match_operand:QI 0 "register_operand" "")
13204         (ltgt:QI (reg:CC 17) (const_int 0)))]
13205   "TARGET_80387 || TARGET_SSE"
13206   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13207
13208 (define_insn "*setcc_1"
13209   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13210         (match_operator:QI 1 "ix86_comparison_operator"
13211           [(reg 17) (const_int 0)]))]
13212   ""
13213   "set%C1\t%0"
13214   [(set_attr "type" "setcc")
13215    (set_attr "mode" "QI")])
13216
13217 (define_insn "setcc_2"
13218   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13219         (match_operator:QI 1 "ix86_comparison_operator"
13220           [(reg 17) (const_int 0)]))]
13221   ""
13222   "set%C1\t%0"
13223   [(set_attr "type" "setcc")
13224    (set_attr "mode" "QI")])
13225
13226 ;; In general it is not safe to assume too much about CCmode registers,
13227 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13228 ;; conditions this is safe on x86, so help combine not create
13229 ;;
13230 ;;      seta    %al
13231 ;;      testb   %al, %al
13232 ;;      sete    %al
13233
13234 (define_split 
13235   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13236         (ne:QI (match_operator 1 "ix86_comparison_operator"
13237                  [(reg 17) (const_int 0)])
13238             (const_int 0)))]
13239   ""
13240   [(set (match_dup 0) (match_dup 1))]
13241 {
13242   PUT_MODE (operands[1], QImode);
13243 })
13244
13245 (define_split 
13246   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13247         (ne:QI (match_operator 1 "ix86_comparison_operator"
13248                  [(reg 17) (const_int 0)])
13249             (const_int 0)))]
13250   ""
13251   [(set (match_dup 0) (match_dup 1))]
13252 {
13253   PUT_MODE (operands[1], QImode);
13254 })
13255
13256 (define_split 
13257   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13258         (eq:QI (match_operator 1 "ix86_comparison_operator"
13259                  [(reg 17) (const_int 0)])
13260             (const_int 0)))]
13261   ""
13262   [(set (match_dup 0) (match_dup 1))]
13263 {
13264   rtx new_op1 = copy_rtx (operands[1]);
13265   operands[1] = new_op1;
13266   PUT_MODE (new_op1, QImode);
13267   PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
13268                                         GET_MODE (XEXP (new_op1, 0))));
13269
13270   /* Make sure that (a) the CCmode we have for the flags is strong
13271      enough for the reversed compare or (b) we have a valid FP compare.  */
13272   if (! ix86_comparison_operator (new_op1, VOIDmode))
13273     FAIL;
13274 })
13275
13276 (define_split 
13277   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13278         (eq:QI (match_operator 1 "ix86_comparison_operator"
13279                  [(reg 17) (const_int 0)])
13280             (const_int 0)))]
13281   ""
13282   [(set (match_dup 0) (match_dup 1))]
13283 {
13284   rtx new_op1 = copy_rtx (operands[1]);
13285   operands[1] = new_op1;
13286   PUT_MODE (new_op1, QImode);
13287   PUT_CODE (new_op1, REVERSE_CONDITION (GET_CODE (new_op1),
13288                                         GET_MODE (XEXP (new_op1, 0))));
13289
13290   /* Make sure that (a) the CCmode we have for the flags is strong
13291      enough for the reversed compare or (b) we have a valid FP compare.  */
13292   if (! ix86_comparison_operator (new_op1, VOIDmode))
13293     FAIL;
13294 })
13295
13296 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13297 ;; subsequent logical operations are used to imitate conditional moves.
13298 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13299 ;; it directly.  Further holding this value in pseudo register might bring
13300 ;; problem in implicit normalization in spill code.
13301 ;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
13302 ;; instructions after reload by splitting the conditional move patterns.
13303
13304 (define_insn "*sse_setccsf"
13305   [(set (match_operand:SF 0 "register_operand" "=x")
13306         (match_operator:SF 1 "sse_comparison_operator"
13307           [(match_operand:SF 2 "register_operand" "0")
13308            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13309   "TARGET_SSE && reload_completed"
13310   "cmp%D1ss\t{%3, %0|%0, %3}"
13311   [(set_attr "type" "ssecmp")
13312    (set_attr "mode" "SF")])
13313
13314 (define_insn "*sse_setccdf"
13315   [(set (match_operand:DF 0 "register_operand" "=Y")
13316         (match_operator:DF 1 "sse_comparison_operator"
13317           [(match_operand:DF 2 "register_operand" "0")
13318            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13319   "TARGET_SSE2 && reload_completed"
13320   "cmp%D1sd\t{%3, %0|%0, %3}"
13321   [(set_attr "type" "ssecmp")
13322    (set_attr "mode" "DF")])
13323 \f
13324 ;; Basic conditional jump instructions.
13325 ;; We ignore the overflow flag for signed branch instructions.
13326
13327 ;; For all bCOND expanders, also expand the compare or test insn that
13328 ;; generates reg 17.  Generate an equality comparison if `beq' or `bne'.
13329
13330 (define_expand "beq"
13331   [(set (pc)
13332         (if_then_else (match_dup 1)
13333                       (label_ref (match_operand 0 "" ""))
13334                       (pc)))]
13335   ""
13336   "ix86_expand_branch (EQ, operands[0]); DONE;")
13337
13338 (define_expand "bne"
13339   [(set (pc)
13340         (if_then_else (match_dup 1)
13341                       (label_ref (match_operand 0 "" ""))
13342                       (pc)))]
13343   ""
13344   "ix86_expand_branch (NE, operands[0]); DONE;")
13345
13346 (define_expand "bgt"
13347   [(set (pc)
13348         (if_then_else (match_dup 1)
13349                       (label_ref (match_operand 0 "" ""))
13350                       (pc)))]
13351   ""
13352   "ix86_expand_branch (GT, operands[0]); DONE;")
13353
13354 (define_expand "bgtu"
13355   [(set (pc)
13356         (if_then_else (match_dup 1)
13357                       (label_ref (match_operand 0 "" ""))
13358                       (pc)))]
13359   ""
13360   "ix86_expand_branch (GTU, operands[0]); DONE;")
13361
13362 (define_expand "blt"
13363   [(set (pc)
13364         (if_then_else (match_dup 1)
13365                       (label_ref (match_operand 0 "" ""))
13366                       (pc)))]
13367   ""
13368   "ix86_expand_branch (LT, operands[0]); DONE;")
13369
13370 (define_expand "bltu"
13371   [(set (pc)
13372         (if_then_else (match_dup 1)
13373                       (label_ref (match_operand 0 "" ""))
13374                       (pc)))]
13375   ""
13376   "ix86_expand_branch (LTU, operands[0]); DONE;")
13377
13378 (define_expand "bge"
13379   [(set (pc)
13380         (if_then_else (match_dup 1)
13381                       (label_ref (match_operand 0 "" ""))
13382                       (pc)))]
13383   ""
13384   "ix86_expand_branch (GE, operands[0]); DONE;")
13385
13386 (define_expand "bgeu"
13387   [(set (pc)
13388         (if_then_else (match_dup 1)
13389                       (label_ref (match_operand 0 "" ""))
13390                       (pc)))]
13391   ""
13392   "ix86_expand_branch (GEU, operands[0]); DONE;")
13393
13394 (define_expand "ble"
13395   [(set (pc)
13396         (if_then_else (match_dup 1)
13397                       (label_ref (match_operand 0 "" ""))
13398                       (pc)))]
13399   ""
13400   "ix86_expand_branch (LE, operands[0]); DONE;")
13401
13402 (define_expand "bleu"
13403   [(set (pc)
13404         (if_then_else (match_dup 1)
13405                       (label_ref (match_operand 0 "" ""))
13406                       (pc)))]
13407   ""
13408   "ix86_expand_branch (LEU, operands[0]); DONE;")
13409
13410 (define_expand "bunordered"
13411   [(set (pc)
13412         (if_then_else (match_dup 1)
13413                       (label_ref (match_operand 0 "" ""))
13414                       (pc)))]
13415   "TARGET_80387 || TARGET_SSE"
13416   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13417
13418 (define_expand "bordered"
13419   [(set (pc)
13420         (if_then_else (match_dup 1)
13421                       (label_ref (match_operand 0 "" ""))
13422                       (pc)))]
13423   "TARGET_80387 || TARGET_SSE"
13424   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13425
13426 (define_expand "buneq"
13427   [(set (pc)
13428         (if_then_else (match_dup 1)
13429                       (label_ref (match_operand 0 "" ""))
13430                       (pc)))]
13431   "TARGET_80387 || TARGET_SSE"
13432   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13433
13434 (define_expand "bunge"
13435   [(set (pc)
13436         (if_then_else (match_dup 1)
13437                       (label_ref (match_operand 0 "" ""))
13438                       (pc)))]
13439   "TARGET_80387 || TARGET_SSE"
13440   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13441
13442 (define_expand "bungt"
13443   [(set (pc)
13444         (if_then_else (match_dup 1)
13445                       (label_ref (match_operand 0 "" ""))
13446                       (pc)))]
13447   "TARGET_80387 || TARGET_SSE"
13448   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13449
13450 (define_expand "bunle"
13451   [(set (pc)
13452         (if_then_else (match_dup 1)
13453                       (label_ref (match_operand 0 "" ""))
13454                       (pc)))]
13455   "TARGET_80387 || TARGET_SSE"
13456   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13457
13458 (define_expand "bunlt"
13459   [(set (pc)
13460         (if_then_else (match_dup 1)
13461                       (label_ref (match_operand 0 "" ""))
13462                       (pc)))]
13463   "TARGET_80387 || TARGET_SSE"
13464   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13465
13466 (define_expand "bltgt"
13467   [(set (pc)
13468         (if_then_else (match_dup 1)
13469                       (label_ref (match_operand 0 "" ""))
13470                       (pc)))]
13471   "TARGET_80387 || TARGET_SSE"
13472   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13473
13474 (define_insn "*jcc_1"
13475   [(set (pc)
13476         (if_then_else (match_operator 1 "ix86_comparison_operator"
13477                                       [(reg 17) (const_int 0)])
13478                       (label_ref (match_operand 0 "" ""))
13479                       (pc)))]
13480   ""
13481   "%+j%C1\t%l0"
13482   [(set_attr "type" "ibr")
13483    (set_attr "modrm" "0")
13484    (set (attr "length")
13485            (if_then_else (and (ge (minus (match_dup 0) (pc))
13486                                   (const_int -126))
13487                               (lt (minus (match_dup 0) (pc))
13488                                   (const_int 128)))
13489              (const_int 2)
13490              (const_int 6)))])
13491
13492 (define_insn "*jcc_2"
13493   [(set (pc)
13494         (if_then_else (match_operator 1 "ix86_comparison_operator"
13495                                       [(reg 17) (const_int 0)])
13496                       (pc)
13497                       (label_ref (match_operand 0 "" ""))))]
13498   ""
13499   "%+j%c1\t%l0"
13500   [(set_attr "type" "ibr")
13501    (set_attr "modrm" "0")
13502    (set (attr "length")
13503            (if_then_else (and (ge (minus (match_dup 0) (pc))
13504                                   (const_int -126))
13505                               (lt (minus (match_dup 0) (pc))
13506                                   (const_int 128)))
13507              (const_int 2)
13508              (const_int 6)))])
13509
13510 ;; In general it is not safe to assume too much about CCmode registers,
13511 ;; so simplify-rtx stops when it sees a second one.  Under certain 
13512 ;; conditions this is safe on x86, so help combine not create
13513 ;;
13514 ;;      seta    %al
13515 ;;      testb   %al, %al
13516 ;;      je      Lfoo
13517
13518 (define_split 
13519   [(set (pc)
13520         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13521                                       [(reg 17) (const_int 0)])
13522                           (const_int 0))
13523                       (label_ref (match_operand 1 "" ""))
13524                       (pc)))]
13525   ""
13526   [(set (pc)
13527         (if_then_else (match_dup 0)
13528                       (label_ref (match_dup 1))
13529                       (pc)))]
13530 {
13531   PUT_MODE (operands[0], VOIDmode);
13532 })
13533   
13534 (define_split 
13535   [(set (pc)
13536         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13537                                       [(reg 17) (const_int 0)])
13538                           (const_int 0))
13539                       (label_ref (match_operand 1 "" ""))
13540                       (pc)))]
13541   ""
13542   [(set (pc)
13543         (if_then_else (match_dup 0)
13544                       (label_ref (match_dup 1))
13545                       (pc)))]
13546 {
13547   rtx new_op0 = copy_rtx (operands[0]);
13548   operands[0] = new_op0;
13549   PUT_MODE (new_op0, VOIDmode);
13550   PUT_CODE (new_op0, REVERSE_CONDITION (GET_CODE (new_op0),
13551                                         GET_MODE (XEXP (new_op0, 0))));
13552
13553   /* Make sure that (a) the CCmode we have for the flags is strong
13554      enough for the reversed compare or (b) we have a valid FP compare.  */
13555   if (! ix86_comparison_operator (new_op0, VOIDmode))
13556     FAIL;
13557 })
13558
13559 ;; Define combination compare-and-branch fp compare instructions to use
13560 ;; during early optimization.  Splitting the operation apart early makes
13561 ;; for bad code when we want to reverse the operation.
13562
13563 (define_insn "*fp_jcc_1"
13564   [(set (pc)
13565         (if_then_else (match_operator 0 "comparison_operator"
13566                         [(match_operand 1 "register_operand" "f")
13567                          (match_operand 2 "register_operand" "f")])
13568           (label_ref (match_operand 3 "" ""))
13569           (pc)))
13570    (clobber (reg:CCFP 18))
13571    (clobber (reg:CCFP 17))]
13572   "TARGET_CMOVE && TARGET_80387
13573    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13574    && FLOAT_MODE_P (GET_MODE (operands[1]))
13575    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13576    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13577   "#")
13578
13579 (define_insn "*fp_jcc_1_sse"
13580   [(set (pc)
13581         (if_then_else (match_operator 0 "comparison_operator"
13582                         [(match_operand 1 "register_operand" "f#x,x#f")
13583                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13584           (label_ref (match_operand 3 "" ""))
13585           (pc)))
13586    (clobber (reg:CCFP 18))
13587    (clobber (reg:CCFP 17))]
13588   "TARGET_80387
13589    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13590    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13591    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13592   "#")
13593
13594 (define_insn "*fp_jcc_1_sse_only"
13595   [(set (pc)
13596         (if_then_else (match_operator 0 "comparison_operator"
13597                         [(match_operand 1 "register_operand" "x")
13598                          (match_operand 2 "nonimmediate_operand" "xm")])
13599           (label_ref (match_operand 3 "" ""))
13600           (pc)))
13601    (clobber (reg:CCFP 18))
13602    (clobber (reg:CCFP 17))]
13603   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13604    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13605    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13606   "#")
13607
13608 (define_insn "*fp_jcc_2"
13609   [(set (pc)
13610         (if_then_else (match_operator 0 "comparison_operator"
13611                         [(match_operand 1 "register_operand" "f")
13612                          (match_operand 2 "register_operand" "f")])
13613           (pc)
13614           (label_ref (match_operand 3 "" ""))))
13615    (clobber (reg:CCFP 18))
13616    (clobber (reg:CCFP 17))]
13617   "TARGET_CMOVE && TARGET_80387
13618    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13619    && FLOAT_MODE_P (GET_MODE (operands[1]))
13620    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13621    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13622   "#")
13623
13624 (define_insn "*fp_jcc_2_sse"
13625   [(set (pc)
13626         (if_then_else (match_operator 0 "comparison_operator"
13627                         [(match_operand 1 "register_operand" "f#x,x#f")
13628                          (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
13629           (pc)
13630           (label_ref (match_operand 3 "" ""))))
13631    (clobber (reg:CCFP 18))
13632    (clobber (reg:CCFP 17))]
13633   "TARGET_80387
13634    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13635    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13636    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13637   "#")
13638
13639 (define_insn "*fp_jcc_2_sse_only"
13640   [(set (pc)
13641         (if_then_else (match_operator 0 "comparison_operator"
13642                         [(match_operand 1 "register_operand" "x")
13643                          (match_operand 2 "nonimmediate_operand" "xm")])
13644           (pc)
13645           (label_ref (match_operand 3 "" ""))))
13646    (clobber (reg:CCFP 18))
13647    (clobber (reg:CCFP 17))]
13648   "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13649    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13650    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13651   "#")
13652
13653 (define_insn "*fp_jcc_3"
13654   [(set (pc)
13655         (if_then_else (match_operator 0 "comparison_operator"
13656                         [(match_operand 1 "register_operand" "f")
13657                          (match_operand 2 "nonimmediate_operand" "fm")])
13658           (label_ref (match_operand 3 "" ""))
13659           (pc)))
13660    (clobber (reg:CCFP 18))
13661    (clobber (reg:CCFP 17))
13662    (clobber (match_scratch:HI 4 "=a"))]
13663   "TARGET_80387
13664    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13665    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13666    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13667    && SELECT_CC_MODE (GET_CODE (operands[0]),
13668                       operands[1], operands[2]) == CCFPmode
13669    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13670   "#")
13671
13672 (define_insn "*fp_jcc_4"
13673   [(set (pc)
13674         (if_then_else (match_operator 0 "comparison_operator"
13675                         [(match_operand 1 "register_operand" "f")
13676                          (match_operand 2 "nonimmediate_operand" "fm")])
13677           (pc)
13678           (label_ref (match_operand 3 "" ""))))
13679    (clobber (reg:CCFP 18))
13680    (clobber (reg:CCFP 17))
13681    (clobber (match_scratch:HI 4 "=a"))]
13682   "TARGET_80387
13683    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13684    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13685    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13686    && SELECT_CC_MODE (GET_CODE (operands[0]),
13687                       operands[1], operands[2]) == CCFPmode
13688    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13689   "#")
13690
13691 (define_insn "*fp_jcc_5"
13692   [(set (pc)
13693         (if_then_else (match_operator 0 "comparison_operator"
13694                         [(match_operand 1 "register_operand" "f")
13695                          (match_operand 2 "register_operand" "f")])
13696           (label_ref (match_operand 3 "" ""))
13697           (pc)))
13698    (clobber (reg:CCFP 18))
13699    (clobber (reg:CCFP 17))
13700    (clobber (match_scratch:HI 4 "=a"))]
13701   "TARGET_80387
13702    && FLOAT_MODE_P (GET_MODE (operands[1]))
13703    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13704    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13705   "#")
13706
13707 (define_insn "*fp_jcc_6"
13708   [(set (pc)
13709         (if_then_else (match_operator 0 "comparison_operator"
13710                         [(match_operand 1 "register_operand" "f")
13711                          (match_operand 2 "register_operand" "f")])
13712           (pc)
13713           (label_ref (match_operand 3 "" ""))))
13714    (clobber (reg:CCFP 18))
13715    (clobber (reg:CCFP 17))
13716    (clobber (match_scratch:HI 4 "=a"))]
13717   "TARGET_80387
13718    && FLOAT_MODE_P (GET_MODE (operands[1]))
13719    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13720    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13721   "#")
13722
13723 (define_split
13724   [(set (pc)
13725         (if_then_else (match_operator 0 "comparison_operator"
13726                         [(match_operand 1 "register_operand" "")
13727                          (match_operand 2 "nonimmediate_operand" "")])
13728           (match_operand 3 "" "")
13729           (match_operand 4 "" "")))
13730    (clobber (reg:CCFP 18))
13731    (clobber (reg:CCFP 17))]
13732   "reload_completed"
13733   [(const_int 0)]
13734 {
13735   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13736                         operands[3], operands[4], NULL_RTX);
13737   DONE;
13738 })
13739
13740 (define_split
13741   [(set (pc)
13742         (if_then_else (match_operator 0 "comparison_operator"
13743                         [(match_operand 1 "register_operand" "")
13744                          (match_operand 2 "nonimmediate_operand" "")])
13745           (match_operand 3 "" "")
13746           (match_operand 4 "" "")))
13747    (clobber (reg:CCFP 18))
13748    (clobber (reg:CCFP 17))
13749    (clobber (match_scratch:HI 5 "=a"))]
13750   "reload_completed"
13751   [(set (pc)
13752         (if_then_else (match_dup 6)
13753           (match_dup 3)
13754           (match_dup 4)))]
13755 {
13756   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13757                         operands[3], operands[4], operands[5]);
13758   DONE;
13759 })
13760 \f
13761 ;; Unconditional and other jump instructions
13762
13763 (define_insn "jump"
13764   [(set (pc)
13765         (label_ref (match_operand 0 "" "")))]
13766   ""
13767   "jmp\t%l0"
13768   [(set_attr "type" "ibr")
13769    (set (attr "length")
13770            (if_then_else (and (ge (minus (match_dup 0) (pc))
13771                                   (const_int -126))
13772                               (lt (minus (match_dup 0) (pc))
13773                                   (const_int 128)))
13774              (const_int 2)
13775              (const_int 5)))
13776    (set_attr "modrm" "0")])
13777
13778 (define_expand "indirect_jump"
13779   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13780   ""
13781   "")
13782
13783 (define_insn "*indirect_jump"
13784   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13785   "!TARGET_64BIT"
13786   "jmp\t%A0"
13787   [(set_attr "type" "ibr")
13788    (set_attr "length_immediate" "0")])
13789
13790 (define_insn "*indirect_jump_rtx64"
13791   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13792   "TARGET_64BIT"
13793   "jmp\t%A0"
13794   [(set_attr "type" "ibr")
13795    (set_attr "length_immediate" "0")])
13796
13797 (define_expand "tablejump"
13798   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13799               (use (label_ref (match_operand 1 "" "")))])]
13800   ""
13801 {
13802   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13803      relative.  Convert the relative address to an absolute address.  */
13804   if (flag_pic)
13805     {
13806       rtx op0, op1;
13807       enum rtx_code code;
13808
13809       if (TARGET_64BIT)
13810         {
13811           code = PLUS;
13812           op0 = operands[0];
13813           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13814         }
13815       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13816         {
13817           code = PLUS;
13818           op0 = operands[0];
13819           op1 = pic_offset_table_rtx;
13820         }
13821       else
13822         {
13823           code = MINUS;
13824           op0 = pic_offset_table_rtx;
13825           op1 = operands[0];
13826         }
13827
13828       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13829                                          OPTAB_DIRECT);
13830     }
13831 })
13832
13833 (define_insn "*tablejump_1"
13834   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13835    (use (label_ref (match_operand 1 "" "")))]
13836   "!TARGET_64BIT"
13837   "jmp\t%A0"
13838   [(set_attr "type" "ibr")
13839    (set_attr "length_immediate" "0")])
13840
13841 (define_insn "*tablejump_1_rtx64"
13842   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13843    (use (label_ref (match_operand 1 "" "")))]
13844   "TARGET_64BIT"
13845   "jmp\t%A0"
13846   [(set_attr "type" "ibr")
13847    (set_attr "length_immediate" "0")])
13848 \f
13849 ;; Loop instruction
13850 ;;
13851 ;; This is all complicated by the fact that since this is a jump insn
13852 ;; we must handle our own reloads.
13853
13854 (define_expand "doloop_end"
13855   [(use (match_operand 0 "" ""))        ; loop pseudo
13856    (use (match_operand 1 "" ""))        ; iterations; zero if unknown
13857    (use (match_operand 2 "" ""))        ; max iterations
13858    (use (match_operand 3 "" ""))        ; loop level 
13859    (use (match_operand 4 "" ""))]       ; label
13860   "!TARGET_64BIT && TARGET_USE_LOOP"
13861   "                                 
13862 {
13863   /* Only use cloop on innermost loops.  */
13864   if (INTVAL (operands[3]) > 1)
13865     FAIL;
13866   if (GET_MODE (operands[0]) != SImode)
13867     FAIL;
13868   emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13869                                            operands[0]));
13870   DONE;
13871 }")
13872
13873 (define_insn "doloop_end_internal"
13874   [(set (pc)
13875         (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13876                           (const_int 1))
13877                       (label_ref (match_operand 0 "" ""))
13878                       (pc)))
13879    (set (match_operand:SI 2 "register_operand" "=1,1,*m*r")
13880         (plus:SI (match_dup 1)
13881                  (const_int -1)))
13882    (clobber (match_scratch:SI 3 "=X,X,r"))
13883    (clobber (reg:CC 17))]
13884   "!TARGET_64BIT && TARGET_USE_LOOP"
13885 {
13886   if (which_alternative != 0)
13887     return "#";
13888   if (get_attr_length (insn) == 2)
13889     return "%+loop\t%l0";
13890   else
13891     return "dec{l}\t%1\;%+jne\t%l0";
13892 }
13893   [(set_attr "ppro_uops" "many")
13894    (set (attr "length")
13895         (if_then_else (and (eq_attr "alternative" "0")
13896                            (and (ge (minus (match_dup 0) (pc))
13897                                     (const_int -126))
13898                                 (lt (minus (match_dup 0) (pc))
13899                                     (const_int 128))))
13900                       (const_int 2)
13901                       (const_int 16)))
13902    ;; We don't know the type before shorten branches.  Optimistically expect
13903    ;; the loop instruction to match.
13904    (set (attr "type") (const_string "ibr"))])
13905
13906 (define_split
13907   [(set (pc)
13908         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13909                           (const_int 1))
13910                       (match_operand 0 "" "")
13911                       (pc)))
13912    (set (match_dup 1)
13913         (plus:SI (match_dup 1)
13914                  (const_int -1)))
13915    (clobber (match_scratch:SI 2 ""))
13916    (clobber (reg:CC 17))]
13917   "!TARGET_64BIT && TARGET_USE_LOOP
13918    && reload_completed
13919    && REGNO (operands[1]) != 2"
13920   [(parallel [(set (reg:CCZ 17)
13921                    (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13922                                  (const_int 0)))
13923               (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13924    (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13925                            (match_dup 0)
13926                            (pc)))]
13927   "")
13928   
13929 (define_split
13930   [(set (pc)
13931         (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13932                           (const_int 1))
13933                       (match_operand 0 "" "")
13934                       (pc)))
13935    (set (match_operand:SI 2 "nonimmediate_operand" "")
13936         (plus:SI (match_dup 1)
13937                  (const_int -1)))
13938    (clobber (match_scratch:SI 3 ""))
13939    (clobber (reg:CC 17))]
13940   "!TARGET_64BIT && TARGET_USE_LOOP
13941    && reload_completed
13942    && (! REG_P (operands[2])
13943        || ! rtx_equal_p (operands[1], operands[2]))"
13944   [(set (match_dup 3) (match_dup 1))
13945    (parallel [(set (reg:CCZ 17)
13946                    (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13947                                 (const_int 0)))
13948               (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13949    (set (match_dup 2) (match_dup 3))
13950    (set (pc) (if_then_else (ne (reg:CCZ 17) (const_int 0))
13951                            (match_dup 0)
13952                            (pc)))]
13953   "")
13954
13955 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13956
13957 (define_peephole2
13958   [(set (reg 17) (match_operand 0 "" ""))
13959    (set (match_operand:QI 1 "register_operand" "")
13960         (match_operator:QI 2 "ix86_comparison_operator"
13961           [(reg 17) (const_int 0)]))
13962    (set (match_operand 3 "q_regs_operand" "")
13963         (zero_extend (match_dup 1)))]
13964   "(peep2_reg_dead_p (3, operands[1])
13965     || operands_match_p (operands[1], operands[3]))
13966    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13967   [(set (match_dup 4) (match_dup 0))
13968    (set (strict_low_part (match_dup 5))
13969         (match_dup 2))]
13970 {
13971   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13972   operands[5] = gen_lowpart (QImode, operands[3]);
13973   ix86_expand_clear (operands[3]);
13974 })
13975
13976 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13977
13978 (define_peephole2
13979   [(set (reg 17) (match_operand 0 "" ""))
13980    (set (match_operand:QI 1 "register_operand" "")
13981         (match_operator:QI 2 "ix86_comparison_operator"
13982           [(reg 17) (const_int 0)]))
13983    (parallel [(set (match_operand 3 "q_regs_operand" "")
13984                    (zero_extend (match_dup 1)))
13985               (clobber (reg:CC 17))])]
13986   "(peep2_reg_dead_p (3, operands[1])
13987     || operands_match_p (operands[1], operands[3]))
13988    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13989   [(set (match_dup 4) (match_dup 0))
13990    (set (strict_low_part (match_dup 5))
13991         (match_dup 2))]
13992 {
13993   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13994   operands[5] = gen_lowpart (QImode, operands[3]);
13995   ix86_expand_clear (operands[3]);
13996 })
13997 \f
13998 ;; Call instructions.
13999
14000 ;; The predicates normally associated with named expanders are not properly
14001 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14002 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14003
14004 ;; Call subroutine returning no value.
14005
14006 (define_expand "call_pop"
14007   [(parallel [(call (match_operand:QI 0 "" "")
14008                     (match_operand:SI 1 "" ""))
14009               (set (reg:SI 7)
14010                    (plus:SI (reg:SI 7)
14011                             (match_operand:SI 3 "" "")))])]
14012   "!TARGET_64BIT"
14013 {
14014   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14015   DONE;
14016 })
14017
14018 (define_insn "*call_pop_0"
14019   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14020          (match_operand:SI 1 "" ""))
14021    (set (reg:SI 7) (plus:SI (reg:SI 7)
14022                             (match_operand:SI 2 "immediate_operand" "")))]
14023   "!TARGET_64BIT"
14024 {
14025   if (SIBLING_CALL_P (insn))
14026     return "jmp\t%P0";
14027   else
14028     return "call\t%P0";
14029 }
14030   [(set_attr "type" "call")])
14031   
14032 (define_insn "*call_pop_1"
14033   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14034          (match_operand:SI 1 "" ""))
14035    (set (reg:SI 7) (plus:SI (reg:SI 7)
14036                             (match_operand:SI 2 "immediate_operand" "i")))]
14037   "!TARGET_64BIT"
14038 {
14039   if (constant_call_address_operand (operands[0], Pmode))
14040     {
14041       if (SIBLING_CALL_P (insn))
14042         return "jmp\t%P0";
14043       else
14044         return "call\t%P0";
14045     }
14046   if (SIBLING_CALL_P (insn))
14047     return "jmp\t%A0";
14048   else
14049     return "call\t%A0";
14050 }
14051   [(set_attr "type" "call")])
14052
14053 (define_expand "call"
14054   [(call (match_operand:QI 0 "" "")
14055          (match_operand 1 "" ""))
14056    (use (match_operand 2 "" ""))]
14057   ""
14058 {
14059   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14060   DONE;
14061 })
14062
14063 (define_expand "sibcall"
14064   [(call (match_operand:QI 0 "" "")
14065          (match_operand 1 "" ""))
14066    (use (match_operand 2 "" ""))]
14067   ""
14068 {
14069   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14070   DONE;
14071 })
14072
14073 (define_insn "*call_0"
14074   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14075          (match_operand 1 "" ""))]
14076   ""
14077 {
14078   if (SIBLING_CALL_P (insn))
14079     return "jmp\t%P0";
14080   else
14081     return "call\t%P0";
14082 }
14083   [(set_attr "type" "call")])
14084
14085 (define_insn "*call_1"
14086   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14087          (match_operand 1 "" ""))]
14088   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14089 {
14090   if (constant_call_address_operand (operands[0], QImode))
14091     return "call\t%P0";
14092   return "call\t%A0";
14093 }
14094   [(set_attr "type" "call")])
14095
14096 (define_insn "*sibcall_1"
14097   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14098          (match_operand 1 "" ""))]
14099   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14100 {
14101   if (constant_call_address_operand (operands[0], QImode))
14102     return "jmp\t%P0";
14103   return "jmp\t%A0";
14104 }
14105   [(set_attr "type" "call")])
14106
14107 (define_insn "*call_1_rex64"
14108   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14109          (match_operand 1 "" ""))]
14110   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14111 {
14112   if (constant_call_address_operand (operands[0], QImode))
14113     return "call\t%P0";
14114   return "call\t%A0";
14115 }
14116   [(set_attr "type" "call")])
14117
14118 (define_insn "*sibcall_1_rex64"
14119   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14120          (match_operand 1 "" ""))]
14121   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14122   "jmp\t%P0"
14123   [(set_attr "type" "call")])
14124
14125 (define_insn "*sibcall_1_rex64_v"
14126   [(call (mem:QI (reg:DI 40))
14127          (match_operand 0 "" ""))]
14128   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14129   "jmp\t*%%r11"
14130   [(set_attr "type" "call")])
14131
14132
14133 ;; Call subroutine, returning value in operand 0
14134
14135 (define_expand "call_value_pop"
14136   [(parallel [(set (match_operand 0 "" "")
14137                    (call (match_operand:QI 1 "" "")
14138                          (match_operand:SI 2 "" "")))
14139               (set (reg:SI 7)
14140                    (plus:SI (reg:SI 7)
14141                             (match_operand:SI 4 "" "")))])]
14142   "!TARGET_64BIT"
14143 {
14144   ix86_expand_call (operands[0], operands[1], operands[2],
14145                     operands[3], operands[4], 0);
14146   DONE;
14147 })
14148
14149 (define_expand "call_value"
14150   [(set (match_operand 0 "" "")
14151         (call (match_operand:QI 1 "" "")
14152               (match_operand:SI 2 "" "")))
14153    (use (match_operand:SI 3 "" ""))]
14154   ;; Operand 2 not used on the i386.
14155   ""
14156 {
14157   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14158   DONE;
14159 })
14160
14161 (define_expand "sibcall_value"
14162   [(set (match_operand 0 "" "")
14163         (call (match_operand:QI 1 "" "")
14164               (match_operand:SI 2 "" "")))
14165    (use (match_operand:SI 3 "" ""))]
14166   ;; Operand 2 not used on the i386.
14167   ""
14168 {
14169   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14170   DONE;
14171 })
14172
14173 ;; Call subroutine returning any type.
14174
14175 (define_expand "untyped_call"
14176   [(parallel [(call (match_operand 0 "" "")
14177                     (const_int 0))
14178               (match_operand 1 "" "")
14179               (match_operand 2 "" "")])]
14180   ""
14181 {
14182   int i;
14183
14184   /* In order to give reg-stack an easier job in validating two
14185      coprocessor registers as containing a possible return value,
14186      simply pretend the untyped call returns a complex long double
14187      value.  */
14188
14189   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14190                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14191                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14192                     NULL, 0);
14193
14194   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14195     {
14196       rtx set = XVECEXP (operands[2], 0, i);
14197       emit_move_insn (SET_DEST (set), SET_SRC (set));
14198     }
14199
14200   /* The optimizer does not know that the call sets the function value
14201      registers we stored in the result block.  We avoid problems by
14202      claiming that all hard registers are used and clobbered at this
14203      point.  */
14204   emit_insn (gen_blockage (const0_rtx));
14205
14206   DONE;
14207 })
14208 \f
14209 ;; Prologue and epilogue instructions
14210
14211 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14212 ;; all of memory.  This blocks insns from being moved across this point.
14213
14214 (define_insn "blockage"
14215   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14216   ""
14217   ""
14218   [(set_attr "length" "0")])
14219
14220 ;; Insn emitted into the body of a function to return from a function.
14221 ;; This is only done if the function's epilogue is known to be simple.
14222 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14223
14224 (define_expand "return"
14225   [(return)]
14226   "ix86_can_use_return_insn_p ()"
14227 {
14228   if (current_function_pops_args)
14229     {
14230       rtx popc = GEN_INT (current_function_pops_args);
14231       emit_jump_insn (gen_return_pop_internal (popc));
14232       DONE;
14233     }
14234 })
14235
14236 (define_insn "return_internal"
14237   [(return)]
14238   "reload_completed"
14239   "ret"
14240   [(set_attr "length" "1")
14241    (set_attr "length_immediate" "0")
14242    (set_attr "modrm" "0")])
14243
14244 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14245 ;; instruction Athlon and K8 have.
14246
14247 (define_insn "return_internal_long"
14248   [(return)
14249    (unspec [(const_int 0)] UNSPEC_REP)]
14250   "reload_completed"
14251   "rep {;} ret"
14252   [(set_attr "length" "1")
14253    (set_attr "length_immediate" "0")
14254    (set_attr "prefix_rep" "1")
14255    (set_attr "modrm" "0")])
14256
14257 (define_insn "return_pop_internal"
14258   [(return)
14259    (use (match_operand:SI 0 "const_int_operand" ""))]
14260   "reload_completed"
14261   "ret\t%0"
14262   [(set_attr "length" "3")
14263    (set_attr "length_immediate" "2")
14264    (set_attr "modrm" "0")])
14265
14266 (define_insn "return_indirect_internal"
14267   [(return)
14268    (use (match_operand:SI 0 "register_operand" "r"))]
14269   "reload_completed"
14270   "jmp\t%A0"
14271   [(set_attr "type" "ibr")
14272    (set_attr "length_immediate" "0")])
14273
14274 (define_insn "nop"
14275   [(const_int 0)]
14276   ""
14277   "nop"
14278   [(set_attr "length" "1")
14279    (set_attr "length_immediate" "0")
14280    (set_attr "modrm" "0")
14281    (set_attr "ppro_uops" "one")])
14282
14283 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14284 ;; branch prediction penalty for the third jump in a 16-byte
14285 ;; block on K8.
14286
14287 (define_insn "align"
14288   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14289   ""
14290 {
14291 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14292   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14293 #else
14294   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14295      The align insn is used to avoid 3 jump instructions in the row to improve
14296      branch prediction and the benefits hardly outweight the cost of extra 8
14297      nops on the average inserted by full alignment pseudo operation.  */
14298 #endif
14299   return "";
14300 }
14301   [(set_attr "length" "16")])
14302
14303 (define_expand "prologue"
14304   [(const_int 1)]
14305   ""
14306   "ix86_expand_prologue (); DONE;")
14307
14308 (define_insn "set_got"
14309   [(set (match_operand:SI 0 "register_operand" "=r")
14310         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14311    (clobber (reg:CC 17))]
14312   "!TARGET_64BIT"
14313   { return output_set_got (operands[0]); }
14314   [(set_attr "type" "multi")
14315    (set_attr "length" "12")])
14316
14317 (define_expand "epilogue"
14318   [(const_int 1)]
14319   ""
14320   "ix86_expand_epilogue (1); DONE;")
14321
14322 (define_expand "sibcall_epilogue"
14323   [(const_int 1)]
14324   ""
14325   "ix86_expand_epilogue (0); DONE;")
14326
14327 (define_expand "eh_return"
14328   [(use (match_operand 0 "register_operand" ""))]
14329   ""
14330 {
14331   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14332
14333   /* Tricky bit: we write the address of the handler to which we will
14334      be returning into someone else's stack frame, one word below the
14335      stack address we wish to restore.  */
14336   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14337   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14338   tmp = gen_rtx_MEM (Pmode, tmp);
14339   emit_move_insn (tmp, ra);
14340
14341   if (Pmode == SImode)
14342     emit_insn (gen_eh_return_si (sa));
14343   else
14344     emit_insn (gen_eh_return_di (sa));
14345   emit_barrier ();
14346   DONE;
14347 })
14348
14349 (define_insn_and_split "eh_return_si"
14350   [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")]
14351                     UNSPECV_EH_RETURN)]
14352   "!TARGET_64BIT"
14353   "#"
14354   "reload_completed"
14355   [(const_int 1)]
14356   "ix86_expand_epilogue (2); DONE;")
14357
14358 (define_insn_and_split "eh_return_di"
14359   [(unspec_volatile [(match_operand:DI 0 "register_operand" "c")]
14360                     UNSPECV_EH_RETURN)]
14361   "TARGET_64BIT"
14362   "#"
14363   "reload_completed"
14364   [(const_int 1)]
14365   "ix86_expand_epilogue (2); DONE;")
14366
14367 (define_insn "leave"
14368   [(set (reg:SI 7) (plus:SI (reg:SI 6) (const_int 4)))
14369    (set (reg:SI 6) (mem:SI (reg:SI 6)))
14370    (clobber (mem:BLK (scratch)))]
14371   "!TARGET_64BIT"
14372   "leave"
14373   [(set_attr "type" "leave")])
14374
14375 (define_insn "leave_rex64"
14376   [(set (reg:DI 7) (plus:DI (reg:DI 6) (const_int 8)))
14377    (set (reg:DI 6) (mem:DI (reg:DI 6)))
14378    (clobber (mem:BLK (scratch)))]
14379   "TARGET_64BIT"
14380   "leave"
14381   [(set_attr "type" "leave")])
14382 \f
14383 (define_expand "ffssi2"
14384   [(parallel
14385      [(set (match_operand:SI 0 "register_operand" "") 
14386            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14387       (clobber (match_scratch:SI 2 ""))
14388       (clobber (reg:CC 17))])]
14389   ""
14390   "")
14391
14392 (define_insn_and_split "*ffs_cmove"
14393   [(set (match_operand:SI 0 "register_operand" "=r") 
14394         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14395    (clobber (match_scratch:SI 2 "=&r"))
14396    (clobber (reg:CC 17))]
14397   "TARGET_CMOVE"
14398   "#"
14399   "&& reload_completed"
14400   [(set (match_dup 2) (const_int -1))
14401    (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14402               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14403    (set (match_dup 0) (if_then_else:SI
14404                         (eq (reg:CCZ 17) (const_int 0))
14405                         (match_dup 2)
14406                         (match_dup 0)))
14407    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14408               (clobber (reg:CC 17))])]
14409   "")
14410
14411 (define_insn_and_split "*ffs_no_cmove"
14412   [(set (match_operand:SI 0 "nonimmediate_operand" "=r") 
14413         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14414    (clobber (match_scratch:SI 2 "=&r"))
14415    (clobber (reg:CC 17))]
14416   ""
14417   "#"
14418   "reload_completed"
14419   [(parallel [(set (match_dup 2) (const_int 0))
14420               (clobber (reg:CC 17))])
14421    (parallel [(set (reg:CCZ 17) (compare:CCZ (match_dup 1) (const_int 0)))
14422               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14423    (set (strict_low_part (match_dup 3))
14424         (eq:QI (reg:CCZ 17) (const_int 0)))
14425    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14426               (clobber (reg:CC 17))])
14427    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14428               (clobber (reg:CC 17))])
14429    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14430               (clobber (reg:CC 17))])]
14431 {
14432   operands[3] = gen_lowpart (QImode, operands[2]);
14433 })
14434
14435 (define_insn "*ffssi_1"
14436   [(set (reg:CCZ 17)
14437         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14438                      (const_int 0)))
14439    (set (match_operand:SI 0 "register_operand" "=r")
14440         (ctz:SI (match_dup 1)))]
14441   ""
14442   "bsf{l}\t{%1, %0|%0, %1}"
14443   [(set_attr "prefix_0f" "1")
14444    (set_attr "ppro_uops" "few")])
14445
14446 (define_insn "ctzsi2"
14447   [(set (match_operand:SI 0 "register_operand" "=r")
14448         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14449    (clobber (reg:CC 17))]
14450   ""
14451   "bsf{l}\t{%1, %0|%0, %1}"
14452   [(set_attr "prefix_0f" "1")
14453    (set_attr "ppro_uops" "few")])
14454
14455 (define_expand "clzsi2"
14456   [(parallel
14457      [(set (match_operand:SI 0 "register_operand" "")
14458            (minus:SI (const_int 31)
14459                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14460       (clobber (reg:CC 17))])
14461    (parallel
14462      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14463       (clobber (reg:CC 17))])]
14464   ""
14465   "")
14466
14467 (define_insn "*bsr"
14468   [(set (match_operand:SI 0 "register_operand" "=r")
14469         (minus:SI (const_int 31)
14470                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14471    (clobber (reg:CC 17))]
14472   ""
14473   "bsr{l}\t{%1, %0|%0, %1}"
14474   [(set_attr "prefix_0f" "1")
14475    (set_attr "ppro_uops" "few")])
14476 \f
14477 ;; Thread-local storage patterns for ELF.
14478 ;;
14479 ;; Note that these code sequences must appear exactly as shown
14480 ;; in order to allow linker relaxation.
14481
14482 (define_insn "*tls_global_dynamic_32_gnu"
14483   [(set (match_operand:SI 0 "register_operand" "=a")
14484         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14485                     (match_operand:SI 2 "tls_symbolic_operand" "")
14486                     (match_operand:SI 3 "call_insn_operand" "")]
14487                     UNSPEC_TLS_GD))
14488    (clobber (match_scratch:SI 4 "=d"))
14489    (clobber (match_scratch:SI 5 "=c"))
14490    (clobber (reg:CC 17))]
14491   "!TARGET_64BIT && TARGET_GNU_TLS"
14492   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14493   [(set_attr "type" "multi")
14494    (set_attr "length" "12")])
14495
14496 (define_insn "*tls_global_dynamic_32_sun"
14497   [(set (match_operand:SI 0 "register_operand" "=a")
14498         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14499                     (match_operand:SI 2 "tls_symbolic_operand" "")
14500                     (match_operand:SI 3 "call_insn_operand" "")]
14501                     UNSPEC_TLS_GD))
14502    (clobber (match_scratch:SI 4 "=d"))
14503    (clobber (match_scratch:SI 5 "=c"))
14504    (clobber (reg:CC 17))]
14505   "!TARGET_64BIT && TARGET_SUN_TLS"
14506   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14507         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14508   [(set_attr "type" "multi")
14509    (set_attr "length" "14")])
14510
14511 (define_expand "tls_global_dynamic_32"
14512   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14513                    (unspec:SI
14514                     [(match_dup 2)
14515                      (match_operand:SI 1 "tls_symbolic_operand" "")
14516                      (match_dup 3)]
14517                     UNSPEC_TLS_GD))
14518               (clobber (match_scratch:SI 4 ""))
14519               (clobber (match_scratch:SI 5 ""))
14520               (clobber (reg:CC 17))])]
14521   ""
14522 {
14523   if (flag_pic)
14524     operands[2] = pic_offset_table_rtx;
14525   else
14526     {
14527       operands[2] = gen_reg_rtx (Pmode);
14528       emit_insn (gen_set_got (operands[2]));
14529     }
14530   operands[3] = ix86_tls_get_addr ();
14531 })
14532
14533 (define_insn "*tls_global_dynamic_64"
14534   [(set (match_operand:DI 0 "register_operand" "=a")
14535         (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14536                       (match_operand:DI 3 "" "")))
14537    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14538               UNSPEC_TLS_GD)]
14539   "TARGET_64BIT"
14540   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14541   [(set_attr "type" "multi")
14542    (set_attr "length" "16")])
14543
14544 (define_expand "tls_global_dynamic_64"
14545   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14546                    (call (mem:QI (match_dup 2)) (const_int 0)))
14547               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14548                          UNSPEC_TLS_GD)])]
14549   ""
14550 {
14551   operands[2] = ix86_tls_get_addr ();
14552 })
14553
14554 (define_insn "*tls_local_dynamic_base_32_gnu"
14555   [(set (match_operand:SI 0 "register_operand" "=a")
14556         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14557                     (match_operand:SI 2 "call_insn_operand" "")]
14558                    UNSPEC_TLS_LD_BASE))
14559    (clobber (match_scratch:SI 3 "=d"))
14560    (clobber (match_scratch:SI 4 "=c"))
14561    (clobber (reg:CC 17))]
14562   "!TARGET_64BIT && TARGET_GNU_TLS"
14563   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14564   [(set_attr "type" "multi")
14565    (set_attr "length" "11")])
14566
14567 (define_insn "*tls_local_dynamic_base_32_sun"
14568   [(set (match_operand:SI 0 "register_operand" "=a")
14569         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14570                     (match_operand:SI 2 "call_insn_operand" "")]
14571                    UNSPEC_TLS_LD_BASE))
14572    (clobber (match_scratch:SI 3 "=d"))
14573    (clobber (match_scratch:SI 4 "=c"))
14574    (clobber (reg:CC 17))]
14575   "!TARGET_64BIT && TARGET_SUN_TLS"
14576   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14577         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14578   [(set_attr "type" "multi")
14579    (set_attr "length" "13")])
14580
14581 (define_expand "tls_local_dynamic_base_32"
14582   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14583                    (unspec:SI [(match_dup 1) (match_dup 2)]
14584                               UNSPEC_TLS_LD_BASE))
14585               (clobber (match_scratch:SI 3 ""))
14586               (clobber (match_scratch:SI 4 ""))
14587               (clobber (reg:CC 17))])]
14588   ""
14589 {
14590   if (flag_pic)
14591     operands[1] = pic_offset_table_rtx;
14592   else
14593     {
14594       operands[1] = gen_reg_rtx (Pmode);
14595       emit_insn (gen_set_got (operands[1]));
14596     }
14597   operands[2] = ix86_tls_get_addr ();
14598 })
14599
14600 (define_insn "*tls_local_dynamic_base_64"
14601   [(set (match_operand:DI 0 "register_operand" "=a")
14602         (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14603                       (match_operand:DI 2 "" "")))
14604    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14605   "TARGET_64BIT"
14606   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14607   [(set_attr "type" "multi")
14608    (set_attr "length" "12")])
14609
14610 (define_expand "tls_local_dynamic_base_64"
14611   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14612                    (call (mem:QI (match_dup 1)) (const_int 0)))
14613               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14614   ""
14615 {
14616   operands[1] = ix86_tls_get_addr ();
14617 })
14618
14619 ;; Local dynamic of a single variable is a lose.  Show combine how
14620 ;; to convert that back to global dynamic.
14621
14622 (define_insn_and_split "*tls_local_dynamic_32_once"
14623   [(set (match_operand:SI 0 "register_operand" "=a")
14624         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14625                              (match_operand:SI 2 "call_insn_operand" "")]
14626                             UNSPEC_TLS_LD_BASE)
14627                  (const:SI (unspec:SI
14628                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14629                             UNSPEC_DTPOFF))))
14630    (clobber (match_scratch:SI 4 "=d"))
14631    (clobber (match_scratch:SI 5 "=c"))
14632    (clobber (reg:CC 17))]
14633   ""
14634   "#"
14635   ""
14636   [(parallel [(set (match_dup 0)
14637                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14638                               UNSPEC_TLS_GD))
14639               (clobber (match_dup 4))
14640               (clobber (match_dup 5))
14641               (clobber (reg:CC 17))])]
14642   "")
14643
14644 ;; Load and add the thread base pointer from %gs:0.
14645
14646 (define_insn "*load_tp_si"
14647   [(set (match_operand:SI 0 "register_operand" "=r")
14648         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14649   "!TARGET_64BIT"
14650   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14651   [(set_attr "type" "imov")
14652    (set_attr "modrm" "0")
14653    (set_attr "length" "7")
14654    (set_attr "memory" "load")
14655    (set_attr "imm_disp" "false")])
14656
14657 (define_insn "*add_tp_si"
14658   [(set (match_operand:SI 0 "register_operand" "=r")
14659         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14660                  (match_operand:SI 1 "register_operand" "0")))
14661    (clobber (reg:CC 17))]
14662   "!TARGET_64BIT"
14663   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14664   [(set_attr "type" "alu")
14665    (set_attr "modrm" "0")
14666    (set_attr "length" "7")
14667    (set_attr "memory" "load")
14668    (set_attr "imm_disp" "false")])
14669
14670 (define_insn "*load_tp_di"
14671   [(set (match_operand:DI 0 "register_operand" "=r")
14672         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14673   "TARGET_64BIT"
14674   "mov{l}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14675   [(set_attr "type" "imov")
14676    (set_attr "modrm" "0")
14677    (set_attr "length" "7")
14678    (set_attr "memory" "load")
14679    (set_attr "imm_disp" "false")])
14680
14681 (define_insn "*add_tp_di"
14682   [(set (match_operand:DI 0 "register_operand" "=r")
14683         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14684                  (match_operand:DI 1 "register_operand" "0")))
14685    (clobber (reg:CC 17))]
14686   "TARGET_64BIT"
14687   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14688   [(set_attr "type" "alu")
14689    (set_attr "modrm" "0")
14690    (set_attr "length" "7")
14691    (set_attr "memory" "load")
14692    (set_attr "imm_disp" "false")])
14693 \f
14694 ;; These patterns match the binary 387 instructions for addM3, subM3,
14695 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14696 ;; SFmode.  The first is the normal insn, the second the same insn but
14697 ;; with one operand a conversion, and the third the same insn but with
14698 ;; the other operand a conversion.  The conversion may be SFmode or
14699 ;; SImode if the target mode DFmode, but only SImode if the target mode
14700 ;; is SFmode.
14701
14702 ;; Gcc is slightly more smart about handling normal two address instructions
14703 ;; so use special patterns for add and mull.
14704 (define_insn "*fop_sf_comm_nosse"
14705   [(set (match_operand:SF 0 "register_operand" "=f")
14706         (match_operator:SF 3 "binary_fp_operator"
14707                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14708                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14709   "TARGET_80387 && !TARGET_SSE_MATH
14710    && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14711    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14712   "* return output_387_binary_op (insn, operands);"
14713   [(set (attr "type") 
14714         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14715            (const_string "fmul")
14716            (const_string "fop")))
14717    (set_attr "mode" "SF")])
14718
14719 (define_insn "*fop_sf_comm"
14720   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14721         (match_operator:SF 3 "binary_fp_operator"
14722                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14723                          (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14724   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14725    && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14726    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14727   "* return output_387_binary_op (insn, operands);"
14728   [(set (attr "type") 
14729         (if_then_else (eq_attr "alternative" "1")
14730            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14731               (const_string "ssemul")
14732               (const_string "sseadd"))
14733            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14734               (const_string "fmul")
14735               (const_string "fop"))))
14736    (set_attr "mode" "SF")])
14737
14738 (define_insn "*fop_sf_comm_sse"
14739   [(set (match_operand:SF 0 "register_operand" "=x")
14740         (match_operator:SF 3 "binary_fp_operator"
14741                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
14742                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14743   "TARGET_SSE_MATH && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14744    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14745   "* return output_387_binary_op (insn, operands);"
14746   [(set (attr "type") 
14747         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14748            (const_string "ssemul")
14749            (const_string "sseadd")))
14750    (set_attr "mode" "SF")])
14751
14752 (define_insn "*fop_df_comm_nosse"
14753   [(set (match_operand:DF 0 "register_operand" "=f")
14754         (match_operator:DF 3 "binary_fp_operator"
14755                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14756                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14757   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14758    && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14759    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14760   "* return output_387_binary_op (insn, operands);"
14761   [(set (attr "type") 
14762         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14763            (const_string "fmul")
14764            (const_string "fop")))
14765    (set_attr "mode" "DF")])
14766
14767 (define_insn "*fop_df_comm"
14768   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14769         (match_operator:DF 3 "binary_fp_operator"
14770                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14771                          (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14772   "TARGET_80387 && TARGET_SSE_MATH && TARGET_SSE2 && TARGET_MIX_SSE_I387
14773    && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14774    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14775   "* return output_387_binary_op (insn, operands);"
14776   [(set (attr "type") 
14777         (if_then_else (eq_attr "alternative" "1")
14778            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14779               (const_string "ssemul")
14780               (const_string "sseadd"))
14781            (if_then_else (match_operand:SF 3 "mult_operator" "") 
14782               (const_string "fmul")
14783               (const_string "fop"))))
14784    (set_attr "mode" "DF")])
14785
14786 (define_insn "*fop_df_comm_sse"
14787   [(set (match_operand:DF 0 "register_operand" "=Y")
14788         (match_operator:DF 3 "binary_fp_operator"
14789                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
14790                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14791   "TARGET_SSE2 && TARGET_SSE_MATH
14792    && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'
14793    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14794   "* return output_387_binary_op (insn, operands);"
14795   [(set (attr "type") 
14796         (if_then_else (match_operand:SF 3 "mult_operator" "") 
14797            (const_string "ssemul")
14798            (const_string "sseadd")))
14799    (set_attr "mode" "DF")])
14800
14801 (define_insn "*fop_xf_comm"
14802   [(set (match_operand:XF 0 "register_operand" "=f")
14803         (match_operator:XF 3 "binary_fp_operator"
14804                         [(match_operand:XF 1 "register_operand" "%0")
14805                          (match_operand:XF 2 "register_operand" "f")]))]
14806   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
14807    && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14808   "* return output_387_binary_op (insn, operands);"
14809   [(set (attr "type") 
14810         (if_then_else (match_operand:XF 3 "mult_operator" "") 
14811            (const_string "fmul")
14812            (const_string "fop")))
14813    (set_attr "mode" "XF")])
14814
14815 (define_insn "*fop_tf_comm"
14816   [(set (match_operand:TF 0 "register_operand" "=f")
14817         (match_operator:TF 3 "binary_fp_operator"
14818                         [(match_operand:TF 1 "register_operand" "%0")
14819                          (match_operand:TF 2 "register_operand" "f")]))]
14820   "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
14821   "* return output_387_binary_op (insn, operands);"
14822   [(set (attr "type") 
14823         (if_then_else (match_operand:TF 3 "mult_operator" "") 
14824            (const_string "fmul")
14825            (const_string "fop")))
14826    (set_attr "mode" "XF")])
14827
14828 (define_insn "*fop_sf_1_nosse"
14829   [(set (match_operand:SF 0 "register_operand" "=f,f")
14830         (match_operator:SF 3 "binary_fp_operator"
14831                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14832                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14833   "TARGET_80387 && !TARGET_SSE_MATH
14834    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14835    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14836   "* return output_387_binary_op (insn, operands);"
14837   [(set (attr "type") 
14838         (cond [(match_operand:SF 3 "mult_operator" "") 
14839                  (const_string "fmul")
14840                (match_operand:SF 3 "div_operator" "") 
14841                  (const_string "fdiv")
14842               ]
14843               (const_string "fop")))
14844    (set_attr "mode" "SF")])
14845
14846 (define_insn "*fop_sf_1"
14847   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14848         (match_operator:SF 3 "binary_fp_operator"
14849                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14850                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14851   "TARGET_80387 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14852    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14853    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14854   "* return output_387_binary_op (insn, operands);"
14855   [(set (attr "type") 
14856         (cond [(and (eq_attr "alternative" "2")
14857                     (match_operand:SF 3 "mult_operator" ""))
14858                  (const_string "ssemul")
14859                (and (eq_attr "alternative" "2")
14860                     (match_operand:SF 3 "div_operator" ""))
14861                  (const_string "ssediv")
14862                (eq_attr "alternative" "2")
14863                  (const_string "sseadd")
14864                (match_operand:SF 3 "mult_operator" "") 
14865                  (const_string "fmul")
14866                (match_operand:SF 3 "div_operator" "") 
14867                  (const_string "fdiv")
14868               ]
14869               (const_string "fop")))
14870    (set_attr "mode" "SF")])
14871
14872 (define_insn "*fop_sf_1_sse"
14873   [(set (match_operand:SF 0 "register_operand" "=x")
14874         (match_operator:SF 3 "binary_fp_operator"
14875                         [(match_operand:SF 1 "register_operand" "0")
14876                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14877   "TARGET_SSE_MATH
14878    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14879   "* return output_387_binary_op (insn, operands);"
14880   [(set (attr "type") 
14881         (cond [(match_operand:SF 3 "mult_operator" "")
14882                  (const_string "ssemul")
14883                (match_operand:SF 3 "div_operator" "")
14884                  (const_string "ssediv")
14885               ]
14886               (const_string "sseadd")))
14887    (set_attr "mode" "SF")])
14888
14889 ;; ??? Add SSE splitters for these!
14890 (define_insn "*fop_sf_2"
14891   [(set (match_operand:SF 0 "register_operand" "=f,f")
14892         (match_operator:SF 3 "binary_fp_operator"
14893           [(float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14894            (match_operand:SF 2 "register_operand" "0,0")]))]
14895   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14896   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14897   [(set (attr "type") 
14898         (cond [(match_operand:SF 3 "mult_operator" "") 
14899                  (const_string "fmul")
14900                (match_operand:SF 3 "div_operator" "") 
14901                  (const_string "fdiv")
14902               ]
14903               (const_string "fop")))
14904    (set_attr "fp_int_src" "true")
14905    (set_attr "ppro_uops" "many")
14906    (set_attr "mode" "SI")])
14907
14908 (define_insn "*fop_sf_3"
14909   [(set (match_operand:SF 0 "register_operand" "=f,f")
14910         (match_operator:SF 3 "binary_fp_operator"
14911           [(match_operand:SF 1 "register_operand" "0,0")
14912            (float:SF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
14913   "TARGET_80387 && TARGET_USE_FIOP && !TARGET_SSE_MATH"
14914   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14915   [(set (attr "type") 
14916         (cond [(match_operand:SF 3 "mult_operator" "") 
14917                  (const_string "fmul")
14918                (match_operand:SF 3 "div_operator" "") 
14919                  (const_string "fdiv")
14920               ]
14921               (const_string "fop")))
14922    (set_attr "fp_int_src" "true")
14923    (set_attr "ppro_uops" "many")
14924    (set_attr "mode" "SI")])
14925
14926 (define_insn "*fop_df_1_nosse"
14927   [(set (match_operand:DF 0 "register_operand" "=f,f")
14928         (match_operator:DF 3 "binary_fp_operator"
14929                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14930                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14931   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
14932    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14933    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14934   "* return output_387_binary_op (insn, operands);"
14935   [(set (attr "type") 
14936         (cond [(match_operand:DF 3 "mult_operator" "") 
14937                  (const_string "fmul")
14938                (match_operand:DF 3 "div_operator" "")
14939                  (const_string "fdiv")
14940               ]
14941               (const_string "fop")))
14942    (set_attr "mode" "DF")])
14943
14944
14945 (define_insn "*fop_df_1"
14946   [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14947         (match_operator:DF 3 "binary_fp_operator"
14948                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14949                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14950   "TARGET_80387 && TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14951    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'
14952    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14953   "* return output_387_binary_op (insn, operands);"
14954   [(set (attr "type") 
14955         (cond [(and (eq_attr "alternative" "2")
14956                     (match_operand:SF 3 "mult_operator" ""))
14957                  (const_string "ssemul")
14958                (and (eq_attr "alternative" "2")
14959                     (match_operand:SF 3 "div_operator" ""))
14960                  (const_string "ssediv")
14961                (eq_attr "alternative" "2")
14962                  (const_string "sseadd")
14963                (match_operand:DF 3 "mult_operator" "") 
14964                  (const_string "fmul")
14965                (match_operand:DF 3 "div_operator" "") 
14966                  (const_string "fdiv")
14967               ]
14968               (const_string "fop")))
14969    (set_attr "mode" "DF")])
14970
14971 (define_insn "*fop_df_1_sse"
14972   [(set (match_operand:DF 0 "register_operand" "=Y")
14973         (match_operator:DF 3 "binary_fp_operator"
14974                         [(match_operand:DF 1 "register_operand" "0")
14975                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14976   "TARGET_SSE2 && TARGET_SSE_MATH
14977    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
14978   "* return output_387_binary_op (insn, operands);"
14979   [(set_attr "mode" "DF")
14980    (set (attr "type") 
14981         (cond [(match_operand:SF 3 "mult_operator" "")
14982                  (const_string "ssemul")
14983                (match_operand:SF 3 "div_operator" "")
14984                  (const_string "ssediv")
14985               ]
14986               (const_string "sseadd")))])
14987
14988 ;; ??? Add SSE splitters for these!
14989 (define_insn "*fop_df_2"
14990   [(set (match_operand:DF 0 "register_operand" "=f,f")
14991         (match_operator:DF 3 "binary_fp_operator"
14992            [(float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
14993             (match_operand:DF 2 "register_operand" "0,0")]))]
14994   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14995   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14996   [(set (attr "type") 
14997         (cond [(match_operand:DF 3 "mult_operator" "") 
14998                  (const_string "fmul")
14999                (match_operand:DF 3 "div_operator" "") 
15000                  (const_string "fdiv")
15001               ]
15002               (const_string "fop")))
15003    (set_attr "fp_int_src" "true")
15004    (set_attr "ppro_uops" "many")
15005    (set_attr "mode" "SI")])
15006
15007 (define_insn "*fop_df_3"
15008   [(set (match_operand:DF 0 "register_operand" "=f,f")
15009         (match_operator:DF 3 "binary_fp_operator"
15010            [(match_operand:DF 1 "register_operand" "0,0")
15011             (float:DF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
15012   "TARGET_80387 && TARGET_USE_FIOP && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15013   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15014   [(set (attr "type") 
15015         (cond [(match_operand:DF 3 "mult_operator" "") 
15016                  (const_string "fmul")
15017                (match_operand:DF 3 "div_operator" "") 
15018                  (const_string "fdiv")
15019               ]
15020               (const_string "fop")))
15021    (set_attr "fp_int_src" "true")
15022    (set_attr "ppro_uops" "many")
15023    (set_attr "mode" "SI")])
15024
15025 (define_insn "*fop_df_4"
15026   [(set (match_operand:DF 0 "register_operand" "=f,f")
15027         (match_operator:DF 3 "binary_fp_operator"
15028            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15029             (match_operand:DF 2 "register_operand" "0,f")]))]
15030   "TARGET_80387 && (!TARGET_SSE2 || !TARGET_SSE_MATH)
15031    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15032   "* return output_387_binary_op (insn, operands);"
15033   [(set (attr "type") 
15034         (cond [(match_operand:DF 3 "mult_operator" "") 
15035                  (const_string "fmul")
15036                (match_operand:DF 3 "div_operator" "") 
15037                  (const_string "fdiv")
15038               ]
15039               (const_string "fop")))
15040    (set_attr "mode" "SF")])
15041
15042 (define_insn "*fop_df_5"
15043   [(set (match_operand:DF 0 "register_operand" "=f,f")
15044         (match_operator:DF 3 "binary_fp_operator"
15045           [(match_operand:DF 1 "register_operand" "0,f")
15046            (float_extend:DF
15047             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15048   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15049   "* return output_387_binary_op (insn, operands);"
15050   [(set (attr "type") 
15051         (cond [(match_operand:DF 3 "mult_operator" "") 
15052                  (const_string "fmul")
15053                (match_operand:DF 3 "div_operator" "") 
15054                  (const_string "fdiv")
15055               ]
15056               (const_string "fop")))
15057    (set_attr "mode" "SF")])
15058
15059 (define_insn "*fop_df_6"
15060   [(set (match_operand:DF 0 "register_operand" "=f,f")
15061         (match_operator:DF 3 "binary_fp_operator"
15062           [(float_extend:DF
15063             (match_operand:SF 1 "register_operand" "0,f"))
15064            (float_extend:DF
15065             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15066   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15067   "* return output_387_binary_op (insn, operands);"
15068   [(set (attr "type") 
15069         (cond [(match_operand:DF 3 "mult_operator" "") 
15070                  (const_string "fmul")
15071                (match_operand:DF 3 "div_operator" "") 
15072                  (const_string "fdiv")
15073               ]
15074               (const_string "fop")))
15075    (set_attr "mode" "SF")])
15076
15077 (define_insn "*fop_xf_1"
15078   [(set (match_operand:XF 0 "register_operand" "=f,f")
15079         (match_operator:XF 3 "binary_fp_operator"
15080                         [(match_operand:XF 1 "register_operand" "0,f")
15081                          (match_operand:XF 2 "register_operand" "f,0")]))]
15082   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387
15083    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
15084   "* return output_387_binary_op (insn, operands);"
15085   [(set (attr "type") 
15086         (cond [(match_operand:XF 3 "mult_operator" "") 
15087                  (const_string "fmul")
15088                (match_operand:XF 3 "div_operator" "") 
15089                  (const_string "fdiv")
15090               ]
15091               (const_string "fop")))
15092    (set_attr "mode" "XF")])
15093
15094 (define_insn "*fop_tf_1"
15095   [(set (match_operand:TF 0 "register_operand" "=f,f")
15096         (match_operator:TF 3 "binary_fp_operator"
15097                         [(match_operand:TF 1 "register_operand" "0,f")
15098                          (match_operand:TF 2 "register_operand" "f,0")]))]
15099   "TARGET_80387
15100    && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
15101   "* return output_387_binary_op (insn, operands);"
15102   [(set (attr "type") 
15103         (cond [(match_operand:TF 3 "mult_operator" "") 
15104                  (const_string "fmul")
15105                (match_operand:TF 3 "div_operator" "") 
15106                  (const_string "fdiv")
15107               ]
15108               (const_string "fop")))
15109    (set_attr "mode" "XF")])
15110
15111 (define_insn "*fop_xf_2"
15112   [(set (match_operand:XF 0 "register_operand" "=f,f")
15113         (match_operator:XF 3 "binary_fp_operator"
15114            [(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
15115             (match_operand:XF 2 "register_operand" "0,0")]))]
15116   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && TARGET_USE_FIOP"
15117   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15118   [(set (attr "type") 
15119         (cond [(match_operand:XF 3 "mult_operator" "") 
15120                  (const_string "fmul")
15121                (match_operand:XF 3 "div_operator" "") 
15122                  (const_string "fdiv")
15123               ]
15124               (const_string "fop")))
15125    (set_attr "fp_int_src" "true")
15126    (set_attr "mode" "SI")
15127    (set_attr "ppro_uops" "many")])
15128
15129 (define_insn "*fop_tf_2"
15130   [(set (match_operand:TF 0 "register_operand" "=f,f")
15131         (match_operator:TF 3 "binary_fp_operator"
15132            [(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
15133             (match_operand:TF 2 "register_operand" "0,0")]))]
15134   "TARGET_80387 && TARGET_USE_FIOP"
15135   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15136   [(set (attr "type") 
15137         (cond [(match_operand:TF 3 "mult_operator" "") 
15138                  (const_string "fmul")
15139                (match_operand:TF 3 "div_operator" "") 
15140                  (const_string "fdiv")
15141               ]
15142               (const_string "fop")))
15143    (set_attr "fp_int_src" "true")
15144    (set_attr "mode" "SI")
15145    (set_attr "ppro_uops" "many")])
15146
15147 (define_insn "*fop_xf_3"
15148   [(set (match_operand:XF 0 "register_operand" "=f,f")
15149         (match_operator:XF 3 "binary_fp_operator"
15150           [(match_operand:XF 1 "register_operand" "0,0")
15151            (float:XF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
15152   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && TARGET_USE_FIOP"
15153   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15154   [(set (attr "type") 
15155         (cond [(match_operand:XF 3 "mult_operator" "") 
15156                  (const_string "fmul")
15157                (match_operand:XF 3 "div_operator" "") 
15158                  (const_string "fdiv")
15159               ]
15160               (const_string "fop")))
15161    (set_attr "fp_int_src" "true")
15162    (set_attr "mode" "SI")
15163    (set_attr "ppro_uops" "many")])
15164
15165 (define_insn "*fop_tf_3"
15166   [(set (match_operand:TF 0 "register_operand" "=f,f")
15167         (match_operator:TF 3 "binary_fp_operator"
15168           [(match_operand:TF 1 "register_operand" "0,0")
15169            (float:TF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
15170   "TARGET_80387 && TARGET_USE_FIOP"
15171   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15172   [(set (attr "type") 
15173         (cond [(match_operand:TF 3 "mult_operator" "") 
15174                  (const_string "fmul")
15175                (match_operand:TF 3 "div_operator" "") 
15176                  (const_string "fdiv")
15177               ]
15178               (const_string "fop")))
15179    (set_attr "fp_int_src" "true")
15180    (set_attr "mode" "SI")
15181    (set_attr "ppro_uops" "many")])
15182
15183 (define_insn "*fop_xf_4"
15184   [(set (match_operand:XF 0 "register_operand" "=f,f")
15185         (match_operator:XF 3 "binary_fp_operator"
15186            [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15187             (match_operand:XF 2 "register_operand" "0,f")]))]
15188   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
15189   "* return output_387_binary_op (insn, operands);"
15190   [(set (attr "type") 
15191         (cond [(match_operand:XF 3 "mult_operator" "") 
15192                  (const_string "fmul")
15193                (match_operand:XF 3 "div_operator" "") 
15194                  (const_string "fdiv")
15195               ]
15196               (const_string "fop")))
15197    (set_attr "mode" "SF")])
15198
15199 (define_insn "*fop_tf_4"
15200   [(set (match_operand:TF 0 "register_operand" "=f,f")
15201         (match_operator:TF 3 "binary_fp_operator"
15202            [(float_extend:TF (match_operand 1 "nonimmediate_operand" "fm,0"))
15203             (match_operand:TF 2 "register_operand" "0,f")]))]
15204   "TARGET_80387"
15205   "* return output_387_binary_op (insn, operands);"
15206   [(set (attr "type") 
15207         (cond [(match_operand:TF 3 "mult_operator" "") 
15208                  (const_string "fmul")
15209                (match_operand:TF 3 "div_operator" "") 
15210                  (const_string "fdiv")
15211               ]
15212               (const_string "fop")))
15213    (set_attr "mode" "SF")])
15214
15215 (define_insn "*fop_xf_5"
15216   [(set (match_operand:XF 0 "register_operand" "=f,f")
15217         (match_operator:XF 3 "binary_fp_operator"
15218           [(match_operand:XF 1 "register_operand" "0,f")
15219            (float_extend:XF
15220             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15221   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
15222   "* return output_387_binary_op (insn, operands);"
15223   [(set (attr "type") 
15224         (cond [(match_operand:XF 3 "mult_operator" "") 
15225                  (const_string "fmul")
15226                (match_operand:XF 3 "div_operator" "") 
15227                  (const_string "fdiv")
15228               ]
15229               (const_string "fop")))
15230    (set_attr "mode" "SF")])
15231
15232 (define_insn "*fop_tf_5"
15233   [(set (match_operand:TF 0 "register_operand" "=f,f")
15234         (match_operator:TF 3 "binary_fp_operator"
15235           [(match_operand:TF 1 "register_operand" "0,f")
15236            (float_extend:TF
15237             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15238   "TARGET_80387"
15239   "* return output_387_binary_op (insn, operands);"
15240   [(set (attr "type") 
15241         (cond [(match_operand:TF 3 "mult_operator" "") 
15242                  (const_string "fmul")
15243                (match_operand:TF 3 "div_operator" "") 
15244                  (const_string "fdiv")
15245               ]
15246               (const_string "fop")))
15247    (set_attr "mode" "SF")])
15248
15249 (define_insn "*fop_xf_6"
15250   [(set (match_operand:XF 0 "register_operand" "=f,f")
15251         (match_operator:XF 3 "binary_fp_operator"
15252           [(float_extend:XF
15253             (match_operand 1 "register_operand" "0,f"))
15254            (float_extend:XF
15255             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15256   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387"
15257   "* return output_387_binary_op (insn, operands);"
15258   [(set (attr "type") 
15259         (cond [(match_operand:XF 3 "mult_operator" "") 
15260                  (const_string "fmul")
15261                (match_operand:XF 3 "div_operator" "") 
15262                  (const_string "fdiv")
15263               ]
15264               (const_string "fop")))
15265    (set_attr "mode" "SF")])
15266
15267 (define_insn "*fop_tf_6"
15268   [(set (match_operand:TF 0 "register_operand" "=f,f")
15269         (match_operator:TF 3 "binary_fp_operator"
15270           [(float_extend:TF
15271             (match_operand 1 "register_operand" "0,f"))
15272            (float_extend:TF
15273             (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15274   "TARGET_80387"
15275   "* return output_387_binary_op (insn, operands);"
15276   [(set (attr "type") 
15277         (cond [(match_operand:TF 3 "mult_operator" "") 
15278                  (const_string "fmul")
15279                (match_operand:TF 3 "div_operator" "") 
15280                  (const_string "fdiv")
15281               ]
15282               (const_string "fop")))
15283    (set_attr "mode" "SF")])
15284
15285 (define_split
15286   [(set (match_operand 0 "register_operand" "")
15287         (match_operator 3 "binary_fp_operator"
15288            [(float (match_operand:SI 1 "register_operand" ""))
15289             (match_operand 2 "register_operand" "")]))]
15290   "TARGET_80387 && reload_completed
15291    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15292   [(const_int 0)]
15293
15294   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15295   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15296   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15297                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15298                                           GET_MODE (operands[3]),
15299                                           operands[4],
15300                                           operands[2])));
15301   ix86_free_from_memory (GET_MODE (operands[1]));
15302   DONE;
15303 })
15304
15305 (define_split
15306   [(set (match_operand 0 "register_operand" "")
15307         (match_operator 3 "binary_fp_operator"
15308            [(match_operand 1 "register_operand" "")
15309             (float (match_operand:SI 2 "register_operand" ""))]))]
15310   "TARGET_80387 && reload_completed
15311    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15312   [(const_int 0)]
15313 {
15314   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15315   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15316   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15317                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15318                                           GET_MODE (operands[3]),
15319                                           operands[1],
15320                                           operands[4])));
15321   ix86_free_from_memory (GET_MODE (operands[2]));
15322   DONE;
15323 })
15324 \f
15325 ;; FPU special functions.
15326
15327 (define_expand "sqrtsf2"
15328   [(set (match_operand:SF 0 "register_operand" "")
15329         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15330   "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387) || TARGET_SSE_MATH"
15331 {
15332   if (!TARGET_SSE_MATH)
15333     operands[1] = force_reg (SFmode, operands[1]);
15334 })
15335
15336 (define_insn "sqrtsf2_1"
15337   [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
15338         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
15339   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15340    && (TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
15341   "@
15342    fsqrt
15343    sqrtss\t{%1, %0|%0, %1}"
15344   [(set_attr "type" "fpspc,sse")
15345    (set_attr "mode" "SF,SF")
15346    (set_attr "athlon_decode" "direct,*")])
15347
15348 (define_insn "sqrtsf2_1_sse_only"
15349   [(set (match_operand:SF 0 "register_operand" "=x")
15350         (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15351   "TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
15352   "sqrtss\t{%1, %0|%0, %1}"
15353   [(set_attr "type" "sse")
15354    (set_attr "mode" "SF")
15355    (set_attr "athlon_decode" "*")])
15356
15357 (define_insn "sqrtsf2_i387"
15358   [(set (match_operand:SF 0 "register_operand" "=f")
15359         (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15360   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15361    && !TARGET_SSE_MATH"
15362   "fsqrt"
15363   [(set_attr "type" "fpspc")
15364    (set_attr "mode" "SF")
15365    (set_attr "athlon_decode" "direct")])
15366
15367 (define_expand "sqrtdf2"
15368   [(set (match_operand:DF 0 "register_operand" "")
15369         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15370   "(! TARGET_NO_FANCY_MATH_387 && TARGET_80387)
15371    || (TARGET_SSE2 && TARGET_SSE_MATH)"
15372 {
15373   if (!TARGET_SSE2 || !TARGET_SSE_MATH)
15374     operands[1] = force_reg (DFmode, operands[1]);
15375 })
15376
15377 (define_insn "sqrtdf2_1"
15378   [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
15379         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
15380   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15381    && (TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387)"
15382   "@
15383    fsqrt
15384    sqrtsd\t{%1, %0|%0, %1}"
15385   [(set_attr "type" "fpspc,sse")
15386    (set_attr "mode" "DF,DF")
15387    (set_attr "athlon_decode" "direct,*")])
15388
15389 (define_insn "sqrtdf2_1_sse_only"
15390   [(set (match_operand:DF 0 "register_operand" "=Y")
15391         (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15392   "TARGET_SSE2 && TARGET_SSE_MATH && (!TARGET_80387 || !TARGET_MIX_SSE_I387)"
15393   "sqrtsd\t{%1, %0|%0, %1}"
15394   [(set_attr "type" "sse")
15395    (set_attr "mode" "DF")
15396    (set_attr "athlon_decode" "*")])
15397
15398 (define_insn "sqrtdf2_i387"
15399   [(set (match_operand:DF 0 "register_operand" "=f")
15400         (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15401   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15402    && (!TARGET_SSE2 || !TARGET_SSE_MATH)"
15403   "fsqrt"
15404   [(set_attr "type" "fpspc")
15405    (set_attr "mode" "DF")
15406    (set_attr "athlon_decode" "direct")])
15407
15408 (define_insn "*sqrtextendsfdf2"
15409   [(set (match_operand:DF 0 "register_operand" "=f")
15410         (sqrt:DF (float_extend:DF
15411                   (match_operand:SF 1 "register_operand" "0"))))]
15412   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15413    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15414   "fsqrt"
15415   [(set_attr "type" "fpspc")
15416    (set_attr "mode" "DF")
15417    (set_attr "athlon_decode" "direct")])
15418
15419 (define_insn "sqrtxf2"
15420   [(set (match_operand:XF 0 "register_operand" "=f")
15421         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15422   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && !TARGET_NO_FANCY_MATH_387 
15423    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15424   "fsqrt"
15425   [(set_attr "type" "fpspc")
15426    (set_attr "mode" "XF")
15427    (set_attr "athlon_decode" "direct")])
15428
15429 (define_insn "sqrttf2"
15430   [(set (match_operand:TF 0 "register_operand" "=f")
15431         (sqrt:TF (match_operand:TF 1 "register_operand" "0")))]
15432   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15433    && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
15434   "fsqrt"
15435   [(set_attr "type" "fpspc")
15436    (set_attr "mode" "XF")
15437    (set_attr "athlon_decode" "direct")])
15438
15439 (define_insn "*sqrtextenddfxf2"
15440   [(set (match_operand:XF 0 "register_operand" "=f")
15441         (sqrt:XF (float_extend:XF
15442                   (match_operand:DF 1 "register_operand" "0"))))]
15443   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
15444   "fsqrt"
15445   [(set_attr "type" "fpspc")
15446    (set_attr "mode" "XF")
15447    (set_attr "athlon_decode" "direct")])
15448
15449 (define_insn "*sqrtextenddftf2"
15450   [(set (match_operand:TF 0 "register_operand" "=f")
15451         (sqrt:TF (float_extend:TF
15452                   (match_operand:DF 1 "register_operand" "0"))))]
15453   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
15454   "fsqrt"
15455   [(set_attr "type" "fpspc")
15456    (set_attr "mode" "XF")
15457    (set_attr "athlon_decode" "direct")])
15458
15459 (define_insn "*sqrtextendsfxf2"
15460   [(set (match_operand:XF 0 "register_operand" "=f")
15461         (sqrt:XF (float_extend:XF
15462                   (match_operand:SF 1 "register_operand" "0"))))]
15463   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && !TARGET_NO_FANCY_MATH_387"
15464   "fsqrt"
15465   [(set_attr "type" "fpspc")
15466    (set_attr "mode" "XF")
15467    (set_attr "athlon_decode" "direct")])
15468
15469 (define_insn "*sqrtextendsftf2"
15470   [(set (match_operand:TF 0 "register_operand" "=f")
15471         (sqrt:TF (float_extend:TF
15472                   (match_operand:SF 1 "register_operand" "0"))))]
15473   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
15474   "fsqrt"
15475   [(set_attr "type" "fpspc")
15476    (set_attr "mode" "XF")
15477    (set_attr "athlon_decode" "direct")])
15478
15479 (define_insn "sindf2"
15480   [(set (match_operand:DF 0 "register_operand" "=f")
15481         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15482   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15483    && flag_unsafe_math_optimizations"
15484   "fsin"
15485   [(set_attr "type" "fpspc")
15486    (set_attr "mode" "DF")])
15487
15488 (define_insn "sinsf2"
15489   [(set (match_operand:SF 0 "register_operand" "=f")
15490         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15491   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15492    && flag_unsafe_math_optimizations"
15493   "fsin"
15494   [(set_attr "type" "fpspc")
15495    (set_attr "mode" "SF")])
15496
15497 (define_insn "*sinextendsfdf2"
15498   [(set (match_operand:DF 0 "register_operand" "=f")
15499         (unspec:DF [(float_extend:DF
15500                      (match_operand:SF 1 "register_operand" "0"))]
15501                    UNSPEC_SIN))]
15502   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15503    && flag_unsafe_math_optimizations"
15504   "fsin"
15505   [(set_attr "type" "fpspc")
15506    (set_attr "mode" "DF")])
15507
15508 (define_insn "sinxf2"
15509   [(set (match_operand:XF 0 "register_operand" "=f")
15510         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15511   "!TARGET_128BIT_LONG_DOUBLE && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
15512    && flag_unsafe_math_optimizations"
15513   "fsin"
15514   [(set_attr "type" "fpspc")
15515    (set_attr "mode" "XF")])
15516
15517 (define_insn "sintf2"
15518   [(set (match_operand:TF 0 "register_operand" "=f")
15519         (unspec:TF [(match_operand:TF 1 "register_operand" "0")] UNSPEC_SIN))]
15520   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15521    && flag_unsafe_math_optimizations"
15522   "fsin"
15523   [(set_attr "type" "fpspc")
15524    (set_attr "mode" "XF")])
15525
15526 (define_insn "cosdf2"
15527   [(set (match_operand:DF 0 "register_operand" "=f")
15528         (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15529   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15530    && flag_unsafe_math_optimizations"
15531   "fcos"
15532   [(set_attr "type" "fpspc")
15533    (set_attr "mode" "DF")])
15534
15535 (define_insn "cossf2"
15536   [(set (match_operand:SF 0 "register_operand" "=f")
15537         (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15538   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15539    && flag_unsafe_math_optimizations"
15540   "fcos"
15541   [(set_attr "type" "fpspc")
15542    (set_attr "mode" "SF")])
15543
15544 (define_insn "*cosextendsfdf2"
15545   [(set (match_operand:DF 0 "register_operand" "=f")
15546         (unspec:DF [(float_extend:DF
15547                      (match_operand:SF 1 "register_operand" "0"))]
15548                    UNSPEC_COS))]
15549   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15550    && flag_unsafe_math_optimizations"
15551   "fcos"
15552   [(set_attr "type" "fpspc")
15553    (set_attr "mode" "DF")])
15554
15555 (define_insn "cosxf2"
15556   [(set (match_operand:XF 0 "register_operand" "=f")
15557         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15558   "!TARGET_128BIT_LONG_DOUBLE && ! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15559    && flag_unsafe_math_optimizations"
15560   "fcos"
15561   [(set_attr "type" "fpspc")
15562    (set_attr "mode" "XF")])
15563
15564 (define_insn "costf2"
15565   [(set (match_operand:TF 0 "register_operand" "=f")
15566         (unspec:TF [(match_operand:TF 1 "register_operand" "0")] UNSPEC_COS))]
15567   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
15568    && flag_unsafe_math_optimizations"
15569   "fcos"
15570   [(set_attr "type" "fpspc")
15571    (set_attr "mode" "XF")])
15572
15573 (define_insn "atan2df3"
15574   [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
15575                    (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15576                                (match_operand:DF 1 "register_operand" "u")]
15577                     UNSPEC_FPATAN))
15578               (clobber (match_dup 1))])]
15579   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15580    && flag_unsafe_math_optimizations"
15581   "fpatan"
15582   [(set_attr "type" "fpspc")
15583    (set_attr "mode" "DF")])
15584
15585 (define_insn "atan2sf3"
15586   [(parallel [(set (match_operand:SF 0 "register_operand" "=f")
15587                    (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15588                                (match_operand:SF 1 "register_operand" "u")]
15589                     UNSPEC_FPATAN))
15590               (clobber (match_dup 1))])]
15591   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15592    && flag_unsafe_math_optimizations"
15593   "fpatan"
15594   [(set_attr "type" "fpspc")
15595    (set_attr "mode" "SF")])
15596
15597 (define_insn "atan2xf3"
15598   [(parallel [(set (match_operand:XF 0 "register_operand" "=f")
15599                    (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15600                                (match_operand:XF 1 "register_operand" "u")]
15601                     UNSPEC_FPATAN))
15602               (clobber (match_dup 1))])]
15603   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15604    && flag_unsafe_math_optimizations"
15605   "fpatan"
15606   [(set_attr "type" "fpspc")
15607    (set_attr "mode" "XF")])
15608
15609 (define_insn "atan2tf3"
15610   [(parallel [(set (match_operand:TF 0 "register_operand" "=f")
15611                    (unspec:TF [(match_operand:TF 2 "register_operand" "0")
15612                                (match_operand:TF 1 "register_operand" "u")]
15613                     UNSPEC_FPATAN))
15614               (clobber (match_dup 1))])]
15615   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15616    && flag_unsafe_math_optimizations"
15617   "fpatan"
15618   [(set_attr "type" "fpspc")
15619    (set_attr "mode" "XF")])
15620
15621 (define_insn "*fyl2x_sfxf3"
15622   [(parallel [(set (match_operand:SF 0 "register_operand" "=f")
15623                    (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15624                                (match_operand:XF 1 "register_operand" "u")]
15625                     UNSPEC_FYL2X))
15626               (clobber (match_dup 1))])]
15627   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15628    && flag_unsafe_math_optimizations"
15629   "fyl2x"
15630   [(set_attr "type" "fpspc")
15631    (set_attr "mode" "SF")])
15632
15633 (define_insn "*fyl2x_dfxf3"
15634   [(parallel [(set (match_operand:DF 0 "register_operand" "=f")
15635                    (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15636                                (match_operand:XF 1 "register_operand" "u")]
15637                     UNSPEC_FYL2X))
15638               (clobber (match_dup 1))])]
15639   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15640    && flag_unsafe_math_optimizations"
15641   "fyl2x"
15642   [(set_attr "type" "fpspc")
15643    (set_attr "mode" "DF")])
15644
15645 (define_insn "*fyl2x_xf3"
15646   [(parallel [(set (match_operand:XF 0 "register_operand" "=f")
15647                    (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15648                                (match_operand:XF 1 "register_operand" "u")]
15649                     UNSPEC_FYL2X))
15650               (clobber (match_dup 1))])]
15651   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15652    && flag_unsafe_math_optimizations"
15653   "fyl2x"
15654   [(set_attr "type" "fpspc")
15655    (set_attr "mode" "XF")])
15656
15657 (define_insn "*fyl2x_tfxf3"
15658   [(parallel [(set (match_operand:TF 0 "register_operand" "=f")
15659                    (unspec:TF [(match_operand:TF 2 "register_operand" "0")
15660                                (match_operand:XF 1 "register_operand" "u")]
15661                     UNSPEC_FYL2X))
15662               (clobber (match_dup 1))])]
15663   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15664    && flag_unsafe_math_optimizations"
15665   "fyl2x"
15666   [(set_attr "type" "fpspc")
15667    (set_attr "mode" "XF")])
15668
15669 (define_expand "logsf2"
15670   [(parallel [(set (match_operand:SF 0 "register_operand" "")
15671                    (unspec:SF [(match_operand:SF 1 "register_operand" "")
15672                                (match_dup 2)] UNSPEC_FYL2X))
15673               (clobber (match_dup 2))])]
15674   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15675    && flag_unsafe_math_optimizations"
15676 {
15677   rtx temp;
15678
15679   operands[2] = gen_reg_rtx (XFmode);
15680   temp = standard_80387_constant_rtx (4); /* fldln2 */
15681   emit_move_insn (operands[2], temp);
15682 })
15683
15684 (define_expand "logdf2"
15685   [(parallel [(set (match_operand:DF 0 "register_operand" "")
15686                    (unspec:DF [(match_operand:DF 1 "register_operand" "")
15687                                (match_dup 2)] UNSPEC_FYL2X))
15688               (clobber (match_dup 2))])]
15689   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15690    && flag_unsafe_math_optimizations"
15691 {
15692   rtx temp;
15693
15694   operands[2] = gen_reg_rtx (XFmode);
15695   temp = standard_80387_constant_rtx (4); /* fldln2 */
15696   emit_move_insn (operands[2], temp);
15697 })
15698
15699 (define_expand "logxf2"
15700   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15701                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15702                                (match_dup 2)] UNSPEC_FYL2X))
15703               (clobber (match_dup 2))])]
15704   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15705    && flag_unsafe_math_optimizations"
15706 {
15707   rtx temp;
15708
15709   operands[2] = gen_reg_rtx (XFmode);
15710   temp = standard_80387_constant_rtx (4); /* fldln2 */
15711   emit_move_insn (operands[2], temp);
15712 })
15713
15714 (define_expand "logtf2"
15715   [(parallel [(set (match_operand:TF 0 "register_operand" "")
15716                    (unspec:TF [(match_operand:TF 1 "register_operand" "")
15717                                (match_dup 2)] UNSPEC_FYL2X))
15718               (clobber (match_dup 2))])]
15719   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
15720    && flag_unsafe_math_optimizations"
15721 {
15722   rtx temp;
15723
15724   operands[2] = gen_reg_rtx (XFmode);
15725   temp = standard_80387_constant_rtx (4); /* fldln2 */
15726   emit_move_insn (operands[2], temp);
15727 })
15728 \f
15729 ;; Block operation instructions
15730
15731 (define_insn "cld"
15732  [(set (reg:SI 19) (const_int 0))]
15733  ""
15734  "cld"
15735   [(set_attr "type" "cld")])
15736
15737 (define_expand "movstrsi"
15738   [(use (match_operand:BLK 0 "memory_operand" ""))
15739    (use (match_operand:BLK 1 "memory_operand" ""))
15740    (use (match_operand:SI 2 "nonmemory_operand" ""))
15741    (use (match_operand:SI 3 "const_int_operand" ""))]
15742   ""
15743 {
15744  if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15745    DONE;
15746  else
15747    FAIL;
15748 })
15749
15750 (define_expand "movstrdi"
15751   [(use (match_operand:BLK 0 "memory_operand" ""))
15752    (use (match_operand:BLK 1 "memory_operand" ""))
15753    (use (match_operand:DI 2 "nonmemory_operand" ""))
15754    (use (match_operand:DI 3 "const_int_operand" ""))]
15755   "TARGET_64BIT"
15756 {
15757  if (ix86_expand_movstr (operands[0], operands[1], operands[2], operands[3]))
15758    DONE;
15759  else
15760    FAIL;
15761 })
15762
15763 ;; Most CPUs don't like single string operations
15764 ;; Handle this case here to simplify previous expander.
15765
15766 (define_expand "strmovdi_rex64"
15767   [(set (match_dup 2)
15768         (mem:DI (match_operand:DI 1 "register_operand" "")))
15769    (set (mem:DI (match_operand:DI 0 "register_operand" ""))
15770         (match_dup 2))
15771    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
15772               (clobber (reg:CC 17))])
15773    (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 8)))
15774               (clobber (reg:CC 17))])]
15775   "TARGET_64BIT"
15776 {
15777   if (TARGET_SINGLE_STRINGOP || optimize_size)
15778     {
15779       emit_insn (gen_strmovdi_rex_1 (operands[0], operands[1], operands[0],
15780                                      operands[1]));
15781       DONE;
15782     }
15783   else 
15784     operands[2] = gen_reg_rtx (DImode);
15785 })
15786
15787
15788 (define_expand "strmovsi"
15789   [(set (match_dup 2)
15790         (mem:SI (match_operand:SI 1 "register_operand" "")))
15791    (set (mem:SI (match_operand:SI 0 "register_operand" ""))
15792         (match_dup 2))
15793    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
15794               (clobber (reg:CC 17))])
15795    (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
15796               (clobber (reg:CC 17))])]
15797   ""
15798 {
15799   if (TARGET_64BIT)
15800     {
15801       emit_insn (gen_strmovsi_rex64 (operands[0], operands[1]));
15802       DONE;
15803     }
15804   if (TARGET_SINGLE_STRINGOP || optimize_size)
15805     {
15806       emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
15807                                 operands[1]));
15808       DONE;
15809     }
15810   else 
15811     operands[2] = gen_reg_rtx (SImode);
15812 })
15813
15814 (define_expand "strmovsi_rex64"
15815   [(set (match_dup 2)
15816         (mem:SI (match_operand:DI 1 "register_operand" "")))
15817    (set (mem:SI (match_operand:DI 0 "register_operand" ""))
15818         (match_dup 2))
15819    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
15820               (clobber (reg:CC 17))])
15821    (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 4)))
15822               (clobber (reg:CC 17))])]
15823   "TARGET_64BIT"
15824 {
15825   if (TARGET_SINGLE_STRINGOP || optimize_size)
15826     {
15827       emit_insn (gen_strmovsi_rex_1 (operands[0], operands[1], operands[0],
15828                                      operands[1]));
15829       DONE;
15830     }
15831   else 
15832     operands[2] = gen_reg_rtx (SImode);
15833 })
15834
15835 (define_expand "strmovhi"
15836   [(set (match_dup 2)
15837         (mem:HI (match_operand:SI 1 "register_operand" "")))
15838    (set (mem:HI (match_operand:SI 0 "register_operand" ""))
15839         (match_dup 2))
15840    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
15841               (clobber (reg:CC 17))])
15842    (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
15843               (clobber (reg:CC 17))])]
15844   ""
15845 {
15846   if (TARGET_64BIT)
15847     {
15848       emit_insn (gen_strmovhi_rex64 (operands[0], operands[1]));
15849       DONE;
15850     }
15851   if (TARGET_SINGLE_STRINGOP || optimize_size)
15852     {
15853       emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
15854                                 operands[1]));
15855       DONE;
15856     }
15857   else 
15858     operands[2] = gen_reg_rtx (HImode);
15859 })
15860
15861 (define_expand "strmovhi_rex64"
15862   [(set (match_dup 2)
15863         (mem:HI (match_operand:DI 1 "register_operand" "")))
15864    (set (mem:HI (match_operand:DI 0 "register_operand" ""))
15865         (match_dup 2))
15866    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
15867               (clobber (reg:CC 17))])
15868    (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 2)))
15869               (clobber (reg:CC 17))])]
15870   "TARGET_64BIT"
15871 {
15872   if (TARGET_SINGLE_STRINGOP || optimize_size)
15873     {
15874       emit_insn (gen_strmovhi_rex_1 (operands[0], operands[1], operands[0],
15875                                      operands[1]));
15876       DONE;
15877     }
15878   else 
15879     operands[2] = gen_reg_rtx (HImode);
15880 })
15881
15882 (define_expand "strmovqi"
15883   [(set (match_dup 2)
15884         (mem:QI (match_operand:SI 1 "register_operand" "")))
15885    (set (mem:QI (match_operand:SI 0 "register_operand" ""))
15886         (match_dup 2))
15887    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15888               (clobber (reg:CC 17))])
15889    (parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
15890               (clobber (reg:CC 17))])]
15891   ""
15892 {
15893   if (TARGET_64BIT)
15894     {
15895       emit_insn (gen_strmovqi_rex64 (operands[0], operands[1]));
15896       DONE;
15897     }
15898   if (TARGET_SINGLE_STRINGOP || optimize_size)
15899     {
15900       emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
15901                                 operands[1]));
15902       DONE;
15903     }
15904   else 
15905     operands[2] = gen_reg_rtx (QImode);
15906 })
15907
15908 (define_expand "strmovqi_rex64"
15909   [(set (match_dup 2)
15910         (mem:QI (match_operand:DI 1 "register_operand" "")))
15911    (set (mem:QI (match_operand:DI 0 "register_operand" ""))
15912         (match_dup 2))
15913    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15914               (clobber (reg:CC 17))])
15915    (parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 1)))
15916               (clobber (reg:CC 17))])]
15917   "TARGET_64BIT"
15918 {
15919   if (TARGET_SINGLE_STRINGOP || optimize_size)
15920     {
15921       emit_insn (gen_strmovqi_rex_1 (operands[0], operands[1], operands[0],
15922                                      operands[1]));
15923       DONE;
15924     }
15925   else 
15926     operands[2] = gen_reg_rtx (QImode);
15927 })
15928
15929 (define_insn "strmovdi_rex_1"
15930   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15931         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15932    (set (match_operand:DI 0 "register_operand" "=D")
15933         (plus:DI (match_dup 2)
15934                  (const_int 8)))
15935    (set (match_operand:DI 1 "register_operand" "=S")
15936         (plus:DI (match_dup 3)
15937                  (const_int 8)))
15938    (use (reg:SI 19))]
15939   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15940   "movsq"
15941   [(set_attr "type" "str")
15942    (set_attr "mode" "DI")
15943    (set_attr "memory" "both")])
15944
15945 (define_insn "strmovsi_1"
15946   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15947         (mem:SI (match_operand:SI 3 "register_operand" "1")))
15948    (set (match_operand:SI 0 "register_operand" "=D")
15949         (plus:SI (match_dup 2)
15950                  (const_int 4)))
15951    (set (match_operand:SI 1 "register_operand" "=S")
15952         (plus:SI (match_dup 3)
15953                  (const_int 4)))
15954    (use (reg:SI 19))]
15955   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15956   "{movsl|movsd}"
15957   [(set_attr "type" "str")
15958    (set_attr "mode" "SI")
15959    (set_attr "memory" "both")])
15960
15961 (define_insn "strmovsi_rex_1"
15962   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15963         (mem:SI (match_operand:DI 3 "register_operand" "1")))
15964    (set (match_operand:DI 0 "register_operand" "=D")
15965         (plus:DI (match_dup 2)
15966                  (const_int 4)))
15967    (set (match_operand:DI 1 "register_operand" "=S")
15968         (plus:DI (match_dup 3)
15969                  (const_int 4)))
15970    (use (reg:SI 19))]
15971   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15972   "{movsl|movsd}"
15973   [(set_attr "type" "str")
15974    (set_attr "mode" "SI")
15975    (set_attr "memory" "both")])
15976
15977 (define_insn "strmovhi_1"
15978   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15979         (mem:HI (match_operand:SI 3 "register_operand" "1")))
15980    (set (match_operand:SI 0 "register_operand" "=D")
15981         (plus:SI (match_dup 2)
15982                  (const_int 2)))
15983    (set (match_operand:SI 1 "register_operand" "=S")
15984         (plus:SI (match_dup 3)
15985                  (const_int 2)))
15986    (use (reg:SI 19))]
15987   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
15988   "movsw"
15989   [(set_attr "type" "str")
15990    (set_attr "memory" "both")
15991    (set_attr "mode" "HI")])
15992
15993 (define_insn "strmovhi_rex_1"
15994   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15995         (mem:HI (match_operand:DI 3 "register_operand" "1")))
15996    (set (match_operand:DI 0 "register_operand" "=D")
15997         (plus:DI (match_dup 2)
15998                  (const_int 2)))
15999    (set (match_operand:DI 1 "register_operand" "=S")
16000         (plus:DI (match_dup 3)
16001                  (const_int 2)))
16002    (use (reg:SI 19))]
16003   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16004   "movsw"
16005   [(set_attr "type" "str")
16006    (set_attr "memory" "both")
16007    (set_attr "mode" "HI")])
16008
16009 (define_insn "strmovqi_1"
16010   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
16011         (mem:QI (match_operand:SI 3 "register_operand" "1")))
16012    (set (match_operand:SI 0 "register_operand" "=D")
16013         (plus:SI (match_dup 2)
16014                  (const_int 1)))
16015    (set (match_operand:SI 1 "register_operand" "=S")
16016         (plus:SI (match_dup 3)
16017                  (const_int 1)))
16018    (use (reg:SI 19))]
16019   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16020   "movsb"
16021   [(set_attr "type" "str")
16022    (set_attr "memory" "both")
16023    (set_attr "mode" "QI")])
16024
16025 (define_insn "strmovqi_rex_1"
16026   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
16027         (mem:QI (match_operand:DI 3 "register_operand" "1")))
16028    (set (match_operand:DI 0 "register_operand" "=D")
16029         (plus:DI (match_dup 2)
16030                  (const_int 1)))
16031    (set (match_operand:DI 1 "register_operand" "=S")
16032         (plus:DI (match_dup 3)
16033                  (const_int 1)))
16034    (use (reg:SI 19))]
16035   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16036   "movsb"
16037   [(set_attr "type" "str")
16038    (set_attr "memory" "both")
16039    (set_attr "mode" "QI")])
16040
16041 (define_insn "rep_movdi_rex64"
16042   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16043    (set (match_operand:DI 0 "register_operand" "=D") 
16044         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16045                             (const_int 3))
16046                  (match_operand:DI 3 "register_operand" "0")))
16047    (set (match_operand:DI 1 "register_operand" "=S") 
16048         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16049                  (match_operand:DI 4 "register_operand" "1")))
16050    (set (mem:BLK (match_dup 3))
16051         (mem:BLK (match_dup 4)))
16052    (use (match_dup 5))
16053    (use (reg:SI 19))]
16054   "TARGET_64BIT"
16055   "{rep\;movsq|rep movsq}"
16056   [(set_attr "type" "str")
16057    (set_attr "prefix_rep" "1")
16058    (set_attr "memory" "both")
16059    (set_attr "mode" "DI")])
16060
16061 (define_insn "rep_movsi"
16062   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16063    (set (match_operand:SI 0 "register_operand" "=D") 
16064         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16065                             (const_int 2))
16066                  (match_operand:SI 3 "register_operand" "0")))
16067    (set (match_operand:SI 1 "register_operand" "=S") 
16068         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16069                  (match_operand:SI 4 "register_operand" "1")))
16070    (set (mem:BLK (match_dup 3))
16071         (mem:BLK (match_dup 4)))
16072    (use (match_dup 5))
16073    (use (reg:SI 19))]
16074   "!TARGET_64BIT"
16075   "{rep\;movsl|rep movsd}"
16076   [(set_attr "type" "str")
16077    (set_attr "prefix_rep" "1")
16078    (set_attr "memory" "both")
16079    (set_attr "mode" "SI")])
16080
16081 (define_insn "rep_movsi_rex64"
16082   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16083    (set (match_operand:DI 0 "register_operand" "=D") 
16084         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16085                             (const_int 2))
16086                  (match_operand:DI 3 "register_operand" "0")))
16087    (set (match_operand:DI 1 "register_operand" "=S") 
16088         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16089                  (match_operand:DI 4 "register_operand" "1")))
16090    (set (mem:BLK (match_dup 3))
16091         (mem:BLK (match_dup 4)))
16092    (use (match_dup 5))
16093    (use (reg:SI 19))]
16094   "TARGET_64BIT"
16095   "{rep\;movsl|rep movsd}"
16096   [(set_attr "type" "str")
16097    (set_attr "prefix_rep" "1")
16098    (set_attr "memory" "both")
16099    (set_attr "mode" "SI")])
16100
16101 (define_insn "rep_movqi"
16102   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16103    (set (match_operand:SI 0 "register_operand" "=D") 
16104         (plus:SI (match_operand:SI 3 "register_operand" "0")
16105                  (match_operand:SI 5 "register_operand" "2")))
16106    (set (match_operand:SI 1 "register_operand" "=S") 
16107         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16108    (set (mem:BLK (match_dup 3))
16109         (mem:BLK (match_dup 4)))
16110    (use (match_dup 5))
16111    (use (reg:SI 19))]
16112   "!TARGET_64BIT"
16113   "{rep\;movsb|rep movsb}"
16114   [(set_attr "type" "str")
16115    (set_attr "prefix_rep" "1")
16116    (set_attr "memory" "both")
16117    (set_attr "mode" "SI")])
16118
16119 (define_insn "rep_movqi_rex64"
16120   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16121    (set (match_operand:DI 0 "register_operand" "=D") 
16122         (plus:DI (match_operand:DI 3 "register_operand" "0")
16123                  (match_operand:DI 5 "register_operand" "2")))
16124    (set (match_operand:DI 1 "register_operand" "=S") 
16125         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16126    (set (mem:BLK (match_dup 3))
16127         (mem:BLK (match_dup 4)))
16128    (use (match_dup 5))
16129    (use (reg:SI 19))]
16130   "TARGET_64BIT"
16131   "{rep\;movsb|rep movsb}"
16132   [(set_attr "type" "str")
16133    (set_attr "prefix_rep" "1")
16134    (set_attr "memory" "both")
16135    (set_attr "mode" "SI")])
16136
16137 (define_expand "clrstrsi"
16138    [(use (match_operand:BLK 0 "memory_operand" ""))
16139     (use (match_operand:SI 1 "nonmemory_operand" ""))
16140     (use (match_operand 2 "const_int_operand" ""))]
16141   ""
16142 {
16143  if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
16144    DONE;
16145  else
16146    FAIL;
16147 })
16148
16149 (define_expand "clrstrdi"
16150    [(use (match_operand:BLK 0 "memory_operand" ""))
16151     (use (match_operand:DI 1 "nonmemory_operand" ""))
16152     (use (match_operand 2 "const_int_operand" ""))]
16153   "TARGET_64BIT"
16154 {
16155  if (ix86_expand_clrstr (operands[0], operands[1], operands[2]))
16156    DONE;
16157  else
16158    FAIL;
16159 })
16160
16161 ;; Most CPUs don't like single string operations
16162 ;; Handle this case here to simplify previous expander.
16163
16164 (define_expand "strsetdi_rex64"
16165   [(set (mem:DI (match_operand:DI 0 "register_operand" ""))
16166         (match_operand:DI 1 "register_operand" ""))
16167    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
16168               (clobber (reg:CC 17))])]
16169   "TARGET_64BIT"
16170 {
16171   if (TARGET_SINGLE_STRINGOP || optimize_size)
16172     {
16173       emit_insn (gen_strsetdi_rex_1 (operands[0], operands[0], operands[1]));
16174       DONE;
16175     }
16176 })
16177
16178 (define_expand "strsetsi"
16179   [(set (mem:SI (match_operand:SI 0 "register_operand" ""))
16180         (match_operand:SI 1 "register_operand" ""))
16181    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
16182               (clobber (reg:CC 17))])]
16183   ""
16184 {
16185   if (TARGET_64BIT)
16186     {
16187       emit_insn (gen_strsetsi_rex64 (operands[0], operands[1]));
16188       DONE;
16189     }
16190   else if (TARGET_SINGLE_STRINGOP || optimize_size)
16191     {
16192       emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
16193       DONE;
16194     }
16195 })
16196
16197 (define_expand "strsetsi_rex64"
16198   [(set (mem:SI (match_operand:DI 0 "register_operand" ""))
16199         (match_operand:SI 1 "register_operand" ""))
16200    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
16201               (clobber (reg:CC 17))])]
16202   "TARGET_64BIT"
16203 {
16204   if (TARGET_SINGLE_STRINGOP || optimize_size)
16205     {
16206       emit_insn (gen_strsetsi_rex_1 (operands[0], operands[0], operands[1]));
16207       DONE;
16208     }
16209 })
16210
16211 (define_expand "strsethi"
16212   [(set (mem:HI (match_operand:SI 0 "register_operand" ""))
16213         (match_operand:HI 1 "register_operand" ""))
16214    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
16215               (clobber (reg:CC 17))])]
16216   ""
16217 {
16218   if (TARGET_64BIT)
16219     {
16220       emit_insn (gen_strsethi_rex64 (operands[0], operands[1]));
16221       DONE;
16222     }
16223   else if (TARGET_SINGLE_STRINGOP || optimize_size)
16224     {
16225       emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
16226       DONE;
16227     }
16228 })
16229
16230 (define_expand "strsethi_rex64"
16231   [(set (mem:HI (match_operand:DI 0 "register_operand" ""))
16232         (match_operand:HI 1 "register_operand" ""))
16233    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
16234               (clobber (reg:CC 17))])]
16235   "TARGET_64BIT"
16236 {
16237   if (TARGET_SINGLE_STRINGOP || optimize_size)
16238     {
16239       emit_insn (gen_strsethi_rex_1 (operands[0], operands[0], operands[1]));
16240       DONE;
16241     }
16242 })
16243
16244 (define_expand "strsetqi"
16245   [(set (mem:QI (match_operand:SI 0 "register_operand" ""))
16246         (match_operand:QI 1 "register_operand" ""))
16247    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
16248               (clobber (reg:CC 17))])]
16249   ""
16250 {
16251   if (TARGET_64BIT)
16252     {
16253       emit_insn (gen_strsetqi_rex64 (operands[0], operands[1]));
16254       DONE;
16255     }
16256   else if (TARGET_SINGLE_STRINGOP || optimize_size)
16257     {
16258       emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
16259       DONE;
16260     }
16261 })
16262
16263 (define_expand "strsetqi_rex64"
16264   [(set (mem:QI (match_operand:DI 0 "register_operand" ""))
16265         (match_operand:QI 1 "register_operand" ""))
16266    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
16267               (clobber (reg:CC 17))])]
16268   "TARGET_64BIT"
16269 {
16270   if (TARGET_SINGLE_STRINGOP || optimize_size)
16271     {
16272       emit_insn (gen_strsetqi_rex_1 (operands[0], operands[0], operands[1]));
16273       DONE;
16274     }
16275 })
16276
16277 (define_insn "strsetdi_rex_1"
16278   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16279         (match_operand:SI 2 "register_operand" "a"))
16280    (set (match_operand:DI 0 "register_operand" "=D")
16281         (plus:DI (match_dup 1)
16282                  (const_int 8)))
16283    (use (reg:SI 19))]
16284   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16285   "stosq"
16286   [(set_attr "type" "str")
16287    (set_attr "memory" "store")
16288    (set_attr "mode" "DI")])
16289
16290 (define_insn "strsetsi_1"
16291   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16292         (match_operand:SI 2 "register_operand" "a"))
16293    (set (match_operand:SI 0 "register_operand" "=D")
16294         (plus:SI (match_dup 1)
16295                  (const_int 4)))
16296    (use (reg:SI 19))]
16297   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16298   "{stosl|stosd}"
16299   [(set_attr "type" "str")
16300    (set_attr "memory" "store")
16301    (set_attr "mode" "SI")])
16302
16303 (define_insn "strsetsi_rex_1"
16304   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16305         (match_operand:SI 2 "register_operand" "a"))
16306    (set (match_operand:DI 0 "register_operand" "=D")
16307         (plus:DI (match_dup 1)
16308                  (const_int 4)))
16309    (use (reg:SI 19))]
16310   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16311   "{stosl|stosd}"
16312   [(set_attr "type" "str")
16313    (set_attr "memory" "store")
16314    (set_attr "mode" "SI")])
16315
16316 (define_insn "strsethi_1"
16317   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16318         (match_operand:HI 2 "register_operand" "a"))
16319    (set (match_operand:SI 0 "register_operand" "=D")
16320         (plus:SI (match_dup 1)
16321                  (const_int 2)))
16322    (use (reg:SI 19))]
16323   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16324   "stosw"
16325   [(set_attr "type" "str")
16326    (set_attr "memory" "store")
16327    (set_attr "mode" "HI")])
16328
16329 (define_insn "strsethi_rex_1"
16330   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16331         (match_operand:HI 2 "register_operand" "a"))
16332    (set (match_operand:DI 0 "register_operand" "=D")
16333         (plus:DI (match_dup 1)
16334                  (const_int 2)))
16335    (use (reg:SI 19))]
16336   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16337   "stosw"
16338   [(set_attr "type" "str")
16339    (set_attr "memory" "store")
16340    (set_attr "mode" "HI")])
16341
16342 (define_insn "strsetqi_1"
16343   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16344         (match_operand:QI 2 "register_operand" "a"))
16345    (set (match_operand:SI 0 "register_operand" "=D")
16346         (plus:SI (match_dup 1)
16347                  (const_int 1)))
16348    (use (reg:SI 19))]
16349   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16350   "stosb"
16351   [(set_attr "type" "str")
16352    (set_attr "memory" "store")
16353    (set_attr "mode" "QI")])
16354
16355 (define_insn "strsetqi_rex_1"
16356   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16357         (match_operand:QI 2 "register_operand" "a"))
16358    (set (match_operand:DI 0 "register_operand" "=D")
16359         (plus:DI (match_dup 1)
16360                  (const_int 1)))
16361    (use (reg:SI 19))]
16362   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
16363   "stosb"
16364   [(set_attr "type" "str")
16365    (set_attr "memory" "store")
16366    (set_attr "mode" "QI")])
16367
16368 (define_insn "rep_stosdi_rex64"
16369   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16370    (set (match_operand:DI 0 "register_operand" "=D") 
16371         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16372                             (const_int 3))
16373                  (match_operand:DI 3 "register_operand" "0")))
16374    (set (mem:BLK (match_dup 3))
16375         (const_int 0))
16376    (use (match_operand:DI 2 "register_operand" "a"))
16377    (use (match_dup 4))
16378    (use (reg:SI 19))]
16379   "TARGET_64BIT"
16380   "{rep\;stosq|rep stosq}"
16381   [(set_attr "type" "str")
16382    (set_attr "prefix_rep" "1")
16383    (set_attr "memory" "store")
16384    (set_attr "mode" "DI")])
16385
16386 (define_insn "rep_stossi"
16387   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16388    (set (match_operand:SI 0 "register_operand" "=D") 
16389         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16390                             (const_int 2))
16391                  (match_operand:SI 3 "register_operand" "0")))
16392    (set (mem:BLK (match_dup 3))
16393         (const_int 0))
16394    (use (match_operand:SI 2 "register_operand" "a"))
16395    (use (match_dup 4))
16396    (use (reg:SI 19))]
16397   "!TARGET_64BIT"
16398   "{rep\;stosl|rep stosd}"
16399   [(set_attr "type" "str")
16400    (set_attr "prefix_rep" "1")
16401    (set_attr "memory" "store")
16402    (set_attr "mode" "SI")])
16403
16404 (define_insn "rep_stossi_rex64"
16405   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16406    (set (match_operand:DI 0 "register_operand" "=D") 
16407         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16408                             (const_int 2))
16409                  (match_operand:DI 3 "register_operand" "0")))
16410    (set (mem:BLK (match_dup 3))
16411         (const_int 0))
16412    (use (match_operand:SI 2 "register_operand" "a"))
16413    (use (match_dup 4))
16414    (use (reg:SI 19))]
16415   "TARGET_64BIT"
16416   "{rep\;stosl|rep stosd}"
16417   [(set_attr "type" "str")
16418    (set_attr "prefix_rep" "1")
16419    (set_attr "memory" "store")
16420    (set_attr "mode" "SI")])
16421
16422 (define_insn "rep_stosqi"
16423   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16424    (set (match_operand:SI 0 "register_operand" "=D") 
16425         (plus:SI (match_operand:SI 3 "register_operand" "0")
16426                  (match_operand:SI 4 "register_operand" "1")))
16427    (set (mem:BLK (match_dup 3))
16428         (const_int 0))
16429    (use (match_operand:QI 2 "register_operand" "a"))
16430    (use (match_dup 4))
16431    (use (reg:SI 19))]
16432   "!TARGET_64BIT"
16433   "{rep\;stosb|rep stosb}"
16434   [(set_attr "type" "str")
16435    (set_attr "prefix_rep" "1")
16436    (set_attr "memory" "store")
16437    (set_attr "mode" "QI")])
16438
16439 (define_insn "rep_stosqi_rex64"
16440   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16441    (set (match_operand:DI 0 "register_operand" "=D") 
16442         (plus:DI (match_operand:DI 3 "register_operand" "0")
16443                  (match_operand:DI 4 "register_operand" "1")))
16444    (set (mem:BLK (match_dup 3))
16445         (const_int 0))
16446    (use (match_operand:QI 2 "register_operand" "a"))
16447    (use (match_dup 4))
16448    (use (reg:DI 19))]
16449   "TARGET_64BIT"
16450   "{rep\;stosb|rep stosb}"
16451   [(set_attr "type" "str")
16452    (set_attr "prefix_rep" "1")
16453    (set_attr "memory" "store")
16454    (set_attr "mode" "QI")])
16455
16456 (define_expand "cmpstrsi"
16457   [(set (match_operand:SI 0 "register_operand" "")
16458         (compare:SI (match_operand:BLK 1 "general_operand" "")
16459                     (match_operand:BLK 2 "general_operand" "")))
16460    (use (match_operand 3 "general_operand" ""))
16461    (use (match_operand 4 "immediate_operand" ""))]
16462   ""
16463 {
16464   rtx addr1, addr2, out, outlow, count, countreg, align;
16465
16466   /* Can't use this if the user has appropriated esi or edi.  */
16467   if (global_regs[4] || global_regs[5])
16468     FAIL;
16469
16470   out = operands[0];
16471   if (GET_CODE (out) != REG)
16472     out = gen_reg_rtx (SImode);
16473
16474   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16475   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16476   
16477   count = operands[3];
16478   countreg = ix86_zero_extend_to_Pmode (count);
16479
16480   /* %%% Iff we are testing strict equality, we can use known alignment
16481      to good advantage.  This may be possible with combine, particularly
16482      once cc0 is dead.  */
16483   align = operands[4];
16484
16485   emit_insn (gen_cld ());
16486   if (GET_CODE (count) == CONST_INT)
16487     {
16488       if (INTVAL (count) == 0)
16489         {
16490           emit_move_insn (operands[0], const0_rtx);
16491           DONE;
16492         }
16493       if (TARGET_64BIT)
16494         emit_insn (gen_cmpstrqi_nz_rex_1 (addr1, addr2, countreg, align,
16495                                           addr1, addr2, countreg));
16496       else
16497         emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
16498                                       addr1, addr2, countreg));
16499     }
16500   else
16501     {
16502       if (TARGET_64BIT)
16503         {
16504           emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
16505           emit_insn (gen_cmpstrqi_rex_1 (addr1, addr2, countreg, align,
16506                                          addr1, addr2, countreg));
16507         }
16508       else
16509         {
16510           emit_insn (gen_cmpsi_1 (countreg, countreg));
16511           emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
16512                                      addr1, addr2, countreg));
16513         }
16514     }
16515
16516   outlow = gen_lowpart (QImode, out);
16517   emit_insn (gen_cmpintqi (outlow));
16518   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16519
16520   if (operands[0] != out)
16521     emit_move_insn (operands[0], out);
16522
16523   DONE;
16524 })
16525
16526 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16527
16528 (define_expand "cmpintqi"
16529   [(set (match_dup 1)
16530         (gtu:QI (reg:CC 17) (const_int 0)))
16531    (set (match_dup 2)
16532         (ltu:QI (reg:CC 17) (const_int 0)))
16533    (parallel [(set (match_operand:QI 0 "register_operand" "")
16534                    (minus:QI (match_dup 1)
16535                              (match_dup 2)))
16536               (clobber (reg:CC 17))])]
16537   ""
16538   "operands[1] = gen_reg_rtx (QImode);
16539    operands[2] = gen_reg_rtx (QImode);")
16540
16541 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16542 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16543
16544 (define_insn "cmpstrqi_nz_1"
16545   [(set (reg:CC 17)
16546         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16547                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16548    (use (match_operand:SI 6 "register_operand" "2"))
16549    (use (match_operand:SI 3 "immediate_operand" "i"))
16550    (use (reg:SI 19))
16551    (clobber (match_operand:SI 0 "register_operand" "=S"))
16552    (clobber (match_operand:SI 1 "register_operand" "=D"))
16553    (clobber (match_operand:SI 2 "register_operand" "=c"))]
16554   "!TARGET_64BIT"
16555   "repz{\;| }cmpsb"
16556   [(set_attr "type" "str")
16557    (set_attr "mode" "QI")
16558    (set_attr "prefix_rep" "1")])
16559
16560 (define_insn "cmpstrqi_nz_rex_1"
16561   [(set (reg:CC 17)
16562         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16563                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16564    (use (match_operand:DI 6 "register_operand" "2"))
16565    (use (match_operand:SI 3 "immediate_operand" "i"))
16566    (use (reg:SI 19))
16567    (clobber (match_operand:DI 0 "register_operand" "=S"))
16568    (clobber (match_operand:DI 1 "register_operand" "=D"))
16569    (clobber (match_operand:DI 2 "register_operand" "=c"))]
16570   "TARGET_64BIT"
16571   "repz{\;| }cmpsb"
16572   [(set_attr "type" "str")
16573    (set_attr "mode" "QI")
16574    (set_attr "prefix_rep" "1")])
16575
16576 ;; The same, but the count is not known to not be zero.
16577
16578 (define_insn "cmpstrqi_1"
16579   [(set (reg:CC 17)
16580         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16581                              (const_int 0))
16582           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16583                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16584           (const_int 0)))
16585    (use (match_operand:SI 3 "immediate_operand" "i"))
16586    (use (reg:CC 17))
16587    (use (reg:SI 19))
16588    (clobber (match_operand:SI 0 "register_operand" "=S"))
16589    (clobber (match_operand:SI 1 "register_operand" "=D"))
16590    (clobber (match_operand:SI 2 "register_operand" "=c"))]
16591   "!TARGET_64BIT"
16592   "repz{\;| }cmpsb"
16593   [(set_attr "type" "str")
16594    (set_attr "mode" "QI")
16595    (set_attr "prefix_rep" "1")])
16596
16597 (define_insn "cmpstrqi_rex_1"
16598   [(set (reg:CC 17)
16599         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16600                              (const_int 0))
16601           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16602                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16603           (const_int 0)))
16604    (use (match_operand:SI 3 "immediate_operand" "i"))
16605    (use (reg:CC 17))
16606    (use (reg:SI 19))
16607    (clobber (match_operand:DI 0 "register_operand" "=S"))
16608    (clobber (match_operand:DI 1 "register_operand" "=D"))
16609    (clobber (match_operand:DI 2 "register_operand" "=c"))]
16610   "TARGET_64BIT"
16611   "repz{\;| }cmpsb"
16612   [(set_attr "type" "str")
16613    (set_attr "mode" "QI")
16614    (set_attr "prefix_rep" "1")])
16615
16616 (define_expand "strlensi"
16617   [(set (match_operand:SI 0 "register_operand" "")
16618         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16619                     (match_operand:QI 2 "immediate_operand" "")
16620                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16621   ""
16622 {
16623  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16624    DONE;
16625  else
16626    FAIL;
16627 })
16628
16629 (define_expand "strlendi"
16630   [(set (match_operand:DI 0 "register_operand" "")
16631         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16632                     (match_operand:QI 2 "immediate_operand" "")
16633                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16634   ""
16635 {
16636  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16637    DONE;
16638  else
16639    FAIL;
16640 })
16641
16642 (define_insn "strlenqi_1"
16643   [(set (match_operand:SI 0 "register_operand" "=&c")
16644         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16645                     (match_operand:QI 2 "register_operand" "a")
16646                     (match_operand:SI 3 "immediate_operand" "i")
16647                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16648    (use (reg:SI 19))
16649    (clobber (match_operand:SI 1 "register_operand" "=D"))
16650    (clobber (reg:CC 17))]
16651   "!TARGET_64BIT"
16652   "repnz{\;| }scasb"
16653   [(set_attr "type" "str")
16654    (set_attr "mode" "QI")
16655    (set_attr "prefix_rep" "1")])
16656
16657 (define_insn "strlenqi_rex_1"
16658   [(set (match_operand:DI 0 "register_operand" "=&c")
16659         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16660                     (match_operand:QI 2 "register_operand" "a")
16661                     (match_operand:DI 3 "immediate_operand" "i")
16662                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16663    (use (reg:SI 19))
16664    (clobber (match_operand:DI 1 "register_operand" "=D"))
16665    (clobber (reg:CC 17))]
16666   "TARGET_64BIT"
16667   "repnz{\;| }scasb"
16668   [(set_attr "type" "str")
16669    (set_attr "mode" "QI")
16670    (set_attr "prefix_rep" "1")])
16671
16672 ;; Peephole optimizations to clean up after cmpstr*.  This should be
16673 ;; handled in combine, but it is not currently up to the task.
16674 ;; When used for their truth value, the cmpstr* expanders generate
16675 ;; code like this:
16676 ;;
16677 ;;   repz cmpsb
16678 ;;   seta       %al
16679 ;;   setb       %dl
16680 ;;   cmpb       %al, %dl
16681 ;;   jcc        label
16682 ;;
16683 ;; The intermediate three instructions are unnecessary.
16684
16685 ;; This one handles cmpstr*_nz_1...
16686 (define_peephole2
16687   [(parallel[
16688      (set (reg:CC 17)
16689           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16690                       (mem:BLK (match_operand 5 "register_operand" ""))))
16691      (use (match_operand 6 "register_operand" ""))
16692      (use (match_operand:SI 3 "immediate_operand" ""))
16693      (use (reg:SI 19))
16694      (clobber (match_operand 0 "register_operand" ""))
16695      (clobber (match_operand 1 "register_operand" ""))
16696      (clobber (match_operand 2 "register_operand" ""))])
16697    (set (match_operand:QI 7 "register_operand" "")
16698         (gtu:QI (reg:CC 17) (const_int 0)))
16699    (set (match_operand:QI 8 "register_operand" "")
16700         (ltu:QI (reg:CC 17) (const_int 0)))
16701    (set (reg 17)
16702         (compare (match_dup 7) (match_dup 8)))
16703   ]
16704   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16705   [(parallel[
16706      (set (reg:CC 17)
16707           (compare:CC (mem:BLK (match_dup 4))
16708                       (mem:BLK (match_dup 5))))
16709      (use (match_dup 6))
16710      (use (match_dup 3))
16711      (use (reg:SI 19))
16712      (clobber (match_dup 0))
16713      (clobber (match_dup 1))
16714      (clobber (match_dup 2))])]
16715   "")
16716
16717 ;; ...and this one handles cmpstr*_1.
16718 (define_peephole2
16719   [(parallel[
16720      (set (reg:CC 17)
16721           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16722                                (const_int 0))
16723             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16724                         (mem:BLK (match_operand 5 "register_operand" "")))
16725             (const_int 0)))
16726      (use (match_operand:SI 3 "immediate_operand" ""))
16727      (use (reg:CC 17))
16728      (use (reg:SI 19))
16729      (clobber (match_operand 0 "register_operand" ""))
16730      (clobber (match_operand 1 "register_operand" ""))
16731      (clobber (match_operand 2 "register_operand" ""))])
16732    (set (match_operand:QI 7 "register_operand" "")
16733         (gtu:QI (reg:CC 17) (const_int 0)))
16734    (set (match_operand:QI 8 "register_operand" "")
16735         (ltu:QI (reg:CC 17) (const_int 0)))
16736    (set (reg 17)
16737         (compare (match_dup 7) (match_dup 8)))
16738   ]
16739   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16740   [(parallel[
16741      (set (reg:CC 17)
16742           (if_then_else:CC (ne (match_dup 6)
16743                                (const_int 0))
16744             (compare:CC (mem:BLK (match_dup 4))
16745                         (mem:BLK (match_dup 5)))
16746             (const_int 0)))
16747      (use (match_dup 3))
16748      (use (reg:CC 17))
16749      (use (reg:SI 19))
16750      (clobber (match_dup 0))
16751      (clobber (match_dup 1))
16752      (clobber (match_dup 2))])]
16753   "")
16754
16755
16756 \f
16757 ;; Conditional move instructions.
16758
16759 (define_expand "movdicc"
16760   [(set (match_operand:DI 0 "register_operand" "")
16761         (if_then_else:DI (match_operand 1 "comparison_operator" "")
16762                          (match_operand:DI 2 "general_operand" "")
16763                          (match_operand:DI 3 "general_operand" "")))]
16764   "TARGET_64BIT"
16765   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16766
16767 (define_insn "x86_movdicc_0_m1_rex64"
16768   [(set (match_operand:DI 0 "register_operand" "=r")
16769         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
16770           (const_int -1)
16771           (const_int 0)))
16772    (clobber (reg:CC 17))]
16773   "TARGET_64BIT"
16774   "sbb{q}\t%0, %0"
16775   ; Since we don't have the proper number of operands for an alu insn,
16776   ; fill in all the blanks.
16777   [(set_attr "type" "alu")
16778    (set_attr "pent_pair" "pu")
16779    (set_attr "memory" "none")
16780    (set_attr "imm_disp" "false")
16781    (set_attr "mode" "DI")
16782    (set_attr "length_immediate" "0")])
16783
16784 (define_insn "movdicc_c_rex64"
16785   [(set (match_operand:DI 0 "register_operand" "=r,r")
16786         (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 
16787                                 [(reg 17) (const_int 0)])
16788                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
16789                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
16790   "TARGET_64BIT && TARGET_CMOVE
16791    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16792   "@
16793    cmov%O2%C1\t{%2, %0|%0, %2}
16794    cmov%O2%c1\t{%3, %0|%0, %3}"
16795   [(set_attr "type" "icmov")
16796    (set_attr "mode" "DI")])
16797
16798 (define_expand "movsicc"
16799   [(set (match_operand:SI 0 "register_operand" "")
16800         (if_then_else:SI (match_operand 1 "comparison_operator" "")
16801                          (match_operand:SI 2 "general_operand" "")
16802                          (match_operand:SI 3 "general_operand" "")))]
16803   ""
16804   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16805
16806 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16807 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16808 ;; So just document what we're doing explicitly.
16809
16810 (define_insn "x86_movsicc_0_m1"
16811   [(set (match_operand:SI 0 "register_operand" "=r")
16812         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
16813           (const_int -1)
16814           (const_int 0)))
16815    (clobber (reg:CC 17))]
16816   ""
16817   "sbb{l}\t%0, %0"
16818   ; Since we don't have the proper number of operands for an alu insn,
16819   ; fill in all the blanks.
16820   [(set_attr "type" "alu")
16821    (set_attr "pent_pair" "pu")
16822    (set_attr "memory" "none")
16823    (set_attr "imm_disp" "false")
16824    (set_attr "mode" "SI")
16825    (set_attr "length_immediate" "0")])
16826
16827 (define_insn "*movsicc_noc"
16828   [(set (match_operand:SI 0 "register_operand" "=r,r")
16829         (if_then_else:SI (match_operator 1 "ix86_comparison_operator" 
16830                                 [(reg 17) (const_int 0)])
16831                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
16832                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
16833   "TARGET_CMOVE
16834    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16835   "@
16836    cmov%O2%C1\t{%2, %0|%0, %2}
16837    cmov%O2%c1\t{%3, %0|%0, %3}"
16838   [(set_attr "type" "icmov")
16839    (set_attr "mode" "SI")])
16840
16841 (define_expand "movhicc"
16842   [(set (match_operand:HI 0 "register_operand" "")
16843         (if_then_else:HI (match_operand 1 "comparison_operator" "")
16844                          (match_operand:HI 2 "general_operand" "")
16845                          (match_operand:HI 3 "general_operand" "")))]
16846   "TARGET_HIMODE_MATH"
16847   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16848
16849 (define_insn "*movhicc_noc"
16850   [(set (match_operand:HI 0 "register_operand" "=r,r")
16851         (if_then_else:HI (match_operator 1 "ix86_comparison_operator" 
16852                                 [(reg 17) (const_int 0)])
16853                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
16854                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
16855   "TARGET_CMOVE
16856    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16857   "@
16858    cmov%O2%C1\t{%2, %0|%0, %2}
16859    cmov%O2%c1\t{%3, %0|%0, %3}"
16860   [(set_attr "type" "icmov")
16861    (set_attr "mode" "HI")])
16862
16863 (define_expand "movqicc"
16864   [(set (match_operand:QI 0 "register_operand" "")
16865         (if_then_else:QI (match_operand 1 "comparison_operator" "")
16866                          (match_operand:QI 2 "general_operand" "")
16867                          (match_operand:QI 3 "general_operand" "")))]
16868   "TARGET_QIMODE_MATH"
16869   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
16870
16871 (define_insn_and_split "*movqicc_noc"
16872   [(set (match_operand:QI 0 "register_operand" "=r,r")
16873         (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 
16874                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16875                       (match_operand:QI 2 "register_operand" "r,0")
16876                       (match_operand:QI 3 "register_operand" "0,r")))]
16877   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16878   "#"
16879   "&& reload_completed"
16880   [(set (match_dup 0)
16881         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16882                       (match_dup 2)
16883                       (match_dup 3)))]
16884   "operands[0] = gen_lowpart (SImode, operands[0]);
16885    operands[2] = gen_lowpart (SImode, operands[2]);
16886    operands[3] = gen_lowpart (SImode, operands[3]);"
16887   [(set_attr "type" "icmov")
16888    (set_attr "mode" "SI")])
16889
16890 (define_expand "movsfcc"
16891   [(set (match_operand:SF 0 "register_operand" "")
16892         (if_then_else:SF (match_operand 1 "comparison_operator" "")
16893                          (match_operand:SF 2 "register_operand" "")
16894                          (match_operand:SF 3 "register_operand" "")))]
16895   "TARGET_CMOVE"
16896   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16897
16898 (define_insn "*movsfcc_1"
16899   [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16900         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 
16901                                 [(reg 17) (const_int 0)])
16902                       (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16903                       (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16904   "TARGET_CMOVE
16905    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16906   "@
16907    fcmov%F1\t{%2, %0|%0, %2}
16908    fcmov%f1\t{%3, %0|%0, %3}
16909    cmov%O2%C1\t{%2, %0|%0, %2}
16910    cmov%O2%c1\t{%3, %0|%0, %3}"
16911   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16912    (set_attr "mode" "SF,SF,SI,SI")])
16913
16914 (define_expand "movdfcc"
16915   [(set (match_operand:DF 0 "register_operand" "")
16916         (if_then_else:DF (match_operand 1 "comparison_operator" "")
16917                          (match_operand:DF 2 "register_operand" "")
16918                          (match_operand:DF 3 "register_operand" "")))]
16919   "TARGET_CMOVE"
16920   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16921
16922 (define_insn "*movdfcc_1"
16923   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
16924         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
16925                                 [(reg 17) (const_int 0)])
16926                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
16927                       (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
16928   "!TARGET_64BIT && TARGET_CMOVE
16929    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16930   "@
16931    fcmov%F1\t{%2, %0|%0, %2}
16932    fcmov%f1\t{%3, %0|%0, %3}
16933    #
16934    #"
16935   [(set_attr "type" "fcmov,fcmov,multi,multi")
16936    (set_attr "mode" "DF")])
16937
16938 (define_insn "*movdfcc_1_rex64"
16939   [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
16940         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
16941                                 [(reg 17) (const_int 0)])
16942                       (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
16943                       (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
16944   "TARGET_64BIT && TARGET_CMOVE
16945    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
16946   "@
16947    fcmov%F1\t{%2, %0|%0, %2}
16948    fcmov%f1\t{%3, %0|%0, %3}
16949    cmov%O2%C1\t{%2, %0|%0, %2}
16950    cmov%O2%c1\t{%3, %0|%0, %3}"
16951   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16952    (set_attr "mode" "DF")])
16953
16954 (define_split
16955   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16956         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 
16957                                 [(match_operand 4 "flags_reg_operand" "") (const_int 0)])
16958                       (match_operand:DF 2 "nonimmediate_operand" "")
16959                       (match_operand:DF 3 "nonimmediate_operand" "")))]
16960   "!TARGET_64BIT && reload_completed"
16961   [(set (match_dup 2)
16962         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16963                       (match_dup 5)
16964                       (match_dup 7)))
16965    (set (match_dup 3)
16966         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16967                       (match_dup 6)
16968                       (match_dup 8)))]
16969   "split_di (operands+2, 1, operands+5, operands+6);
16970    split_di (operands+3, 1, operands+7, operands+8);
16971    split_di (operands, 1, operands+2, operands+3);")
16972
16973 (define_expand "movxfcc"
16974   [(set (match_operand:XF 0 "register_operand" "")
16975         (if_then_else:XF (match_operand 1 "comparison_operator" "")
16976                          (match_operand:XF 2 "register_operand" "")
16977                          (match_operand:XF 3 "register_operand" "")))]
16978   "!TARGET_128BIT_LONG_DOUBLE && TARGET_CMOVE"
16979   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16980
16981 (define_expand "movtfcc"
16982   [(set (match_operand:TF 0 "register_operand" "")
16983         (if_then_else:TF (match_operand 1 "comparison_operator" "")
16984                          (match_operand:TF 2 "register_operand" "")
16985                          (match_operand:TF 3 "register_operand" "")))]
16986   "TARGET_CMOVE"
16987   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
16988
16989 (define_insn "*movxfcc_1"
16990   [(set (match_operand:XF 0 "register_operand" "=f,f")
16991         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 
16992                                 [(reg 17) (const_int 0)])
16993                       (match_operand:XF 2 "register_operand" "f,0")
16994                       (match_operand:XF 3 "register_operand" "0,f")))]
16995   "!TARGET_128BIT_LONG_DOUBLE && TARGET_CMOVE"
16996   "@
16997    fcmov%F1\t{%2, %0|%0, %2}
16998    fcmov%f1\t{%3, %0|%0, %3}"
16999   [(set_attr "type" "fcmov")
17000    (set_attr "mode" "XF")])
17001
17002 (define_insn "*movtfcc_1"
17003   [(set (match_operand:TF 0 "register_operand" "=f,f")
17004         (if_then_else:TF (match_operator 1 "fcmov_comparison_operator" 
17005                                 [(reg 17) (const_int 0)])
17006                       (match_operand:TF 2 "register_operand" "f,0")
17007                       (match_operand:TF 3 "register_operand" "0,f")))]
17008   "TARGET_CMOVE"
17009   "@
17010    fcmov%F1\t{%2, %0|%0, %2}
17011    fcmov%f1\t{%3, %0|%0, %3}"
17012   [(set_attr "type" "fcmov")
17013    (set_attr "mode" "XF")])
17014
17015 (define_expand "minsf3"
17016   [(parallel [
17017      (set (match_operand:SF 0 "register_operand" "")
17018           (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17019                                (match_operand:SF 2 "nonimmediate_operand" ""))
17020                            (match_dup 1)
17021                            (match_dup 2)))
17022      (clobber (reg:CC 17))])]
17023   "TARGET_SSE"
17024   "")
17025
17026 (define_insn "*minsf"
17027   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17028         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0,0,f#x")
17029                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17030                          (match_dup 1)
17031                          (match_dup 2)))
17032    (clobber (reg:CC 17))]
17033   "TARGET_SSE && TARGET_IEEE_FP"
17034   "#")
17035
17036 (define_insn "*minsf_nonieee"
17037   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17038         (if_then_else:SF (lt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17039                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17040                          (match_dup 1)
17041                          (match_dup 2)))
17042    (clobber (reg:CC 17))]
17043   "TARGET_SSE && !TARGET_IEEE_FP
17044    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17045   "#")
17046
17047 (define_split
17048   [(set (match_operand:SF 0 "register_operand" "")
17049         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17050                              (match_operand:SF 2 "nonimmediate_operand" ""))
17051                          (match_operand:SF 3 "register_operand" "")
17052                          (match_operand:SF 4 "nonimmediate_operand" "")))
17053    (clobber (reg:CC 17))]
17054   "SSE_REG_P (operands[0]) && reload_completed
17055    && ((operands_match_p (operands[1], operands[3])
17056         && operands_match_p (operands[2], operands[4]))
17057        || (operands_match_p (operands[1], operands[4])
17058            && operands_match_p (operands[2], operands[3])))"
17059   [(set (match_dup 0)
17060         (if_then_else:SF (lt (match_dup 1)
17061                              (match_dup 2))
17062                          (match_dup 1)
17063                          (match_dup 2)))])
17064
17065 ;; Conditional addition patterns
17066 (define_expand "addqicc"
17067   [(match_operand:QI 0 "register_operand" "")
17068    (match_operand 1 "comparison_operator" "")
17069    (match_operand:QI 2 "register_operand" "")
17070    (match_operand:QI 3 "const_int_operand" "")]
17071   ""
17072   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17073
17074 (define_expand "addhicc"
17075   [(match_operand:HI 0 "register_operand" "")
17076    (match_operand 1 "comparison_operator" "")
17077    (match_operand:HI 2 "register_operand" "")
17078    (match_operand:HI 3 "const_int_operand" "")]
17079   ""
17080   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17081
17082 (define_expand "addsicc"
17083   [(match_operand:SI 0 "register_operand" "")
17084    (match_operand 1 "comparison_operator" "")
17085    (match_operand:SI 2 "register_operand" "")
17086    (match_operand:SI 3 "const_int_operand" "")]
17087   ""
17088   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17089
17090 (define_expand "adddicc"
17091   [(match_operand:DI 0 "register_operand" "")
17092    (match_operand 1 "comparison_operator" "")
17093    (match_operand:DI 2 "register_operand" "")
17094    (match_operand:DI 3 "const_int_operand" "")]
17095   "TARGET_64BIT"
17096   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
17097
17098 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17099
17100 (define_split
17101   [(set (match_operand:SF 0 "fp_register_operand" "")
17102         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "")
17103                              (match_operand:SF 2 "register_operand" ""))
17104                          (match_operand:SF 3 "register_operand" "")
17105                          (match_operand:SF 4 "register_operand" "")))
17106    (clobber (reg:CC 17))]
17107   "reload_completed
17108    && ((operands_match_p (operands[1], operands[3])
17109         && operands_match_p (operands[2], operands[4]))
17110        || (operands_match_p (operands[1], operands[4])
17111            && operands_match_p (operands[2], operands[3])))"
17112   [(set (reg:CCFP 17)
17113         (compare:CCFP (match_dup 2)
17114                       (match_dup 1)))
17115    (set (match_dup 0)
17116         (if_then_else:SF (ge (reg:CCFP 17) (const_int 0))
17117                          (match_dup 1)
17118                          (match_dup 2)))])
17119
17120 (define_insn "*minsf_sse"
17121   [(set (match_operand:SF 0 "register_operand" "=x")
17122         (if_then_else:SF (lt (match_operand:SF 1 "register_operand" "0")
17123                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17124                          (match_dup 1)
17125                          (match_dup 2)))]
17126   "TARGET_SSE && reload_completed"
17127   "minss\t{%2, %0|%0, %2}"
17128   [(set_attr "type" "sse")
17129    (set_attr "mode" "SF")])
17130
17131 (define_expand "mindf3"
17132   [(parallel [
17133      (set (match_operand:DF 0 "register_operand" "")
17134           (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17135                                (match_operand:DF 2 "nonimmediate_operand" ""))
17136                            (match_dup 1)
17137                            (match_dup 2)))
17138      (clobber (reg:CC 17))])]
17139   "TARGET_SSE2 && TARGET_SSE_MATH"
17140   "#")
17141
17142 (define_insn "*mindf"
17143   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17144         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17145                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17146                          (match_dup 1)
17147                          (match_dup 2)))
17148    (clobber (reg:CC 17))]
17149   "TARGET_SSE2 && TARGET_IEEE_FP && TARGET_SSE_MATH"
17150   "#")
17151
17152 (define_insn "*mindf_nonieee"
17153   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17154         (if_then_else:DF (lt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17155                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17156                          (match_dup 1)
17157                          (match_dup 2)))
17158    (clobber (reg:CC 17))]
17159   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17160    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17161   "#")
17162
17163 (define_split
17164   [(set (match_operand:DF 0 "register_operand" "")
17165         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17166                              (match_operand:DF 2 "nonimmediate_operand" ""))
17167                          (match_operand:DF 3 "register_operand" "")
17168                          (match_operand:DF 4 "nonimmediate_operand" "")))
17169    (clobber (reg:CC 17))]
17170   "SSE_REG_P (operands[0]) && reload_completed
17171    && ((operands_match_p (operands[1], operands[3])
17172         && operands_match_p (operands[2], operands[4]))
17173        || (operands_match_p (operands[1], operands[4])
17174            && operands_match_p (operands[2], operands[3])))"
17175   [(set (match_dup 0)
17176         (if_then_else:DF (lt (match_dup 1)
17177                              (match_dup 2))
17178                          (match_dup 1)
17179                          (match_dup 2)))])
17180
17181 ;; We can't represent the LT test directly.  Do this by swapping the operands.
17182 (define_split
17183   [(set (match_operand:DF 0 "fp_register_operand" "")
17184         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "")
17185                              (match_operand:DF 2 "register_operand" ""))
17186                          (match_operand:DF 3 "register_operand" "")
17187                          (match_operand:DF 4 "register_operand" "")))
17188    (clobber (reg:CC 17))]
17189   "reload_completed
17190    && ((operands_match_p (operands[1], operands[3])
17191         && operands_match_p (operands[2], operands[4]))
17192        || (operands_match_p (operands[1], operands[4])
17193            && operands_match_p (operands[2], operands[3])))"
17194   [(set (reg:CCFP 17)
17195         (compare:CCFP (match_dup 2)
17196                       (match_dup 2)))
17197    (set (match_dup 0)
17198         (if_then_else:DF (ge (reg:CCFP 17) (const_int 0))
17199                          (match_dup 1)
17200                          (match_dup 2)))])
17201
17202 (define_insn "*mindf_sse"
17203   [(set (match_operand:DF 0 "register_operand" "=Y")
17204         (if_then_else:DF (lt (match_operand:DF 1 "register_operand" "0")
17205                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17206                          (match_dup 1)
17207                          (match_dup 2)))]
17208   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17209   "minsd\t{%2, %0|%0, %2}"
17210   [(set_attr "type" "sse")
17211    (set_attr "mode" "DF")])
17212
17213 (define_expand "maxsf3"
17214   [(parallel [
17215      (set (match_operand:SF 0 "register_operand" "")
17216           (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17217                                (match_operand:SF 2 "nonimmediate_operand" ""))
17218                            (match_dup 1)
17219                            (match_dup 2)))
17220      (clobber (reg:CC 17))])]
17221   "TARGET_SSE"
17222   "#")
17223
17224 (define_insn "*maxsf"
17225   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x,f#x")
17226         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0,0,f#x")
17227                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x,0"))
17228                          (match_dup 1)
17229                          (match_dup 2)))
17230    (clobber (reg:CC 17))]
17231   "TARGET_SSE && TARGET_IEEE_FP"
17232   "#")
17233
17234 (define_insn "*maxsf_nonieee"
17235   [(set (match_operand:SF 0 "register_operand" "=x#f,f#x")
17236         (if_then_else:SF (gt (match_operand:SF 1 "nonimmediate_operand" "%0,0")
17237                              (match_operand:SF 2 "nonimmediate_operand" "xm#f,f#x"))
17238                          (match_dup 1)
17239                          (match_dup 2)))
17240    (clobber (reg:CC 17))]
17241   "TARGET_SSE && !TARGET_IEEE_FP
17242    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17243   "#")
17244
17245 (define_split
17246   [(set (match_operand:SF 0 "register_operand" "")
17247         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17248                              (match_operand:SF 2 "nonimmediate_operand" ""))
17249                          (match_operand:SF 3 "register_operand" "")
17250                          (match_operand:SF 4 "nonimmediate_operand" "")))
17251    (clobber (reg:CC 17))]
17252   "SSE_REG_P (operands[0]) && reload_completed
17253    && ((operands_match_p (operands[1], operands[3])
17254         && operands_match_p (operands[2], operands[4]))
17255        || (operands_match_p (operands[1], operands[4])
17256            && operands_match_p (operands[2], operands[3])))"
17257   [(set (match_dup 0)
17258         (if_then_else:SF (gt (match_dup 1)
17259                              (match_dup 2))
17260                          (match_dup 1)
17261                          (match_dup 2)))])
17262
17263 (define_split
17264   [(set (match_operand:SF 0 "fp_register_operand" "")
17265         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "")
17266                              (match_operand:SF 2 "register_operand" ""))
17267                          (match_operand:SF 3 "register_operand" "")
17268                          (match_operand:SF 4 "register_operand" "")))
17269    (clobber (reg:CC 17))]
17270   "reload_completed
17271    && ((operands_match_p (operands[1], operands[3])
17272         && operands_match_p (operands[2], operands[4]))
17273        || (operands_match_p (operands[1], operands[4])
17274            && operands_match_p (operands[2], operands[3])))"
17275   [(set (reg:CCFP 17)
17276         (compare:CCFP (match_dup 1)
17277                       (match_dup 2)))
17278    (set (match_dup 0)
17279         (if_then_else:SF (gt (reg:CCFP 17) (const_int 0))
17280                          (match_dup 1)
17281                          (match_dup 2)))])
17282
17283 (define_insn "*maxsf_sse"
17284   [(set (match_operand:SF 0 "register_operand" "=x")
17285         (if_then_else:SF (gt (match_operand:SF 1 "register_operand" "0")
17286                              (match_operand:SF 2 "nonimmediate_operand" "xm"))
17287                          (match_dup 1)
17288                          (match_dup 2)))]
17289   "TARGET_SSE && reload_completed"
17290   "maxss\t{%2, %0|%0, %2}"
17291   [(set_attr "type" "sse")
17292    (set_attr "mode" "SF")])
17293
17294 (define_expand "maxdf3"
17295   [(parallel [
17296      (set (match_operand:DF 0 "register_operand" "")
17297           (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17298                                (match_operand:DF 2 "nonimmediate_operand" ""))
17299                            (match_dup 1)
17300                            (match_dup 2)))
17301      (clobber (reg:CC 17))])]
17302   "TARGET_SSE2 && TARGET_SSE_MATH"
17303   "#")
17304
17305 (define_insn "*maxdf"
17306   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y,f#Y")
17307         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0,0,f#Y")
17308                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y,0"))
17309                          (match_dup 1)
17310                          (match_dup 2)))
17311    (clobber (reg:CC 17))]
17312   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_IEEE_FP"
17313   "#")
17314
17315 (define_insn "*maxdf_nonieee"
17316   [(set (match_operand:DF 0 "register_operand" "=Y#f,f#Y")
17317         (if_then_else:DF (gt (match_operand:DF 1 "nonimmediate_operand" "%0,0")
17318                              (match_operand:DF 2 "nonimmediate_operand" "Ym#f,f#Y"))
17319                          (match_dup 1)
17320                          (match_dup 2)))
17321    (clobber (reg:CC 17))]
17322   "TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_IEEE_FP
17323    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
17324   "#")
17325
17326 (define_split
17327   [(set (match_operand:DF 0 "register_operand" "")
17328         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17329                              (match_operand:DF 2 "nonimmediate_operand" ""))
17330                          (match_operand:DF 3 "register_operand" "")
17331                          (match_operand:DF 4 "nonimmediate_operand" "")))
17332    (clobber (reg:CC 17))]
17333   "SSE_REG_P (operands[0]) && reload_completed
17334    && ((operands_match_p (operands[1], operands[3])
17335         && operands_match_p (operands[2], operands[4]))
17336        || (operands_match_p (operands[1], operands[4])
17337            && operands_match_p (operands[2], operands[3])))"
17338   [(set (match_dup 0)
17339         (if_then_else:DF (gt (match_dup 1)
17340                              (match_dup 2))
17341                          (match_dup 1)
17342                          (match_dup 2)))])
17343
17344 (define_split
17345   [(set (match_operand:DF 0 "fp_register_operand" "")
17346         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "")
17347                              (match_operand:DF 2 "register_operand" ""))
17348                          (match_operand:DF 3 "register_operand" "")
17349                          (match_operand:DF 4 "register_operand" "")))
17350    (clobber (reg:CC 17))]
17351   "reload_completed
17352    && ((operands_match_p (operands[1], operands[3])
17353         && operands_match_p (operands[2], operands[4]))
17354        || (operands_match_p (operands[1], operands[4])
17355            && operands_match_p (operands[2], operands[3])))"
17356   [(set (reg:CCFP 17)
17357         (compare:CCFP (match_dup 1)
17358                       (match_dup 2)))
17359    (set (match_dup 0)
17360         (if_then_else:DF (gt (reg:CCFP 17) (const_int 0))
17361                          (match_dup 1)
17362                          (match_dup 2)))])
17363
17364 (define_insn "*maxdf_sse"
17365   [(set (match_operand:DF 0 "register_operand" "=Y")
17366         (if_then_else:DF (gt (match_operand:DF 1 "register_operand" "0")
17367                              (match_operand:DF 2 "nonimmediate_operand" "Ym"))
17368                          (match_dup 1)
17369                          (match_dup 2)))]
17370   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
17371   "maxsd\t{%2, %0|%0, %2}"
17372   [(set_attr "type" "sse")
17373    (set_attr "mode" "DF")])
17374 \f
17375 ;; Misc patterns (?)
17376
17377 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17378 ;; Otherwise there will be nothing to keep
17379 ;; 
17380 ;; [(set (reg ebp) (reg esp))]
17381 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17382 ;;  (clobber (eflags)]
17383 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17384 ;;
17385 ;; in proper program order.
17386 (define_expand "pro_epilogue_adjust_stack"
17387   [(parallel [(set (match_operand:SI 0 "register_operand" "=r,r")
17388                    (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17389                             (match_operand:SI 2 "immediate_operand" "i,i")))
17390               (clobber (reg:CC 17))
17391               (clobber (mem:BLK (scratch)))])]
17392  ""
17393 {
17394   if (TARGET_64BIT)
17395     {
17396       emit_insn (gen_pro_epilogue_adjust_stack_rex64
17397                  (operands[0], operands[1], operands[2]));
17398       DONE;
17399     }
17400 })
17401
17402 (define_insn "*pro_epilogue_adjust_stack_1"
17403   [(set (match_operand:SI 0 "register_operand" "=r,r")
17404         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17405                  (match_operand:SI 2 "immediate_operand" "i,i")))
17406    (clobber (reg:CC 17))
17407    (clobber (mem:BLK (scratch)))]
17408   "!TARGET_64BIT"
17409 {
17410   switch (get_attr_type (insn))
17411     {
17412     case TYPE_IMOV:
17413       return "mov{l}\t{%1, %0|%0, %1}";
17414
17415     case TYPE_ALU:
17416       if (GET_CODE (operands[2]) == CONST_INT
17417           && (INTVAL (operands[2]) == 128
17418               || (INTVAL (operands[2]) < 0
17419                   && INTVAL (operands[2]) != -128)))
17420         {
17421           operands[2] = GEN_INT (-INTVAL (operands[2]));
17422           return "sub{l}\t{%2, %0|%0, %2}";
17423         }
17424       return "add{l}\t{%2, %0|%0, %2}";
17425
17426     case TYPE_LEA:
17427       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17428       return "lea{l}\t{%a2, %0|%0, %a2}";
17429
17430     default:
17431       abort ();
17432     }
17433 }
17434   [(set (attr "type")
17435         (cond [(eq_attr "alternative" "0")
17436                  (const_string "alu")
17437                (match_operand:SI 2 "const0_operand" "")
17438                  (const_string "imov")
17439               ]
17440               (const_string "lea")))
17441    (set_attr "mode" "SI")])
17442
17443 (define_insn "pro_epilogue_adjust_stack_rex64"
17444   [(set (match_operand:DI 0 "register_operand" "=r,r")
17445         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17446                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17447    (clobber (reg:CC 17))
17448    (clobber (mem:BLK (scratch)))]
17449   "TARGET_64BIT"
17450 {
17451   switch (get_attr_type (insn))
17452     {
17453     case TYPE_IMOV:
17454       return "mov{q}\t{%1, %0|%0, %1}";
17455
17456     case TYPE_ALU:
17457       if (GET_CODE (operands[2]) == CONST_INT
17458           && (INTVAL (operands[2]) == 128
17459               || (INTVAL (operands[2]) < 0
17460                   && INTVAL (operands[2]) != -128)))
17461         {
17462           operands[2] = GEN_INT (-INTVAL (operands[2]));
17463           return "sub{q}\t{%2, %0|%0, %2}";
17464         }
17465       return "add{q}\t{%2, %0|%0, %2}";
17466
17467     case TYPE_LEA:
17468       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17469       return "lea{q}\t{%a2, %0|%0, %a2}";
17470
17471     default:
17472       abort ();
17473     }
17474 }
17475   [(set (attr "type")
17476         (cond [(eq_attr "alternative" "0")
17477                  (const_string "alu")
17478                (match_operand:DI 2 "const0_operand" "")
17479                  (const_string "imov")
17480               ]
17481               (const_string "lea")))
17482    (set_attr "mode" "DI")])
17483
17484
17485 ;; Placeholder for the conditional moves.  This one is split either to SSE
17486 ;; based moves emulation or to usual cmove sequence.  Little bit unfortunate
17487 ;; fact is that compares supported by the cmp??ss instructions are exactly
17488 ;; swapped of those supported by cmove sequence.
17489 ;; The EQ/NE comparisons also needs bit care, since they are not directly
17490 ;; supported by i387 comparisons and we do need to emit two conditional moves
17491 ;; in tandem.
17492
17493 (define_insn "sse_movsfcc"
17494   [(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")
17495         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17496                         [(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")
17497                          (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")])
17498                       (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")
17499                       (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")))
17500    (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17501    (clobber (reg:CC 17))]
17502   "TARGET_SSE
17503    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17504    /* Avoid combine from being smart and converting min/max
17505       instruction patterns into conditional moves.  */
17506    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17507         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17508        || !rtx_equal_p (operands[4], operands[2])
17509        || !rtx_equal_p (operands[5], operands[3]))
17510    && (!TARGET_IEEE_FP
17511        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17512   "#")
17513
17514 (define_insn "sse_movsfcc_eq"
17515   [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
17516         (if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
17517                              (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
17518                       (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
17519                       (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
17520    (clobber (match_scratch:SF 5 "=1,&3,X,X,X,X"))
17521    (clobber (reg:CC 17))]
17522   "TARGET_SSE
17523    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17524   "#")
17525
17526 (define_insn "sse_movdfcc"
17527   [(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")
17528         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17529                         [(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")
17530                          (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")])
17531                       (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")
17532                       (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")))
17533    (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
17534    (clobber (reg:CC 17))]
17535   "TARGET_SSE2
17536    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
17537    /* Avoid combine from being smart and converting min/max
17538       instruction patterns into conditional moves.  */
17539    && ((GET_CODE (operands[1]) != LT && GET_CODE (operands[1]) != GT
17540         && GET_CODE (operands[1]) != UNLE && GET_CODE (operands[1]) != UNGE)
17541        || !rtx_equal_p (operands[4], operands[2])
17542        || !rtx_equal_p (operands[5], operands[3]))
17543    && (!TARGET_IEEE_FP
17544        || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
17545   "#")
17546
17547 (define_insn "sse_movdfcc_eq"
17548   [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf")
17549         (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f")
17550                              (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f"))
17551                       (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY")
17552                       (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY")))
17553    (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
17554    (clobber (reg:CC 17))]
17555   "TARGET_SSE
17556    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17557   "#")
17558
17559 ;; For non-sse moves just expand the usual cmove sequence.
17560 (define_split
17561   [(set (match_operand 0 "register_operand" "")
17562         (if_then_else (match_operator 1 "comparison_operator"
17563                         [(match_operand 4 "nonimmediate_operand" "")
17564                          (match_operand 5 "register_operand" "")])
17565                       (match_operand 2 "nonimmediate_operand" "")
17566                       (match_operand 3 "nonimmediate_operand" "")))
17567    (clobber (match_operand 6 "" ""))
17568    (clobber (reg:CC 17))]
17569   "!SSE_REG_P (operands[0]) && reload_completed
17570    && VALID_SSE_REG_MODE (GET_MODE (operands[0]))"
17571   [(const_int 0)]
17572 {
17573    ix86_compare_op0 = operands[5];
17574    ix86_compare_op1 = operands[4];
17575    operands[1] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[1])),
17576                                  VOIDmode, operands[5], operands[4]);
17577    ix86_expand_fp_movcc (operands);
17578    DONE;
17579 })
17580
17581 ;; Split SSE based conditional move into sequence:
17582 ;; cmpCC op0, op4   -  set op0 to 0 or ffffffff depending on the comparison
17583 ;; and   op2, op0   -  zero op2 if comparison was false
17584 ;; nand  op0, op3   -  load op3 to op0 if comparison was false
17585 ;; or    op2, op0   -  get the nonzero one into the result.
17586 (define_split
17587   [(set (match_operand 0 "register_operand" "")
17588         (if_then_else (match_operator 1 "sse_comparison_operator"
17589                         [(match_operand 4 "register_operand" "")
17590                          (match_operand 5 "nonimmediate_operand" "")])
17591                       (match_operand 2 "register_operand" "")
17592                       (match_operand 3 "register_operand" "")))
17593    (clobber (match_operand 6 "" ""))
17594    (clobber (reg:CC 17))]
17595   "SSE_REG_P (operands[0]) && reload_completed"
17596   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
17597    (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0)
17598                                             (subreg:TI (match_dup 4) 0)))
17599    (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 4) 0))
17600                                             (subreg:TI (match_dup 3) 0)))
17601    (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
17602                                             (subreg:TI (match_dup 7) 0)))]
17603 {
17604   if (GET_MODE (operands[2]) == DFmode
17605       && TARGET_SSE_PARTIAL_REGS && !optimize_size)
17606     {
17607       rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17608       emit_insn (gen_sse2_unpcklpd (op, op, op));
17609       op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17610       emit_insn (gen_sse2_unpcklpd (op, op, op));
17611     }
17612
17613   /* If op2 == op3, op3 would be clobbered before it is used.  */
17614   if (operands_match_p (operands[2], operands[3]))
17615     {
17616       emit_move_insn (operands[0], operands[2]);
17617       DONE;
17618     }
17619
17620   PUT_MODE (operands[1], GET_MODE (operands[0]));
17621   if (operands_match_p (operands[0], operands[4]))
17622     operands[6] = operands[4], operands[7] = operands[2];
17623   else
17624     operands[6] = operands[2], operands[7] = operands[4];
17625 })
17626
17627 ;; Special case of conditional move we can handle effectively.
17628 ;; Do not brother with the integer/floating point case, since these are
17629 ;; bot considerably slower, unlike in the generic case.
17630 (define_insn "*sse_movsfcc_const0_1"
17631   [(set (match_operand:SF 0 "register_operand" "=&x")
17632         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17633                         [(match_operand:SF 4 "register_operand" "0")
17634                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
17635                       (match_operand:SF 2 "register_operand" "x")
17636                       (match_operand:SF 3 "const0_operand" "X")))]
17637   "TARGET_SSE"
17638   "#")
17639
17640 (define_insn "*sse_movsfcc_const0_2"
17641   [(set (match_operand:SF 0 "register_operand" "=&x")
17642         (if_then_else:SF (match_operator 1 "sse_comparison_operator"
17643                         [(match_operand:SF 4 "register_operand" "0")
17644                          (match_operand:SF 5 "nonimmediate_operand" "xm")])
17645                       (match_operand:SF 2 "const0_operand" "X")
17646                       (match_operand:SF 3 "register_operand" "x")))]
17647   "TARGET_SSE"
17648   "#")
17649
17650 (define_insn "*sse_movsfcc_const0_3"
17651   [(set (match_operand:SF 0 "register_operand" "=&x")
17652         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17653                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
17654                          (match_operand:SF 5 "register_operand" "0")])
17655                       (match_operand:SF 2 "register_operand" "x")
17656                       (match_operand:SF 3 "const0_operand" "X")))]
17657   "TARGET_SSE"
17658   "#")
17659
17660 (define_insn "*sse_movsfcc_const0_4"
17661   [(set (match_operand:SF 0 "register_operand" "=&x")
17662         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17663                         [(match_operand:SF 4 "nonimmediate_operand" "xm")
17664                          (match_operand:SF 5 "register_operand" "0")])
17665                       (match_operand:SF 2 "const0_operand" "X")
17666                       (match_operand:SF 3 "register_operand" "x")))]
17667   "TARGET_SSE"
17668   "#")
17669
17670 (define_insn "*sse_movdfcc_const0_1"
17671   [(set (match_operand:DF 0 "register_operand" "=&Y")
17672         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17673                         [(match_operand:DF 4 "register_operand" "0")
17674                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17675                       (match_operand:DF 2 "register_operand" "Y")
17676                       (match_operand:DF 3 "const0_operand" "X")))]
17677   "TARGET_SSE2"
17678   "#")
17679
17680 (define_insn "*sse_movdfcc_const0_2"
17681   [(set (match_operand:DF 0 "register_operand" "=&Y")
17682         (if_then_else:DF (match_operator 1 "sse_comparison_operator"
17683                         [(match_operand:DF 4 "register_operand" "0")
17684                          (match_operand:DF 5 "nonimmediate_operand" "Ym")])
17685                       (match_operand:DF 2 "const0_operand" "X")
17686                       (match_operand:DF 3 "register_operand" "Y")))]
17687   "TARGET_SSE2"
17688   "#")
17689
17690 (define_insn "*sse_movdfcc_const0_3"
17691   [(set (match_operand:DF 0 "register_operand" "=&Y")
17692         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17693                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17694                          (match_operand:DF 5 "register_operand" "0")])
17695                       (match_operand:DF 2 "register_operand" "Y")
17696                       (match_operand:DF 3 "const0_operand" "X")))]
17697   "TARGET_SSE2"
17698   "#")
17699
17700 (define_insn "*sse_movdfcc_const0_4"
17701   [(set (match_operand:DF 0 "register_operand" "=&Y")
17702         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17703                         [(match_operand:DF 4 "nonimmediate_operand" "Ym")
17704                          (match_operand:DF 5 "register_operand" "0")])
17705                       (match_operand:DF 2 "const0_operand" "X")
17706                       (match_operand:DF 3 "register_operand" "Y")))]
17707   "TARGET_SSE2"
17708   "#")
17709
17710 (define_split
17711   [(set (match_operand 0 "register_operand" "")
17712         (if_then_else (match_operator 1 "comparison_operator"
17713                         [(match_operand 4 "nonimmediate_operand" "")
17714                          (match_operand 5 "nonimmediate_operand" "")])
17715                       (match_operand 2 "nonmemory_operand" "")
17716                       (match_operand 3 "nonmemory_operand" "")))]
17717   "SSE_REG_P (operands[0]) && reload_completed
17718    && (const0_operand (operands[2], GET_MODE (operands[0]))
17719        || const0_operand (operands[3], GET_MODE (operands[0])))"
17720   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
17721    (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
17722                                             (match_dup 7)))]
17723 {
17724   if (TARGET_SSE_PARTIAL_REGS && !optimize_size
17725       && GET_MODE (operands[2]) == DFmode)
17726     {
17727       if (REG_P (operands[2]))
17728         {
17729           rtx op = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
17730           emit_insn (gen_sse2_unpcklpd (op, op, op));
17731         }
17732       if (REG_P (operands[3]))
17733         {
17734           rtx op = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
17735           emit_insn (gen_sse2_unpcklpd (op, op, op));
17736         }
17737     }
17738   PUT_MODE (operands[1], GET_MODE (operands[0]));
17739   if (!sse_comparison_operator (operands[1], VOIDmode)
17740       || !rtx_equal_p (operands[0], operands[4]))
17741     {
17742       rtx tmp = operands[5];
17743       operands[5] = operands[4];
17744       operands[4] = tmp;
17745       PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
17746     }
17747   if (!rtx_equal_p (operands[0], operands[4]))
17748     abort ();
17749   if (const0_operand (operands[2], GET_MODE (operands[0])))
17750     {
17751       operands[7] = operands[3];
17752       operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0],
17753                                                          0));
17754     }
17755   else
17756     {
17757       operands[7] = operands[2];
17758       operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
17759     }
17760   operands[7] = simplify_gen_subreg (TImode, operands[7],
17761                                      GET_MODE (operands[7]), 0);
17762 })
17763
17764 (define_expand "allocate_stack_worker"
17765   [(match_operand:SI 0 "register_operand" "")]
17766   "TARGET_STACK_PROBE"
17767 {
17768   if (TARGET_64BIT)
17769     emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
17770   else
17771     emit_insn (gen_allocate_stack_worker_1 (operands[0]));
17772   DONE;
17773 })
17774
17775 (define_insn "allocate_stack_worker_1"
17776   [(unspec:SI [(match_operand:SI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17777    (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0)))
17778    (clobber (match_dup 0))
17779    (clobber (reg:CC 17))]
17780   "!TARGET_64BIT && TARGET_STACK_PROBE"
17781   "call\t__alloca"
17782   [(set_attr "type" "multi")
17783    (set_attr "length" "5")])
17784
17785 (define_insn "allocate_stack_worker_rex64"
17786   [(unspec:DI [(match_operand:DI 0 "register_operand" "a")] UNSPEC_STACK_PROBE)
17787    (set (reg:DI 7) (minus:DI (reg:DI 7) (match_dup 0)))
17788    (clobber (match_dup 0))
17789    (clobber (reg:CC 17))]
17790   "TARGET_64BIT && TARGET_STACK_PROBE"
17791   "call\t__alloca"
17792   [(set_attr "type" "multi")
17793    (set_attr "length" "5")])
17794
17795 (define_expand "allocate_stack"
17796   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
17797                    (minus:SI (reg:SI 7)
17798                              (match_operand:SI 1 "general_operand" "")))
17799               (clobber (reg:CC 17))])
17800    (parallel [(set (reg:SI 7)
17801                    (minus:SI (reg:SI 7) (match_dup 1)))
17802               (clobber (reg:CC 17))])]
17803   "TARGET_STACK_PROBE"
17804 {
17805 #ifdef CHECK_STACK_LIMIT
17806   if (GET_CODE (operands[1]) == CONST_INT
17807       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17808     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
17809                            operands[1]));
17810   else 
17811 #endif
17812     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
17813                                                             operands[1])));
17814
17815   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17816   DONE;
17817 })
17818
17819 (define_expand "builtin_setjmp_receiver"
17820   [(label_ref (match_operand 0 "" ""))]
17821   "!TARGET_64BIT && flag_pic"
17822 {
17823   emit_insn (gen_set_got (pic_offset_table_rtx));
17824   DONE;
17825 })
17826 \f
17827 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17828
17829 (define_split
17830   [(set (match_operand 0 "register_operand" "")
17831         (match_operator 3 "promotable_binary_operator"
17832            [(match_operand 1 "register_operand" "")
17833             (match_operand 2 "aligned_operand" "")]))
17834    (clobber (reg:CC 17))]
17835   "! TARGET_PARTIAL_REG_STALL && reload_completed
17836    && ((GET_MODE (operands[0]) == HImode 
17837         && ((!optimize_size && !TARGET_FAST_PREFIX)
17838             || GET_CODE (operands[2]) != CONST_INT
17839             || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
17840        || (GET_MODE (operands[0]) == QImode 
17841            && (TARGET_PROMOTE_QImode || optimize_size)))"
17842   [(parallel [(set (match_dup 0)
17843                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17844               (clobber (reg:CC 17))])]
17845   "operands[0] = gen_lowpart (SImode, operands[0]);
17846    operands[1] = gen_lowpart (SImode, operands[1]);
17847    if (GET_CODE (operands[3]) != ASHIFT)
17848      operands[2] = gen_lowpart (SImode, operands[2]);
17849    PUT_MODE (operands[3], SImode);")
17850
17851 ; Promote the QImode tests, as i386 has encoding of the AND
17852 ; instruction with 32-bit sign-extended immediate and thus the
17853 ; instruction size is unchanged, except in the %eax case for
17854 ; which it is increased by one byte, hence the ! optimize_size.
17855 (define_split
17856   [(set (reg 17)
17857         (compare (and (match_operand 1 "aligned_operand" "")
17858                       (match_operand 2 "const_int_operand" ""))
17859                  (const_int 0)))
17860    (set (match_operand 0 "register_operand" "")
17861         (and (match_dup 1) (match_dup 2)))]
17862   "! TARGET_PARTIAL_REG_STALL && reload_completed
17863    /* Ensure that the operand will remain sign-extended immediate.  */
17864    && ix86_match_ccmode (insn, INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)
17865    && ! optimize_size
17866    && ((GET_MODE (operands[0]) == HImode && ! TARGET_FAST_PREFIX)
17867        || (GET_MODE (operands[0]) == QImode && TARGET_PROMOTE_QImode))"
17868   [(parallel [(set (reg:CCNO 17)
17869                    (compare:CCNO (and:SI (match_dup 1) (match_dup 2))
17870                                  (const_int 0)))
17871               (set (match_dup 0)
17872                    (and:SI (match_dup 1) (match_dup 2)))])]
17873   "operands[2]
17874      = gen_int_mode (INTVAL (operands[2])
17875                      & GET_MODE_MASK (GET_MODE (operands[0])),
17876                      SImode);
17877    operands[0] = gen_lowpart (SImode, operands[0]);
17878    operands[1] = gen_lowpart (SImode, operands[1]);")
17879
17880 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17881 ; the TEST instruction with 32-bit sign-extended immediate and thus
17882 ; the instruction size would at least double, which is not what we
17883 ; want even with ! optimize_size.
17884 (define_split
17885   [(set (reg 17)
17886         (compare (and (match_operand:HI 0 "aligned_operand" "")
17887                       (match_operand:HI 1 "const_int_operand" ""))
17888                  (const_int 0)))]
17889   "! TARGET_PARTIAL_REG_STALL && reload_completed
17890    /* Ensure that the operand will remain sign-extended immediate.  */
17891    && ix86_match_ccmode (insn, INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)
17892    && ! TARGET_FAST_PREFIX
17893    && ! optimize_size"
17894   [(set (reg:CCNO 17)
17895         (compare:CCNO (and:SI (match_dup 0) (match_dup 1))
17896                       (const_int 0)))]
17897   "operands[1]
17898      = gen_int_mode (INTVAL (operands[1])
17899                      & GET_MODE_MASK (GET_MODE (operands[0])),
17900                      SImode);
17901    operands[0] = gen_lowpart (SImode, operands[0]);")
17902
17903 (define_split
17904   [(set (match_operand 0 "register_operand" "")
17905         (neg (match_operand 1 "register_operand" "")))
17906    (clobber (reg:CC 17))]
17907   "! TARGET_PARTIAL_REG_STALL && reload_completed
17908    && (GET_MODE (operands[0]) == HImode
17909        || (GET_MODE (operands[0]) == QImode 
17910            && (TARGET_PROMOTE_QImode || optimize_size)))"
17911   [(parallel [(set (match_dup 0)
17912                    (neg:SI (match_dup 1)))
17913               (clobber (reg:CC 17))])]
17914   "operands[0] = gen_lowpart (SImode, operands[0]);
17915    operands[1] = gen_lowpart (SImode, operands[1]);")
17916
17917 (define_split
17918   [(set (match_operand 0 "register_operand" "")
17919         (not (match_operand 1 "register_operand" "")))]
17920   "! TARGET_PARTIAL_REG_STALL && reload_completed
17921    && (GET_MODE (operands[0]) == HImode
17922        || (GET_MODE (operands[0]) == QImode 
17923            && (TARGET_PROMOTE_QImode || optimize_size)))"
17924   [(set (match_dup 0)
17925         (not:SI (match_dup 1)))]
17926   "operands[0] = gen_lowpart (SImode, operands[0]);
17927    operands[1] = gen_lowpart (SImode, operands[1]);")
17928
17929 (define_split 
17930   [(set (match_operand 0 "register_operand" "")
17931         (if_then_else (match_operator 1 "comparison_operator" 
17932                                 [(reg 17) (const_int 0)])
17933                       (match_operand 2 "register_operand" "")
17934                       (match_operand 3 "register_operand" "")))]
17935   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
17936    && (GET_MODE (operands[0]) == HImode
17937        || (GET_MODE (operands[0]) == QImode 
17938            && (TARGET_PROMOTE_QImode || optimize_size)))"
17939   [(set (match_dup 0)
17940         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17941   "operands[0] = gen_lowpart (SImode, operands[0]);
17942    operands[2] = gen_lowpart (SImode, operands[2]);
17943    operands[3] = gen_lowpart (SImode, operands[3]);")
17944                         
17945 \f
17946 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
17947 ;; transform a complex memory operation into two memory to register operations.
17948
17949 ;; Don't push memory operands
17950 (define_peephole2
17951   [(set (match_operand:SI 0 "push_operand" "")
17952         (match_operand:SI 1 "memory_operand" ""))
17953    (match_scratch:SI 2 "r")]
17954   "! optimize_size && ! TARGET_PUSH_MEMORY"
17955   [(set (match_dup 2) (match_dup 1))
17956    (set (match_dup 0) (match_dup 2))]
17957   "")
17958
17959 (define_peephole2
17960   [(set (match_operand:DI 0 "push_operand" "")
17961         (match_operand:DI 1 "memory_operand" ""))
17962    (match_scratch:DI 2 "r")]
17963   "! optimize_size && ! TARGET_PUSH_MEMORY"
17964   [(set (match_dup 2) (match_dup 1))
17965    (set (match_dup 0) (match_dup 2))]
17966   "")
17967
17968 ;; We need to handle SFmode only, because DFmode and XFmode is split to
17969 ;; SImode pushes.
17970 (define_peephole2
17971   [(set (match_operand:SF 0 "push_operand" "")
17972         (match_operand:SF 1 "memory_operand" ""))
17973    (match_scratch:SF 2 "r")]
17974   "! optimize_size && ! TARGET_PUSH_MEMORY"
17975   [(set (match_dup 2) (match_dup 1))
17976    (set (match_dup 0) (match_dup 2))]
17977   "")
17978
17979 (define_peephole2
17980   [(set (match_operand:HI 0 "push_operand" "")
17981         (match_operand:HI 1 "memory_operand" ""))
17982    (match_scratch:HI 2 "r")]
17983   "! optimize_size && ! TARGET_PUSH_MEMORY"
17984   [(set (match_dup 2) (match_dup 1))
17985    (set (match_dup 0) (match_dup 2))]
17986   "")
17987
17988 (define_peephole2
17989   [(set (match_operand:QI 0 "push_operand" "")
17990         (match_operand:QI 1 "memory_operand" ""))
17991    (match_scratch:QI 2 "q")]
17992   "! optimize_size && ! TARGET_PUSH_MEMORY"
17993   [(set (match_dup 2) (match_dup 1))
17994    (set (match_dup 0) (match_dup 2))]
17995   "")
17996
17997 ;; Don't move an immediate directly to memory when the instruction
17998 ;; gets too big.
17999 (define_peephole2
18000   [(match_scratch:SI 1 "r")
18001    (set (match_operand:SI 0 "memory_operand" "")
18002         (const_int 0))]
18003   "! optimize_size
18004    && ! TARGET_USE_MOV0
18005    && TARGET_SPLIT_LONG_MOVES
18006    && get_attr_length (insn) >= ix86_cost->large_insn
18007    && peep2_regno_dead_p (0, FLAGS_REG)"
18008   [(parallel [(set (match_dup 1) (const_int 0))
18009               (clobber (reg:CC 17))])
18010    (set (match_dup 0) (match_dup 1))]
18011   "")
18012
18013 (define_peephole2
18014   [(match_scratch:HI 1 "r")
18015    (set (match_operand:HI 0 "memory_operand" "")
18016         (const_int 0))]
18017   "! optimize_size
18018    && ! TARGET_USE_MOV0
18019    && TARGET_SPLIT_LONG_MOVES
18020    && get_attr_length (insn) >= ix86_cost->large_insn
18021    && peep2_regno_dead_p (0, FLAGS_REG)"
18022   [(parallel [(set (match_dup 2) (const_int 0))
18023               (clobber (reg:CC 17))])
18024    (set (match_dup 0) (match_dup 1))]
18025   "operands[2] = gen_lowpart (SImode, operands[1]);")
18026
18027 (define_peephole2
18028   [(match_scratch:QI 1 "q")
18029    (set (match_operand:QI 0 "memory_operand" "")
18030         (const_int 0))]
18031   "! optimize_size
18032    && ! TARGET_USE_MOV0
18033    && TARGET_SPLIT_LONG_MOVES
18034    && get_attr_length (insn) >= ix86_cost->large_insn
18035    && peep2_regno_dead_p (0, FLAGS_REG)"
18036   [(parallel [(set (match_dup 2) (const_int 0))
18037               (clobber (reg:CC 17))])
18038    (set (match_dup 0) (match_dup 1))]
18039   "operands[2] = gen_lowpart (SImode, operands[1]);")
18040
18041 (define_peephole2
18042   [(match_scratch:SI 2 "r")
18043    (set (match_operand:SI 0 "memory_operand" "")
18044         (match_operand:SI 1 "immediate_operand" ""))]
18045   "! optimize_size
18046    && get_attr_length (insn) >= ix86_cost->large_insn
18047    && TARGET_SPLIT_LONG_MOVES"
18048   [(set (match_dup 2) (match_dup 1))
18049    (set (match_dup 0) (match_dup 2))]
18050   "")
18051
18052 (define_peephole2
18053   [(match_scratch:HI 2 "r")
18054    (set (match_operand:HI 0 "memory_operand" "")
18055         (match_operand:HI 1 "immediate_operand" ""))]
18056   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18057   && TARGET_SPLIT_LONG_MOVES"
18058   [(set (match_dup 2) (match_dup 1))
18059    (set (match_dup 0) (match_dup 2))]
18060   "")
18061
18062 (define_peephole2
18063   [(match_scratch:QI 2 "q")
18064    (set (match_operand:QI 0 "memory_operand" "")
18065         (match_operand:QI 1 "immediate_operand" ""))]
18066   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18067   && TARGET_SPLIT_LONG_MOVES"
18068   [(set (match_dup 2) (match_dup 1))
18069    (set (match_dup 0) (match_dup 2))]
18070   "")
18071
18072 ;; Don't compare memory with zero, load and use a test instead.
18073 (define_peephole2
18074   [(set (reg 17)
18075         (compare (match_operand:SI 0 "memory_operand" "")
18076                  (const_int 0)))
18077    (match_scratch:SI 3 "r")]
18078   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18079   [(set (match_dup 3) (match_dup 0))
18080    (set (reg:CCNO 17) (compare:CCNO (match_dup 3) (const_int 0)))]
18081   "")
18082
18083 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 
18084 ;; Don't split NOTs with a displacement operand, because resulting XOR
18085 ;; will not be pairable anyway.
18086 ;;
18087 ;; On AMD K6, NOT is vector decoded with memory operand that can not be
18088 ;; represented using a modRM byte.  The XOR replacement is long decoded,
18089 ;; so this split helps here as well.
18090 ;;
18091 ;; Note: Can't do this as a regular split because we can't get proper
18092 ;; lifetime information then.
18093
18094 (define_peephole2
18095   [(set (match_operand:SI 0 "nonimmediate_operand" "")
18096         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18097   "!optimize_size
18098    && peep2_regno_dead_p (0, FLAGS_REG)
18099    && ((TARGET_PENTIUM 
18100         && (GET_CODE (operands[0]) != MEM
18101             || !memory_displacement_operand (operands[0], SImode)))
18102        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18103   [(parallel [(set (match_dup 0)
18104                    (xor:SI (match_dup 1) (const_int -1)))
18105               (clobber (reg:CC 17))])]
18106   "")
18107
18108 (define_peephole2
18109   [(set (match_operand:HI 0 "nonimmediate_operand" "")
18110         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18111   "!optimize_size
18112    && peep2_regno_dead_p (0, FLAGS_REG)
18113    && ((TARGET_PENTIUM 
18114         && (GET_CODE (operands[0]) != MEM
18115             || !memory_displacement_operand (operands[0], HImode)))
18116        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18117   [(parallel [(set (match_dup 0)
18118                    (xor:HI (match_dup 1) (const_int -1)))
18119               (clobber (reg:CC 17))])]
18120   "")
18121
18122 (define_peephole2
18123   [(set (match_operand:QI 0 "nonimmediate_operand" "")
18124         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18125   "!optimize_size
18126    && peep2_regno_dead_p (0, FLAGS_REG)
18127    && ((TARGET_PENTIUM 
18128         && (GET_CODE (operands[0]) != MEM
18129             || !memory_displacement_operand (operands[0], QImode)))
18130        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18131   [(parallel [(set (match_dup 0)
18132                    (xor:QI (match_dup 1) (const_int -1)))
18133               (clobber (reg:CC 17))])]
18134   "")
18135
18136 ;; Non pairable "test imm, reg" instructions can be translated to
18137 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
18138 ;; byte opcode instead of two, have a short form for byte operands),
18139 ;; so do it for other CPUs as well.  Given that the value was dead,
18140 ;; this should not create any new dependencies.  Pass on the sub-word
18141 ;; versions if we're concerned about partial register stalls.
18142
18143 (define_peephole2
18144   [(set (reg 17)
18145         (compare (and:SI (match_operand:SI 0 "register_operand" "")
18146                          (match_operand:SI 1 "immediate_operand" ""))
18147                  (const_int 0)))]
18148   "ix86_match_ccmode (insn, CCNOmode)
18149    && (true_regnum (operands[0]) != 0
18150        || (GET_CODE (operands[1]) == CONST_INT
18151            && CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K')))
18152    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18153   [(parallel
18154      [(set (reg:CCNO 17)
18155            (compare:CCNO (and:SI (match_dup 0)
18156                                  (match_dup 1))
18157                          (const_int 0)))
18158       (set (match_dup 0)
18159            (and:SI (match_dup 0) (match_dup 1)))])]
18160   "")
18161
18162 ;; We don't need to handle HImode case, because it will be promoted to SImode
18163 ;; on ! TARGET_PARTIAL_REG_STALL
18164
18165 (define_peephole2
18166   [(set (reg 17)
18167         (compare (and:QI (match_operand:QI 0 "register_operand" "")
18168                          (match_operand:QI 1 "immediate_operand" ""))
18169                  (const_int 0)))]
18170   "! TARGET_PARTIAL_REG_STALL
18171    && ix86_match_ccmode (insn, CCNOmode)
18172    && true_regnum (operands[0]) != 0
18173    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18174   [(parallel
18175      [(set (reg:CCNO 17)
18176            (compare:CCNO (and:QI (match_dup 0)
18177                                  (match_dup 1))
18178                          (const_int 0)))
18179       (set (match_dup 0)
18180            (and:QI (match_dup 0) (match_dup 1)))])]
18181   "")
18182
18183 (define_peephole2
18184   [(set (reg 17)
18185         (compare
18186           (and:SI
18187             (zero_extract:SI
18188               (match_operand 0 "ext_register_operand" "")
18189               (const_int 8)
18190               (const_int 8))
18191             (match_operand 1 "const_int_operand" ""))
18192           (const_int 0)))]
18193   "! TARGET_PARTIAL_REG_STALL
18194    && ix86_match_ccmode (insn, CCNOmode)
18195    && true_regnum (operands[0]) != 0
18196    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18197   [(parallel [(set (reg:CCNO 17)
18198                    (compare:CCNO
18199                        (and:SI
18200                          (zero_extract:SI
18201                          (match_dup 0)
18202                          (const_int 8)
18203                          (const_int 8))
18204                         (match_dup 1))
18205                    (const_int 0)))
18206               (set (zero_extract:SI (match_dup 0)
18207                                     (const_int 8)
18208                                     (const_int 8))
18209                    (and:SI 
18210                      (zero_extract:SI
18211                        (match_dup 0)
18212                        (const_int 8)
18213                        (const_int 8))
18214                      (match_dup 1)))])]
18215   "")
18216
18217 ;; Don't do logical operations with memory inputs.
18218 (define_peephole2
18219   [(match_scratch:SI 2 "r")
18220    (parallel [(set (match_operand:SI 0 "register_operand" "")
18221                    (match_operator:SI 3 "arith_or_logical_operator"
18222                      [(match_dup 0)
18223                       (match_operand:SI 1 "memory_operand" "")]))
18224               (clobber (reg:CC 17))])]
18225   "! optimize_size && ! TARGET_READ_MODIFY"
18226   [(set (match_dup 2) (match_dup 1))
18227    (parallel [(set (match_dup 0)
18228                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18229               (clobber (reg:CC 17))])]
18230   "")
18231
18232 (define_peephole2
18233   [(match_scratch:SI 2 "r")
18234    (parallel [(set (match_operand:SI 0 "register_operand" "")
18235                    (match_operator:SI 3 "arith_or_logical_operator"
18236                      [(match_operand:SI 1 "memory_operand" "")
18237                       (match_dup 0)]))
18238               (clobber (reg:CC 17))])]
18239   "! optimize_size && ! TARGET_READ_MODIFY"
18240   [(set (match_dup 2) (match_dup 1))
18241    (parallel [(set (match_dup 0)
18242                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18243               (clobber (reg:CC 17))])]
18244   "")
18245
18246 ; Don't do logical operations with memory outputs
18247 ;
18248 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18249 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
18250 ; the same decoder scheduling characteristics as the original.
18251
18252 (define_peephole2
18253   [(match_scratch:SI 2 "r")
18254    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18255                    (match_operator:SI 3 "arith_or_logical_operator"
18256                      [(match_dup 0)
18257                       (match_operand:SI 1 "nonmemory_operand" "")]))
18258               (clobber (reg:CC 17))])]
18259   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18260   [(set (match_dup 2) (match_dup 0))
18261    (parallel [(set (match_dup 2)
18262                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18263               (clobber (reg:CC 17))])
18264    (set (match_dup 0) (match_dup 2))]
18265   "")
18266
18267 (define_peephole2
18268   [(match_scratch:SI 2 "r")
18269    (parallel [(set (match_operand:SI 0 "memory_operand" "")
18270                    (match_operator:SI 3 "arith_or_logical_operator"
18271                      [(match_operand:SI 1 "nonmemory_operand" "")
18272                       (match_dup 0)]))
18273               (clobber (reg:CC 17))])]
18274   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18275   [(set (match_dup 2) (match_dup 0))
18276    (parallel [(set (match_dup 2)
18277                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18278               (clobber (reg:CC 17))])
18279    (set (match_dup 0) (match_dup 2))]
18280   "")
18281
18282 ;; Attempt to always use XOR for zeroing registers.
18283 (define_peephole2
18284   [(set (match_operand 0 "register_operand" "")
18285         (const_int 0))]
18286   "(GET_MODE (operands[0]) == QImode
18287     || GET_MODE (operands[0]) == HImode
18288     || GET_MODE (operands[0]) == SImode
18289     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18290    && (! TARGET_USE_MOV0 || optimize_size)
18291    && peep2_regno_dead_p (0, FLAGS_REG)"
18292   [(parallel [(set (match_dup 0) (const_int 0))
18293               (clobber (reg:CC 17))])]
18294   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18295                               operands[0]);")
18296
18297 (define_peephole2
18298   [(set (strict_low_part (match_operand 0 "register_operand" ""))
18299         (const_int 0))]
18300   "(GET_MODE (operands[0]) == QImode
18301     || GET_MODE (operands[0]) == HImode)
18302    && (! TARGET_USE_MOV0 || optimize_size)
18303    && peep2_regno_dead_p (0, FLAGS_REG)"
18304   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18305               (clobber (reg:CC 17))])])
18306
18307 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18308 (define_peephole2
18309   [(set (match_operand 0 "register_operand" "")
18310         (const_int -1))]
18311   "(GET_MODE (operands[0]) == HImode
18312     || GET_MODE (operands[0]) == SImode 
18313     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18314    && (optimize_size || TARGET_PENTIUM)
18315    && peep2_regno_dead_p (0, FLAGS_REG)"
18316   [(parallel [(set (match_dup 0) (const_int -1))
18317               (clobber (reg:CC 17))])]
18318   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18319                               operands[0]);")
18320
18321 ;; Attempt to convert simple leas to adds. These can be created by
18322 ;; move expanders.
18323 (define_peephole2
18324   [(set (match_operand:SI 0 "register_operand" "")
18325         (plus:SI (match_dup 0)
18326                  (match_operand:SI 1 "nonmemory_operand" "")))]
18327   "peep2_regno_dead_p (0, FLAGS_REG)"
18328   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18329               (clobber (reg:CC 17))])]
18330   "")
18331
18332 (define_peephole2
18333   [(set (match_operand:SI 0 "register_operand" "")
18334         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18335                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18336   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18337   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18338               (clobber (reg:CC 17))])]
18339   "operands[2] = gen_lowpart (SImode, operands[2]);")
18340
18341 (define_peephole2
18342   [(set (match_operand:DI 0 "register_operand" "")
18343         (plus:DI (match_dup 0)
18344                  (match_operand:DI 1 "x86_64_general_operand" "")))]
18345   "peep2_regno_dead_p (0, FLAGS_REG)"
18346   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18347               (clobber (reg:CC 17))])]
18348   "")
18349
18350 (define_peephole2
18351   [(set (match_operand:SI 0 "register_operand" "")
18352         (mult:SI (match_dup 0)
18353                  (match_operand:SI 1 "const_int_operand" "")))]
18354   "exact_log2 (INTVAL (operands[1])) >= 0
18355    && peep2_regno_dead_p (0, FLAGS_REG)"
18356   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18357               (clobber (reg:CC 17))])]
18358   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18359
18360 (define_peephole2
18361   [(set (match_operand:DI 0 "register_operand" "")
18362         (mult:DI (match_dup 0)
18363                  (match_operand:DI 1 "const_int_operand" "")))]
18364   "exact_log2 (INTVAL (operands[1])) >= 0
18365    && peep2_regno_dead_p (0, FLAGS_REG)"
18366   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
18367               (clobber (reg:CC 17))])]
18368   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18369
18370 (define_peephole2
18371   [(set (match_operand:SI 0 "register_operand" "")
18372         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
18373                    (match_operand:DI 2 "const_int_operand" "")) 0))]
18374   "exact_log2 (INTVAL (operands[2])) >= 0
18375    && REGNO (operands[0]) == REGNO (operands[1])
18376    && peep2_regno_dead_p (0, FLAGS_REG)"
18377   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18378               (clobber (reg:CC 17))])]
18379   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18380
18381 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
18382 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
18383 ;; many CPUs it is also faster, since special hardware to avoid esp
18384 ;; dependencies is present.
18385
18386 ;; While some of these conversions may be done using splitters, we use peepholes
18387 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
18388
18389 ;; Convert prologue esp subtractions to push.
18390 ;; We need register to push.  In order to keep verify_flow_info happy we have
18391 ;; two choices
18392 ;; - use scratch and clobber it in order to avoid dependencies
18393 ;; - use already live register
18394 ;; We can't use the second way right now, since there is no reliable way how to
18395 ;; verify that given register is live.  First choice will also most likely in
18396 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
18397 ;; call clobbered registers are dead.  We may want to use base pointer as an
18398 ;; alternative when no register is available later.
18399
18400 (define_peephole2
18401   [(match_scratch:SI 0 "r")
18402    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18403               (clobber (reg:CC 17))
18404               (clobber (mem:BLK (scratch)))])]
18405   "optimize_size || !TARGET_SUB_ESP_4"
18406   [(clobber (match_dup 0))
18407    (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18408               (clobber (mem:BLK (scratch)))])])
18409
18410 (define_peephole2
18411   [(match_scratch:SI 0 "r")
18412    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18413               (clobber (reg:CC 17))
18414               (clobber (mem:BLK (scratch)))])]
18415   "optimize_size || !TARGET_SUB_ESP_8"
18416   [(clobber (match_dup 0))
18417    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18418    (parallel [(set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18419               (clobber (mem:BLK (scratch)))])])
18420
18421 ;; Convert esp subtractions to push.
18422 (define_peephole2
18423   [(match_scratch:SI 0 "r")
18424    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -4)))
18425               (clobber (reg:CC 17))])]
18426   "optimize_size || !TARGET_SUB_ESP_4"
18427   [(clobber (match_dup 0))
18428    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18429
18430 (define_peephole2
18431   [(match_scratch:SI 0 "r")
18432    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -8)))
18433               (clobber (reg:CC 17))])]
18434   "optimize_size || !TARGET_SUB_ESP_8"
18435   [(clobber (match_dup 0))
18436    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))
18437    (set (mem:SI (pre_dec:SI (reg:SI 7))) (match_dup 0))])
18438
18439 ;; Convert epilogue deallocator to pop.
18440 (define_peephole2
18441   [(match_scratch:SI 0 "r")
18442    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18443               (clobber (reg:CC 17))
18444               (clobber (mem:BLK (scratch)))])]
18445   "optimize_size || !TARGET_ADD_ESP_4"
18446   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18447               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18448               (clobber (mem:BLK (scratch)))])]
18449   "")
18450
18451 ;; Two pops case is tricky, since pop causes dependency on destination register.
18452 ;; We use two registers if available.
18453 (define_peephole2
18454   [(match_scratch:SI 0 "r")
18455    (match_scratch:SI 1 "r")
18456    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18457               (clobber (reg:CC 17))
18458               (clobber (mem:BLK (scratch)))])]
18459   "optimize_size || !TARGET_ADD_ESP_8"
18460   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18461               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18462               (clobber (mem:BLK (scratch)))])
18463    (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18464               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18465   "")
18466
18467 (define_peephole2
18468   [(match_scratch:SI 0 "r")
18469    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18470               (clobber (reg:CC 17))
18471               (clobber (mem:BLK (scratch)))])]
18472   "optimize_size"
18473   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18474               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18475               (clobber (mem:BLK (scratch)))])
18476    (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18477               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18478   "")
18479
18480 ;; Convert esp additions to pop.
18481 (define_peephole2
18482   [(match_scratch:SI 0 "r")
18483    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))
18484               (clobber (reg:CC 17))])]
18485   ""
18486   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18487               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18488   "")
18489
18490 ;; Two pops case is tricky, since pop causes dependency on destination register.
18491 ;; We use two registers if available.
18492 (define_peephole2
18493   [(match_scratch:SI 0 "r")
18494    (match_scratch:SI 1 "r")
18495    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18496               (clobber (reg:CC 17))])]
18497   ""
18498   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18499               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18500    (parallel [(set (match_dup 1) (mem:SI (reg:SI 7)))
18501               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18502   "")
18503
18504 (define_peephole2
18505   [(match_scratch:SI 0 "r")
18506    (parallel [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 8)))
18507               (clobber (reg:CC 17))])]
18508   "optimize_size"
18509   [(parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18510               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])
18511    (parallel [(set (match_dup 0) (mem:SI (reg:SI 7)))
18512               (set (reg:SI 7) (plus:SI (reg:SI 7) (const_int 4)))])]
18513   "")
18514 \f
18515 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18516 ;; required and register dies.
18517 (define_peephole2
18518   [(set (reg 17)
18519         (compare (match_operand:SI 0 "register_operand" "")
18520                  (match_operand:SI 1 "incdec_operand" "")))]
18521   "ix86_match_ccmode (insn, CCGCmode)
18522    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18523   [(parallel [(set (reg:CCGC 17)
18524                    (compare:CCGC (match_dup 0)
18525                                  (match_dup 1)))
18526               (clobber (match_dup 0))])]
18527   "")
18528
18529 (define_peephole2
18530   [(set (reg 17)
18531         (compare (match_operand:HI 0 "register_operand" "")
18532                  (match_operand:HI 1 "incdec_operand" "")))]
18533   "ix86_match_ccmode (insn, CCGCmode)
18534    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18535   [(parallel [(set (reg:CCGC 17)
18536                    (compare:CCGC (match_dup 0)
18537                                  (match_dup 1)))
18538               (clobber (match_dup 0))])]
18539   "")
18540
18541 (define_peephole2
18542   [(set (reg 17)
18543         (compare (match_operand:QI 0 "register_operand" "")
18544                  (match_operand:QI 1 "incdec_operand" "")))]
18545   "ix86_match_ccmode (insn, CCGCmode)
18546    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18547   [(parallel [(set (reg:CCGC 17)
18548                    (compare:CCGC (match_dup 0)
18549                                  (match_dup 1)))
18550               (clobber (match_dup 0))])]
18551   "")
18552
18553 ;; Convert compares with 128 to shorter add -128
18554 (define_peephole2
18555   [(set (reg 17)
18556         (compare (match_operand:SI 0 "register_operand" "")
18557                  (const_int 128)))]
18558   "ix86_match_ccmode (insn, CCGCmode)
18559    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18560   [(parallel [(set (reg:CCGC 17)
18561                    (compare:CCGC (match_dup 0)
18562                                  (const_int 128)))
18563               (clobber (match_dup 0))])]
18564   "")
18565
18566 (define_peephole2
18567   [(set (reg 17)
18568         (compare (match_operand:HI 0 "register_operand" "")
18569                  (const_int 128)))]
18570   "ix86_match_ccmode (insn, CCGCmode)
18571    && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
18572   [(parallel [(set (reg:CCGC 17)
18573                    (compare:CCGC (match_dup 0)
18574                                  (const_int 128)))
18575               (clobber (match_dup 0))])]
18576   "")
18577 \f
18578 (define_peephole2
18579   [(match_scratch:DI 0 "r")
18580    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18581               (clobber (reg:CC 17))
18582               (clobber (mem:BLK (scratch)))])]
18583   "optimize_size || !TARGET_SUB_ESP_4"
18584   [(clobber (match_dup 0))
18585    (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18586               (clobber (mem:BLK (scratch)))])])
18587
18588 (define_peephole2
18589   [(match_scratch:DI 0 "r")
18590    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18591               (clobber (reg:CC 17))
18592               (clobber (mem:BLK (scratch)))])]
18593   "optimize_size || !TARGET_SUB_ESP_8"
18594   [(clobber (match_dup 0))
18595    (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18596    (parallel [(set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18597               (clobber (mem:BLK (scratch)))])])
18598
18599 ;; Convert esp subtractions to push.
18600 (define_peephole2
18601   [(match_scratch:DI 0 "r")
18602    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -8)))
18603               (clobber (reg:CC 17))])]
18604   "optimize_size || !TARGET_SUB_ESP_4"
18605   [(clobber (match_dup 0))
18606    (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18607
18608 (define_peephole2
18609   [(match_scratch:DI 0 "r")
18610    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int -16)))
18611               (clobber (reg:CC 17))])]
18612   "optimize_size || !TARGET_SUB_ESP_8"
18613   [(clobber (match_dup 0))
18614    (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))
18615    (set (mem:DI (pre_dec:DI (reg:DI 7))) (match_dup 0))])
18616
18617 ;; Convert epilogue deallocator to pop.
18618 (define_peephole2
18619   [(match_scratch:DI 0 "r")
18620    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18621               (clobber (reg:CC 17))
18622               (clobber (mem:BLK (scratch)))])]
18623   "optimize_size || !TARGET_ADD_ESP_4"
18624   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18625               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18626               (clobber (mem:BLK (scratch)))])]
18627   "")
18628
18629 ;; Two pops case is tricky, since pop causes dependency on destination register.
18630 ;; We use two registers if available.
18631 (define_peephole2
18632   [(match_scratch:DI 0 "r")
18633    (match_scratch:DI 1 "r")
18634    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18635               (clobber (reg:CC 17))
18636               (clobber (mem:BLK (scratch)))])]
18637   "optimize_size || !TARGET_ADD_ESP_8"
18638   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18639               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18640               (clobber (mem:BLK (scratch)))])
18641    (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18642               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18643   "")
18644
18645 (define_peephole2
18646   [(match_scratch:DI 0 "r")
18647    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18648               (clobber (reg:CC 17))
18649               (clobber (mem:BLK (scratch)))])]
18650   "optimize_size"
18651   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18652               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18653               (clobber (mem:BLK (scratch)))])
18654    (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18655               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18656   "")
18657
18658 ;; Convert esp additions to pop.
18659 (define_peephole2
18660   [(match_scratch:DI 0 "r")
18661    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))
18662               (clobber (reg:CC 17))])]
18663   ""
18664   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18665               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18666   "")
18667
18668 ;; Two pops case is tricky, since pop causes dependency on destination register.
18669 ;; We use two registers if available.
18670 (define_peephole2
18671   [(match_scratch:DI 0 "r")
18672    (match_scratch:DI 1 "r")
18673    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18674               (clobber (reg:CC 17))])]
18675   ""
18676   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18677               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18678    (parallel [(set (match_dup 1) (mem:DI (reg:DI 7)))
18679               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18680   "")
18681
18682 (define_peephole2
18683   [(match_scratch:DI 0 "r")
18684    (parallel [(set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 16)))
18685               (clobber (reg:CC 17))])]
18686   "optimize_size"
18687   [(parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18688               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])
18689    (parallel [(set (match_dup 0) (mem:DI (reg:DI 7)))
18690               (set (reg:DI 7) (plus:DI (reg:DI 7) (const_int 8)))])]
18691   "")
18692 \f
18693 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18694 ;; imul $32bit_imm, reg, reg is direct decoded.
18695 (define_peephole2
18696   [(match_scratch:DI 3 "r")
18697    (parallel [(set (match_operand:DI 0 "register_operand" "")
18698                    (mult:DI (match_operand:DI 1 "memory_operand" "")
18699                             (match_operand:DI 2 "immediate_operand" "")))
18700               (clobber (reg:CC 17))])]
18701   "TARGET_K8 && !optimize_size
18702    && (GET_CODE (operands[2]) != CONST_INT
18703        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18704   [(set (match_dup 3) (match_dup 1))
18705    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18706               (clobber (reg:CC 17))])]
18707 "")
18708
18709 (define_peephole2
18710   [(match_scratch:SI 3 "r")
18711    (parallel [(set (match_operand:SI 0 "register_operand" "")
18712                    (mult:SI (match_operand:SI 1 "memory_operand" "")
18713                             (match_operand:SI 2 "immediate_operand" "")))
18714               (clobber (reg:CC 17))])]
18715   "TARGET_K8 && !optimize_size
18716    && (GET_CODE (operands[2]) != CONST_INT
18717        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18718   [(set (match_dup 3) (match_dup 1))
18719    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18720               (clobber (reg:CC 17))])]
18721 "")
18722
18723 (define_peephole2
18724   [(match_scratch:SI 3 "r")
18725    (parallel [(set (match_operand:DI 0 "register_operand" "")
18726                    (zero_extend:DI
18727                      (mult:SI (match_operand:SI 1 "memory_operand" "")
18728                               (match_operand:SI 2 "immediate_operand" ""))))
18729               (clobber (reg:CC 17))])]
18730   "TARGET_K8 && !optimize_size
18731    && (GET_CODE (operands[2]) != CONST_INT
18732        || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
18733   [(set (match_dup 3) (match_dup 1))
18734    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18735               (clobber (reg:CC 17))])]
18736 "")
18737
18738 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18739 ;; Convert it into imul reg, reg
18740 ;; It would be better to force assembler to encode instruction using long
18741 ;; immediate, but there is apparently no way to do so.
18742 (define_peephole2
18743   [(parallel [(set (match_operand:DI 0 "register_operand" "")
18744                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18745                             (match_operand:DI 2 "const_int_operand" "")))
18746               (clobber (reg:CC 17))])
18747    (match_scratch:DI 3 "r")]
18748   "TARGET_K8 && !optimize_size
18749    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18750   [(set (match_dup 3) (match_dup 2))
18751    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18752               (clobber (reg:CC 17))])]
18753 {
18754   if (!rtx_equal_p (operands[0], operands[1]))
18755     emit_move_insn (operands[0], operands[1]);
18756 })
18757
18758 (define_peephole2
18759   [(parallel [(set (match_operand:SI 0 "register_operand" "")
18760                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18761                             (match_operand:SI 2 "const_int_operand" "")))
18762               (clobber (reg:CC 17))])
18763    (match_scratch:SI 3 "r")]
18764   "TARGET_K8 && !optimize_size
18765    && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
18766   [(set (match_dup 3) (match_dup 2))
18767    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18768               (clobber (reg:CC 17))])]
18769 {
18770   if (!rtx_equal_p (operands[0], operands[1]))
18771     emit_move_insn (operands[0], operands[1]);
18772 })
18773
18774 (define_peephole2
18775   [(parallel [(set (match_operand:HI 0 "register_operand" "")
18776                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18777                             (match_operand:HI 2 "immediate_operand" "")))
18778               (clobber (reg:CC 17))])
18779    (match_scratch:HI 3 "r")]
18780   "TARGET_K8 && !optimize_size"
18781   [(set (match_dup 3) (match_dup 2))
18782    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18783               (clobber (reg:CC 17))])]
18784 {
18785   if (!rtx_equal_p (operands[0], operands[1]))
18786     emit_move_insn (operands[0], operands[1]);
18787 })
18788 \f
18789 ;; Call-value patterns last so that the wildcard operand does not
18790 ;; disrupt insn-recog's switch tables.
18791
18792 (define_insn "*call_value_pop_0"
18793   [(set (match_operand 0 "" "")
18794         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18795               (match_operand:SI 2 "" "")))
18796    (set (reg:SI 7) (plus:SI (reg:SI 7)
18797                             (match_operand:SI 3 "immediate_operand" "")))]
18798   "!TARGET_64BIT"
18799 {
18800   if (SIBLING_CALL_P (insn))
18801     return "jmp\t%P1";
18802   else
18803     return "call\t%P1";
18804 }
18805   [(set_attr "type" "callv")])
18806
18807 (define_insn "*call_value_pop_1"
18808   [(set (match_operand 0 "" "")
18809         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18810               (match_operand:SI 2 "" "")))
18811    (set (reg:SI 7) (plus:SI (reg:SI 7)
18812                             (match_operand:SI 3 "immediate_operand" "i")))]
18813   "!TARGET_64BIT"
18814 {
18815   if (constant_call_address_operand (operands[1], QImode))
18816     {
18817       if (SIBLING_CALL_P (insn))
18818         return "jmp\t%P1";
18819       else
18820         return "call\t%P1";
18821     }
18822   if (SIBLING_CALL_P (insn))
18823     return "jmp\t%A1";
18824   else
18825     return "call\t%A1";
18826 }
18827   [(set_attr "type" "callv")])
18828
18829 (define_insn "*call_value_0"
18830   [(set (match_operand 0 "" "")
18831         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18832               (match_operand:SI 2 "" "")))]
18833   "!TARGET_64BIT"
18834 {
18835   if (SIBLING_CALL_P (insn))
18836     return "jmp\t%P1";
18837   else
18838     return "call\t%P1";
18839 }
18840   [(set_attr "type" "callv")])
18841
18842 (define_insn "*call_value_0_rex64"
18843   [(set (match_operand 0 "" "")
18844         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18845               (match_operand:DI 2 "const_int_operand" "")))]
18846   "TARGET_64BIT"
18847 {
18848   if (SIBLING_CALL_P (insn))
18849     return "jmp\t%P1";
18850   else
18851     return "call\t%P1";
18852 }
18853   [(set_attr "type" "callv")])
18854
18855 (define_insn "*call_value_1"
18856   [(set (match_operand 0 "" "")
18857         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
18858               (match_operand:SI 2 "" "")))]
18859   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
18860 {
18861   if (constant_call_address_operand (operands[1], QImode))
18862     return "call\t%P1";
18863   return "call\t%*%1";
18864 }
18865   [(set_attr "type" "callv")])
18866
18867 (define_insn "*sibcall_value_1"
18868   [(set (match_operand 0 "" "")
18869         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
18870               (match_operand:SI 2 "" "")))]
18871   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
18872 {
18873   if (constant_call_address_operand (operands[1], QImode))
18874     return "jmp\t%P1";
18875   return "jmp\t%*%1";
18876 }
18877   [(set_attr "type" "callv")])
18878
18879 (define_insn "*call_value_1_rex64"
18880   [(set (match_operand 0 "" "")
18881         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18882               (match_operand:DI 2 "" "")))]
18883   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
18884 {
18885   if (constant_call_address_operand (operands[1], QImode))
18886     return "call\t%P1";
18887   return "call\t%A1";
18888 }
18889   [(set_attr "type" "callv")])
18890
18891 (define_insn "*sibcall_value_1_rex64"
18892   [(set (match_operand 0 "" "")
18893         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18894               (match_operand:DI 2 "" "")))]
18895   "SIBLING_CALL_P (insn) && TARGET_64BIT"
18896   "jmp\t%P1"
18897   [(set_attr "type" "callv")])
18898
18899 (define_insn "*sibcall_value_1_rex64_v"
18900   [(set (match_operand 0 "" "")
18901         (call (mem:QI (reg:DI 40))
18902               (match_operand:DI 1 "" "")))]
18903   "SIBLING_CALL_P (insn) && TARGET_64BIT"
18904   "jmp\t*%%r11"
18905   [(set_attr "type" "callv")])
18906 \f
18907 (define_insn "trap"
18908   [(trap_if (const_int 1) (const_int 5))]
18909   ""
18910   "int\t$5")
18911
18912 ;;; ix86 doesn't have conditional trap instructions, but we fake them
18913 ;;; for the sake of bounds checking.  By emitting bounds checks as
18914 ;;; conditional traps rather than as conditional jumps around
18915 ;;; unconditional traps we avoid introducing spurious basic-block
18916 ;;; boundaries and facilitate elimination of redundant checks.  In
18917 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
18918 ;;; interrupt 5.
18919 ;;; 
18920 ;;; FIXME: Static branch prediction rules for ix86 are such that
18921 ;;; forward conditional branches predict as untaken.  As implemented
18922 ;;; below, pseudo conditional traps violate that rule.  We should use
18923 ;;; .pushsection/.popsection to place all of the `int 5's in a special
18924 ;;; section loaded at the end of the text segment and branch forward
18925 ;;; there on bounds-failure, and then jump back immediately (in case
18926 ;;; the system chooses to ignore bounds violations, or to report
18927 ;;; violations and continue execution).
18928
18929 (define_expand "conditional_trap"
18930   [(trap_if (match_operator 0 "comparison_operator"
18931              [(match_dup 2) (const_int 0)])
18932             (match_operand 1 "const_int_operand" ""))]
18933   ""
18934 {
18935   emit_insn (gen_rtx_TRAP_IF (VOIDmode,
18936                               ix86_expand_compare (GET_CODE (operands[0]),
18937                                                    NULL, NULL),
18938                               operands[1]));
18939   DONE;
18940 })
18941
18942 (define_insn "*conditional_trap_1"
18943   [(trap_if (match_operator 0 "comparison_operator"
18944              [(reg 17) (const_int 0)])
18945             (match_operand 1 "const_int_operand" ""))]
18946   ""
18947 {
18948   operands[2] = gen_label_rtx ();
18949   output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
18950   (*targetm.asm_out.internal_label) (asm_out_file, "L",
18951                              CODE_LABEL_NUMBER (operands[2]));
18952   RET;
18953 })
18954
18955         ;; Pentium III SIMD instructions.
18956
18957 ;; Moves for SSE/MMX regs.
18958
18959 (define_insn "movv4sf_internal"
18960   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,m")
18961         (match_operand:V4SF 1 "vector_move_operand" "C,xm,x"))]
18962   "TARGET_SSE"
18963   "@
18964     xorps\t%0, %0
18965     movaps\t{%1, %0|%0, %1}
18966     movaps\t{%1, %0|%0, %1}"
18967   [(set_attr "type" "ssemov")
18968    (set_attr "mode" "V4SF")])
18969
18970 (define_split
18971   [(set (match_operand:V4SF 0 "register_operand" "")
18972         (match_operand:V4SF 1 "zero_extended_scalar_load_operand" ""))]
18973   "TARGET_SSE"
18974   [(set (match_dup 0)
18975         (vec_merge:V4SF
18976          (vec_duplicate:V4SF (match_dup 1))
18977          (match_dup 2)
18978          (const_int 1)))]
18979 {
18980   operands[1] = simplify_gen_subreg (SFmode, operands[1], V4SFmode, 0);
18981   operands[2] = CONST0_RTX (V4SFmode);
18982 })
18983
18984 (define_insn "movv4si_internal"
18985   [(set (match_operand:V4SI 0 "nonimmediate_operand" "=x,x,m")
18986         (match_operand:V4SI 1 "vector_move_operand" "C,xm,x"))]
18987   "TARGET_SSE"
18988 {
18989   switch (which_alternative)
18990     {
18991     case 0:
18992       if (get_attr_mode (insn) == MODE_V4SF)
18993         return "xorps\t%0, %0";
18994       else
18995         return "pxor\t%0, %0";
18996     case 1:
18997     case 2:
18998       if (get_attr_mode (insn) == MODE_V4SF)
18999         return "movaps\t{%1, %0|%0, %1}";
19000       else
19001         return "movdqa\t{%1, %0|%0, %1}";
19002     default:
19003       abort ();
19004     }
19005 }
19006   [(set_attr "type" "ssemov")
19007    (set (attr "mode")
19008         (cond [(eq_attr "alternative" "0,1")
19009                  (if_then_else
19010                    (ne (symbol_ref "optimize_size")
19011                        (const_int 0))
19012                    (const_string "V4SF")
19013                    (const_string "TI"))
19014                (eq_attr "alternative" "2")
19015                  (if_then_else
19016                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19017                             (const_int 0))
19018                         (ne (symbol_ref "optimize_size")
19019                             (const_int 0)))
19020                    (const_string "V4SF")
19021                    (const_string "TI"))]
19022                (const_string "TI")))])
19023
19024 (define_insn "movv2di_internal"
19025   [(set (match_operand:V2DI 0 "nonimmediate_operand" "=x,x,m")
19026         (match_operand:V2DI 1 "vector_move_operand" "C,xm,x"))]
19027   "TARGET_SSE2"
19028 {
19029   switch (which_alternative)
19030     {
19031     case 0:
19032       if (get_attr_mode (insn) == MODE_V4SF)
19033         return "xorps\t%0, %0";
19034       else
19035         return "pxor\t%0, %0";
19036     case 1:
19037     case 2:
19038       if (get_attr_mode (insn) == MODE_V4SF)
19039         return "movaps\t{%1, %0|%0, %1}";
19040       else
19041         return "movdqa\t{%1, %0|%0, %1}";
19042     default:
19043       abort ();
19044     }
19045 }
19046   [(set_attr "type" "ssemov")
19047    (set (attr "mode")
19048         (cond [(eq_attr "alternative" "0,1")
19049                  (if_then_else
19050                    (ne (symbol_ref "optimize_size")
19051                        (const_int 0))
19052                    (const_string "V4SF")
19053                    (const_string "TI"))
19054                (eq_attr "alternative" "2")
19055                  (if_then_else
19056                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19057                             (const_int 0))
19058                         (ne (symbol_ref "optimize_size")
19059                             (const_int 0)))
19060                    (const_string "V4SF")
19061                    (const_string "TI"))]
19062                (const_string "TI")))])
19063
19064 (define_split
19065   [(set (match_operand:V2DF 0 "register_operand" "")
19066         (match_operand:V2DF 1 "zero_extended_scalar_load_operand" ""))]
19067   "TARGET_SSE2"
19068   [(set (match_dup 0)
19069         (vec_merge:V2DF
19070          (vec_duplicate:V2DF (match_dup 1))
19071          (match_dup 2)
19072          (const_int 1)))]
19073 {
19074   operands[1] = simplify_gen_subreg (DFmode, operands[1], V2DFmode, 0);
19075   operands[2] = CONST0_RTX (V2DFmode);
19076 })
19077
19078 (define_insn "movv8qi_internal"
19079   [(set (match_operand:V8QI 0 "nonimmediate_operand" "=y,y,m")
19080         (match_operand:V8QI 1 "vector_move_operand" "C,ym,y"))]
19081   "TARGET_MMX
19082    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19083   "@
19084     pxor\t%0, %0
19085     movq\t{%1, %0|%0, %1}
19086     movq\t{%1, %0|%0, %1}"
19087   [(set_attr "type" "mmxmov")
19088    (set_attr "mode" "DI")])
19089
19090 (define_insn "movv4hi_internal"
19091   [(set (match_operand:V4HI 0 "nonimmediate_operand" "=y,y,m")
19092         (match_operand:V4HI 1 "vector_move_operand" "C,ym,y"))]
19093   "TARGET_MMX
19094    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19095   "@
19096     pxor\t%0, %0
19097     movq\t{%1, %0|%0, %1}
19098     movq\t{%1, %0|%0, %1}"
19099   [(set_attr "type" "mmxmov")
19100    (set_attr "mode" "DI")])
19101
19102 (define_insn "movv2si_internal"
19103   [(set (match_operand:V2SI 0 "nonimmediate_operand" "=y,y,m")
19104         (match_operand:V2SI 1 "vector_move_operand" "C,ym,y"))]
19105   "TARGET_MMX
19106    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19107   "@
19108     pxor\t%0, %0
19109     movq\t{%1, %0|%0, %1}
19110     movq\t{%1, %0|%0, %1}"
19111   [(set_attr "type" "mmxcvt")
19112    (set_attr "mode" "DI")])
19113
19114 (define_insn "movv2sf_internal"
19115   [(set (match_operand:V2SF 0 "nonimmediate_operand" "=y,y,m")
19116         (match_operand:V2SF 1 "vector_move_operand" "C,ym,y"))]
19117   "TARGET_3DNOW
19118    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19119   "@
19120     pxor\t%0, %0
19121     movq\t{%1, %0|%0, %1}
19122     movq\t{%1, %0|%0, %1}"
19123   [(set_attr "type" "mmxcvt")
19124    (set_attr "mode" "DI")])
19125
19126 (define_expand "movti"
19127   [(set (match_operand:TI 0 "nonimmediate_operand" "")
19128         (match_operand:TI 1 "nonimmediate_operand" ""))]
19129   "TARGET_SSE || TARGET_64BIT"
19130 {
19131   if (TARGET_64BIT)
19132     ix86_expand_move (TImode, operands);
19133   else
19134     ix86_expand_vector_move (TImode, operands);
19135   DONE;
19136 })
19137
19138 (define_insn "movv2df_internal"
19139   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,m")
19140         (match_operand:V2DF 1 "vector_move_operand" "C,xm,x"))]
19141   "TARGET_SSE2
19142    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19143 {
19144   switch (which_alternative)
19145     {
19146     case 0:
19147       if (get_attr_mode (insn) == MODE_V4SF)
19148         return "xorps\t%0, %0";
19149       else
19150         return "xorpd\t%0, %0";
19151     case 1:
19152     case 2:
19153       if (get_attr_mode (insn) == MODE_V4SF)
19154         return "movaps\t{%1, %0|%0, %1}";
19155       else
19156         return "movapd\t{%1, %0|%0, %1}";
19157     default:
19158       abort ();
19159     }
19160 }
19161   [(set_attr "type" "ssemov")
19162    (set (attr "mode")
19163         (cond [(eq_attr "alternative" "0,1")
19164                  (if_then_else
19165                    (ne (symbol_ref "optimize_size")
19166                        (const_int 0))
19167                    (const_string "V4SF")
19168                    (const_string "V2DF"))
19169                (eq_attr "alternative" "2")
19170                  (if_then_else
19171                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19172                             (const_int 0))
19173                         (ne (symbol_ref "optimize_size")
19174                             (const_int 0)))
19175                    (const_string "V4SF")
19176                    (const_string "V2DF"))]
19177                (const_string "V2DF")))])
19178
19179 (define_insn "movv8hi_internal"
19180   [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,x,m")
19181         (match_operand:V8HI 1 "vector_move_operand" "C,xm,x"))]
19182   "TARGET_SSE2
19183    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19184 {
19185   switch (which_alternative)
19186     {
19187     case 0:
19188       if (get_attr_mode (insn) == MODE_V4SF)
19189         return "xorps\t%0, %0";
19190       else
19191         return "pxor\t%0, %0";
19192     case 1:
19193     case 2:
19194       if (get_attr_mode (insn) == MODE_V4SF)
19195         return "movaps\t{%1, %0|%0, %1}";
19196       else
19197         return "movdqa\t{%1, %0|%0, %1}";
19198     default:
19199       abort ();
19200     }
19201 }
19202   [(set_attr "type" "ssemov")
19203    (set (attr "mode")
19204         (cond [(eq_attr "alternative" "0,1")
19205                  (if_then_else
19206                    (ne (symbol_ref "optimize_size")
19207                        (const_int 0))
19208                    (const_string "V4SF")
19209                    (const_string "TI"))
19210                (eq_attr "alternative" "2")
19211                  (if_then_else
19212                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19213                             (const_int 0))
19214                         (ne (symbol_ref "optimize_size")
19215                             (const_int 0)))
19216                    (const_string "V4SF")
19217                    (const_string "TI"))]
19218                (const_string "TI")))])
19219
19220 (define_insn "movv16qi_internal"
19221   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,x,m")
19222         (match_operand:V16QI 1 "nonimmediate_operand" "C,xm,x"))]
19223   "TARGET_SSE2
19224    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19225 {
19226   switch (which_alternative)
19227     {
19228     case 0:
19229       if (get_attr_mode (insn) == MODE_V4SF)
19230         return "xorps\t%0, %0";
19231       else
19232         return "pxor\t%0, %0";
19233     case 1:
19234     case 2:
19235       if (get_attr_mode (insn) == MODE_V4SF)
19236         return "movaps\t{%1, %0|%0, %1}";
19237       else
19238         return "movdqa\t{%1, %0|%0, %1}";
19239     default:
19240       abort ();
19241     }
19242 }
19243   [(set_attr "type" "ssemov")
19244    (set (attr "mode")
19245         (cond [(eq_attr "alternative" "0,1")
19246                  (if_then_else
19247                    (ne (symbol_ref "optimize_size")
19248                        (const_int 0))
19249                    (const_string "V4SF")
19250                    (const_string "TI"))
19251                (eq_attr "alternative" "2")
19252                  (if_then_else
19253                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19254                             (const_int 0))
19255                         (ne (symbol_ref "optimize_size")
19256                             (const_int 0)))
19257                    (const_string "V4SF")
19258                    (const_string "TI"))]
19259                (const_string "TI")))])
19260
19261 (define_expand "movv2df"
19262   [(set (match_operand:V2DF 0 "nonimmediate_operand" "")
19263         (match_operand:V2DF 1 "nonimmediate_operand" ""))]
19264   "TARGET_SSE2"
19265 {
19266   ix86_expand_vector_move (V2DFmode, operands);
19267   DONE;
19268 })
19269
19270 (define_expand "movv8hi"
19271   [(set (match_operand:V8HI 0 "nonimmediate_operand" "")
19272         (match_operand:V8HI 1 "nonimmediate_operand" ""))]
19273   "TARGET_SSE2"
19274 {
19275   ix86_expand_vector_move (V8HImode, operands);
19276   DONE;
19277 })
19278
19279 (define_expand "movv16qi"
19280   [(set (match_operand:V16QI 0 "nonimmediate_operand" "")
19281         (match_operand:V16QI 1 "nonimmediate_operand" ""))]
19282   "TARGET_SSE2"
19283 {
19284   ix86_expand_vector_move (V16QImode, operands);
19285   DONE;
19286 })
19287
19288 (define_expand "movv4sf"
19289   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19290         (match_operand:V4SF 1 "nonimmediate_operand" ""))]
19291   "TARGET_SSE"
19292 {
19293   ix86_expand_vector_move (V4SFmode, operands);
19294   DONE;
19295 })
19296
19297 (define_expand "movv4si"
19298   [(set (match_operand:V4SI 0 "nonimmediate_operand" "")
19299         (match_operand:V4SI 1 "nonimmediate_operand" ""))]
19300   "TARGET_SSE"
19301 {
19302   ix86_expand_vector_move (V4SImode, operands);
19303   DONE;
19304 })
19305
19306 (define_expand "movv2di"
19307   [(set (match_operand:V2DI 0 "nonimmediate_operand" "")
19308         (match_operand:V2DI 1 "nonimmediate_operand" ""))]
19309   "TARGET_SSE"
19310 {
19311   ix86_expand_vector_move (V2DImode, operands);
19312   DONE;
19313 })
19314
19315 (define_expand "movv2si"
19316   [(set (match_operand:V2SI 0 "nonimmediate_operand" "")
19317         (match_operand:V2SI 1 "nonimmediate_operand" ""))]
19318   "TARGET_MMX"
19319 {
19320   ix86_expand_vector_move (V2SImode, operands);
19321   DONE;
19322 })
19323
19324 (define_expand "movv4hi"
19325   [(set (match_operand:V4HI 0 "nonimmediate_operand" "")
19326         (match_operand:V4HI 1 "nonimmediate_operand" ""))]
19327   "TARGET_MMX"
19328 {
19329   ix86_expand_vector_move (V4HImode, operands);
19330   DONE;
19331 })
19332
19333 (define_expand "movv8qi"
19334   [(set (match_operand:V8QI 0 "nonimmediate_operand" "")
19335         (match_operand:V8QI 1 "nonimmediate_operand" ""))]
19336   "TARGET_MMX"
19337 {
19338   ix86_expand_vector_move (V8QImode, operands);
19339   DONE;
19340 })
19341
19342 (define_expand "movv2sf"
19343   [(set (match_operand:V2SF 0 "nonimmediate_operand" "")
19344         (match_operand:V2SF 1 "nonimmediate_operand" ""))]
19345    "TARGET_3DNOW"
19346 {
19347   ix86_expand_vector_move (V2SFmode, operands);
19348   DONE;
19349 })
19350
19351 (define_insn "*pushti"
19352   [(set (match_operand:TI 0 "push_operand" "=<")
19353         (match_operand:TI 1 "register_operand" "x"))]
19354   "TARGET_SSE"
19355   "#")
19356
19357 (define_insn "*pushv2df"
19358   [(set (match_operand:V2DF 0 "push_operand" "=<")
19359         (match_operand:V2DF 1 "register_operand" "x"))]
19360   "TARGET_SSE"
19361   "#")
19362
19363 (define_insn "*pushv2di"
19364   [(set (match_operand:V2DI 0 "push_operand" "=<")
19365         (match_operand:V2DI 1 "register_operand" "x"))]
19366   "TARGET_SSE2"
19367   "#")
19368
19369 (define_insn "*pushv8hi"
19370   [(set (match_operand:V8HI 0 "push_operand" "=<")
19371         (match_operand:V8HI 1 "register_operand" "x"))]
19372   "TARGET_SSE2"
19373   "#")
19374
19375 (define_insn "*pushv16qi"
19376   [(set (match_operand:V16QI 0 "push_operand" "=<")
19377         (match_operand:V16QI 1 "register_operand" "x"))]
19378   "TARGET_SSE2"
19379   "#")
19380
19381 (define_insn "*pushv4sf"
19382   [(set (match_operand:V4SF 0 "push_operand" "=<")
19383         (match_operand:V4SF 1 "register_operand" "x"))]
19384   "TARGET_SSE"
19385   "#")
19386
19387 (define_insn "*pushv4si"
19388   [(set (match_operand:V4SI 0 "push_operand" "=<")
19389         (match_operand:V4SI 1 "register_operand" "x"))]
19390   "TARGET_SSE2"
19391   "#")
19392
19393 (define_insn "*pushv2si"
19394   [(set (match_operand:V2SI 0 "push_operand" "=<")
19395         (match_operand:V2SI 1 "register_operand" "y"))]
19396   "TARGET_MMX"
19397   "#")
19398
19399 (define_insn "*pushv4hi"
19400   [(set (match_operand:V4HI 0 "push_operand" "=<")
19401         (match_operand:V4HI 1 "register_operand" "y"))]
19402   "TARGET_MMX"
19403   "#")
19404
19405 (define_insn "*pushv8qi"
19406   [(set (match_operand:V8QI 0 "push_operand" "=<")
19407         (match_operand:V8QI 1 "register_operand" "y"))]
19408   "TARGET_MMX"
19409   "#")
19410
19411 (define_insn "*pushv2sf"
19412   [(set (match_operand:V2SF 0 "push_operand" "=<")
19413         (match_operand:V2SF 1 "register_operand" "y"))]
19414   "TARGET_3DNOW"
19415   "#")
19416
19417 (define_split
19418   [(set (match_operand 0 "push_operand" "")
19419         (match_operand 1 "register_operand" ""))]
19420   "!TARGET_64BIT && reload_completed
19421    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19422   [(set (reg:SI 7) (plus:SI (reg:SI 7) (match_dup 3)))
19423    (set (match_dup 2) (match_dup 1))]
19424   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19425                                  stack_pointer_rtx);
19426    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19427
19428 (define_split
19429   [(set (match_operand 0 "push_operand" "")
19430         (match_operand 1 "register_operand" ""))]
19431   "TARGET_64BIT && reload_completed
19432    && (SSE_REG_P (operands[1]) || MMX_REG_P (operands[1]))"
19433   [(set (reg:DI 7) (plus:DI (reg:DI 7) (match_dup 3)))
19434    (set (match_dup 2) (match_dup 1))]
19435   "operands[2] = change_address (operands[0], GET_MODE (operands[0]),
19436                                  stack_pointer_rtx);
19437    operands[3] = GEN_INT (-GET_MODE_SIZE (GET_MODE (operands[0])));")
19438
19439
19440 (define_insn "movti_internal"
19441   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
19442         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
19443   "TARGET_SSE && !TARGET_64BIT
19444    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19445 {
19446   switch (which_alternative)
19447     {
19448     case 0:
19449       if (get_attr_mode (insn) == MODE_V4SF)
19450         return "xorps\t%0, %0";
19451       else
19452         return "pxor\t%0, %0";
19453     case 1:
19454     case 2:
19455       if (get_attr_mode (insn) == MODE_V4SF)
19456         return "movaps\t{%1, %0|%0, %1}";
19457       else
19458         return "movdqa\t{%1, %0|%0, %1}";
19459     default:
19460       abort ();
19461     }
19462 }
19463   [(set_attr "type" "ssemov,ssemov,ssemov")
19464    (set (attr "mode")
19465         (cond [(eq_attr "alternative" "0,1")
19466                  (if_then_else
19467                    (ne (symbol_ref "optimize_size")
19468                        (const_int 0))
19469                    (const_string "V4SF")
19470                    (const_string "TI"))
19471                (eq_attr "alternative" "2")
19472                  (if_then_else
19473                    (ne (symbol_ref "optimize_size")
19474                        (const_int 0))
19475                    (const_string "V4SF")
19476                    (const_string "TI"))]
19477                (const_string "TI")))])
19478
19479 (define_insn "*movti_rex64"
19480   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
19481         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
19482   "TARGET_64BIT
19483    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19484 {
19485   switch (which_alternative)
19486     {
19487     case 0:
19488     case 1:
19489       return "#";
19490     case 2:
19491       if (get_attr_mode (insn) == MODE_V4SF)
19492         return "xorps\t%0, %0";
19493       else
19494         return "pxor\t%0, %0";
19495     case 3:
19496     case 4:
19497       if (get_attr_mode (insn) == MODE_V4SF)
19498         return "movaps\t{%1, %0|%0, %1}";
19499       else
19500         return "movdqa\t{%1, %0|%0, %1}";
19501     default:
19502       abort ();
19503     }
19504 }
19505   [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
19506    (set (attr "mode")
19507         (cond [(eq_attr "alternative" "2,3")
19508                  (if_then_else
19509                    (ne (symbol_ref "optimize_size")
19510                        (const_int 0))
19511                    (const_string "V4SF")
19512                    (const_string "TI"))
19513                (eq_attr "alternative" "4")
19514                  (if_then_else
19515                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
19516                             (const_int 0))
19517                         (ne (symbol_ref "optimize_size")
19518                             (const_int 0)))
19519                    (const_string "V4SF")
19520                    (const_string "TI"))]
19521                (const_string "DI")))])
19522
19523 (define_split
19524   [(set (match_operand:TI 0 "nonimmediate_operand" "")
19525         (match_operand:TI 1 "general_operand" ""))]
19526   "reload_completed && !SSE_REG_P (operands[0])
19527    && !SSE_REG_P (operands[1])"
19528   [(const_int 0)]
19529   "ix86_split_long_move (operands); DONE;")
19530
19531 ;; These two patterns are useful for specifying exactly whether to use
19532 ;; movaps or movups
19533 (define_expand "sse_movaps"
19534   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19535         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19536                      UNSPEC_MOVA))]
19537   "TARGET_SSE"
19538 {
19539   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19540     {
19541       rtx tmp = gen_reg_rtx (V4SFmode);
19542       emit_insn (gen_sse_movaps (tmp, operands[1]));
19543       emit_move_insn (operands[0], tmp);
19544       DONE;
19545     }
19546 })
19547
19548 (define_insn "*sse_movaps_1"
19549   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19550         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19551                      UNSPEC_MOVA))]
19552   "TARGET_SSE
19553    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19554   "movaps\t{%1, %0|%0, %1}"
19555   [(set_attr "type" "ssemov,ssemov")
19556    (set_attr "mode" "V4SF")])
19557
19558 (define_expand "sse_movups"
19559   [(set (match_operand:V4SF 0 "nonimmediate_operand" "")
19560         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "")]
19561                      UNSPEC_MOVU))]
19562   "TARGET_SSE"
19563 {
19564   if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
19565     {
19566       rtx tmp = gen_reg_rtx (V4SFmode);
19567       emit_insn (gen_sse_movups (tmp, operands[1]));
19568       emit_move_insn (operands[0], tmp);
19569       DONE;
19570     }
19571 })
19572
19573 (define_insn "*sse_movups_1"
19574   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19575         (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm,x")]
19576                      UNSPEC_MOVU))]
19577   "TARGET_SSE
19578    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
19579   "movups\t{%1, %0|%0, %1}"
19580   [(set_attr "type" "ssecvt,ssecvt")
19581    (set_attr "mode" "V4SF")])
19582
19583 ;; SSE Strange Moves.
19584
19585 (define_insn "sse_movmskps"
19586   [(set (match_operand:SI 0 "register_operand" "=r")
19587         (unspec:SI [(match_operand:V4SF 1 "register_operand" "x")]
19588                    UNSPEC_MOVMSK))]
19589   "TARGET_SSE"
19590   "movmskps\t{%1, %0|%0, %1}"
19591   [(set_attr "type" "ssecvt")
19592    (set_attr "mode" "V4SF")])
19593
19594 (define_insn "mmx_pmovmskb"
19595   [(set (match_operand:SI 0 "register_operand" "=r")
19596         (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")]
19597                    UNSPEC_MOVMSK))]
19598   "TARGET_SSE || TARGET_3DNOW_A"
19599   "pmovmskb\t{%1, %0|%0, %1}"
19600   [(set_attr "type" "ssecvt")
19601    (set_attr "mode" "V4SF")])
19602
19603
19604 (define_insn "mmx_maskmovq"
19605   [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D"))
19606         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19607                       (match_operand:V8QI 2 "register_operand" "y")]
19608                      UNSPEC_MASKMOV))]
19609   "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT"
19610   ;; @@@ check ordering of operands in intel/nonintel syntax
19611   "maskmovq\t{%2, %1|%1, %2}"
19612   [(set_attr "type" "mmxcvt")
19613    (set_attr "mode" "DI")])
19614
19615 (define_insn "mmx_maskmovq_rex"
19616   [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D"))
19617         (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y")
19618                       (match_operand:V8QI 2 "register_operand" "y")]
19619                      UNSPEC_MASKMOV))]
19620   "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT"
19621   ;; @@@ check ordering of operands in intel/nonintel syntax
19622   "maskmovq\t{%2, %1|%1, %2}"
19623   [(set_attr "type" "mmxcvt")
19624    (set_attr "mode" "DI")])
19625
19626 (define_insn "sse_movntv4sf"
19627   [(set (match_operand:V4SF 0 "memory_operand" "=m")
19628         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "x")]
19629                      UNSPEC_MOVNT))]
19630   "TARGET_SSE"
19631   "movntps\t{%1, %0|%0, %1}"
19632   [(set_attr "type" "ssemov")
19633    (set_attr "mode" "V4SF")])
19634
19635 (define_insn "sse_movntdi"
19636   [(set (match_operand:DI 0 "memory_operand" "=m")
19637         (unspec:DI [(match_operand:DI 1 "register_operand" "y")]
19638                    UNSPEC_MOVNT))]
19639   "TARGET_SSE || TARGET_3DNOW_A"
19640   "movntq\t{%1, %0|%0, %1}"
19641   [(set_attr "type" "mmxmov")
19642    (set_attr "mode" "DI")])
19643
19644 (define_insn "sse_movhlps"
19645   [(set (match_operand:V4SF 0 "register_operand" "=x")
19646         (vec_merge:V4SF
19647          (match_operand:V4SF 1 "register_operand" "0")
19648          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19649                           (parallel [(const_int 2)
19650                                      (const_int 3)
19651                                      (const_int 0)
19652                                      (const_int 1)]))
19653          (const_int 3)))]
19654   "TARGET_SSE"
19655   "movhlps\t{%2, %0|%0, %2}"
19656   [(set_attr "type" "ssecvt")
19657    (set_attr "mode" "V4SF")])
19658
19659 (define_insn "sse_movlhps"
19660   [(set (match_operand:V4SF 0 "register_operand" "=x")
19661         (vec_merge:V4SF
19662          (match_operand:V4SF 1 "register_operand" "0")
19663          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
19664                           (parallel [(const_int 2)
19665                                      (const_int 3)
19666                                      (const_int 0)
19667                                      (const_int 1)]))
19668          (const_int 12)))]
19669   "TARGET_SSE"
19670   "movlhps\t{%2, %0|%0, %2}"
19671   [(set_attr "type" "ssecvt")
19672    (set_attr "mode" "V4SF")])
19673
19674 (define_insn "sse_movhps"
19675   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19676         (vec_merge:V4SF
19677          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19678          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19679          (const_int 12)))]
19680   "TARGET_SSE
19681    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19682   "movhps\t{%2, %0|%0, %2}"
19683   [(set_attr "type" "ssecvt")
19684    (set_attr "mode" "V4SF")])
19685
19686 (define_insn "sse_movlps"
19687   [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,m")
19688         (vec_merge:V4SF
19689          (match_operand:V4SF 1 "nonimmediate_operand" "0,0")
19690          (match_operand:V4SF 2 "nonimmediate_operand" "m,x")
19691          (const_int 3)))]
19692   "TARGET_SSE
19693    && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
19694   "movlps\t{%2, %0|%0, %2}"
19695   [(set_attr "type" "ssecvt")
19696    (set_attr "mode" "V4SF")])
19697
19698 (define_expand "sse_loadss"
19699   [(match_operand:V4SF 0 "register_operand" "")
19700    (match_operand:SF 1 "memory_operand" "")]
19701   "TARGET_SSE"
19702 {
19703   emit_insn (gen_sse_loadss_1 (operands[0], operands[1],
19704                                CONST0_RTX (V4SFmode)));
19705   DONE;
19706 })
19707
19708 (define_insn "sse_loadss_1"
19709   [(set (match_operand:V4SF 0 "register_operand" "=x")
19710         (vec_merge:V4SF
19711          (vec_duplicate:V4SF (match_operand:SF 1 "memory_operand" "m"))
19712          (match_operand:V4SF 2 "const0_operand" "X")
19713          (const_int 1)))]
19714   "TARGET_SSE"
19715   "movss\t{%1, %0|%0, %1}"
19716   [(set_attr "type" "ssemov")
19717    (set_attr "mode" "SF")])
19718
19719 (define_insn "sse_movss"
19720   [(set (match_operand:V4SF 0 "register_operand" "=x")
19721         (vec_merge:V4SF
19722          (match_operand:V4SF 1 "register_operand" "0")
19723          (match_operand:V4SF 2 "register_operand" "x")
19724          (const_int 1)))]
19725   "TARGET_SSE"
19726   "movss\t{%2, %0|%0, %2}"
19727   [(set_attr "type" "ssemov")
19728    (set_attr "mode" "SF")])
19729
19730 (define_insn "sse_storess"
19731   [(set (match_operand:SF 0 "memory_operand" "=m")
19732         (vec_select:SF
19733          (match_operand:V4SF 1 "register_operand" "x")
19734          (parallel [(const_int 0)])))]
19735   "TARGET_SSE"
19736   "movss\t{%1, %0|%0, %1}"
19737   [(set_attr "type" "ssemov")
19738    (set_attr "mode" "SF")])
19739
19740 (define_insn "sse_shufps"
19741   [(set (match_operand:V4SF 0 "register_operand" "=x")
19742         (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
19743                       (match_operand:V4SF 2 "nonimmediate_operand" "xm")
19744                       (match_operand:SI 3 "immediate_operand" "i")]
19745                      UNSPEC_SHUFFLE))]
19746   "TARGET_SSE"
19747   ;; @@@ check operand order for intel/nonintel syntax
19748   "shufps\t{%3, %2, %0|%0, %2, %3}"
19749   [(set_attr "type" "ssecvt")
19750    (set_attr "mode" "V4SF")])
19751
19752
19753 ;; SSE arithmetic
19754
19755 (define_insn "addv4sf3"
19756   [(set (match_operand:V4SF 0 "register_operand" "=x")
19757         (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19758                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19759   "TARGET_SSE"
19760   "addps\t{%2, %0|%0, %2}"
19761   [(set_attr "type" "sseadd")
19762    (set_attr "mode" "V4SF")])
19763
19764 (define_insn "vmaddv4sf3"
19765   [(set (match_operand:V4SF 0 "register_operand" "=x")
19766         (vec_merge:V4SF
19767          (plus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19768                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19769          (match_dup 1)
19770          (const_int 1)))]
19771   "TARGET_SSE"
19772   "addss\t{%2, %0|%0, %2}"
19773   [(set_attr "type" "sseadd")
19774    (set_attr "mode" "SF")])
19775
19776 (define_insn "subv4sf3"
19777   [(set (match_operand:V4SF 0 "register_operand" "=x")
19778         (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19779                     (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19780   "TARGET_SSE"
19781   "subps\t{%2, %0|%0, %2}"
19782   [(set_attr "type" "sseadd")
19783    (set_attr "mode" "V4SF")])
19784
19785 (define_insn "vmsubv4sf3"
19786   [(set (match_operand:V4SF 0 "register_operand" "=x")
19787         (vec_merge:V4SF
19788          (minus:V4SF (match_operand:V4SF 1 "register_operand" "0")
19789                      (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19790          (match_dup 1)
19791          (const_int 1)))]
19792   "TARGET_SSE"
19793   "subss\t{%2, %0|%0, %2}"
19794   [(set_attr "type" "sseadd")
19795    (set_attr "mode" "SF")])
19796
19797 (define_insn "mulv4sf3"
19798   [(set (match_operand:V4SF 0 "register_operand" "=x")
19799         (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19800                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19801   "TARGET_SSE"
19802   "mulps\t{%2, %0|%0, %2}"
19803   [(set_attr "type" "ssemul")
19804    (set_attr "mode" "V4SF")])
19805
19806 (define_insn "vmmulv4sf3"
19807   [(set (match_operand:V4SF 0 "register_operand" "=x")
19808         (vec_merge:V4SF
19809          (mult:V4SF (match_operand:V4SF 1 "register_operand" "0")
19810                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19811          (match_dup 1)
19812          (const_int 1)))]
19813   "TARGET_SSE"
19814   "mulss\t{%2, %0|%0, %2}"
19815   [(set_attr "type" "ssemul")
19816    (set_attr "mode" "SF")])
19817
19818 (define_insn "divv4sf3"
19819   [(set (match_operand:V4SF 0 "register_operand" "=x")
19820         (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19821                   (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
19822   "TARGET_SSE"
19823   "divps\t{%2, %0|%0, %2}"
19824   [(set_attr "type" "ssediv")
19825    (set_attr "mode" "V4SF")])
19826
19827 (define_insn "vmdivv4sf3"
19828   [(set (match_operand:V4SF 0 "register_operand" "=x")
19829         (vec_merge:V4SF
19830          (div:V4SF (match_operand:V4SF 1 "register_operand" "0")
19831                    (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
19832          (match_dup 1)
19833          (const_int 1)))]
19834   "TARGET_SSE"
19835   "divss\t{%2, %0|%0, %2}"
19836   [(set_attr "type" "ssediv")
19837    (set_attr "mode" "SF")])
19838
19839
19840 ;; SSE square root/reciprocal
19841
19842 (define_insn "rcpv4sf2"
19843   [(set (match_operand:V4SF 0 "register_operand" "=x")
19844         (unspec:V4SF
19845          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RCP))]
19846   "TARGET_SSE"
19847   "rcpps\t{%1, %0|%0, %1}"
19848   [(set_attr "type" "sse")
19849    (set_attr "mode" "V4SF")])
19850
19851 (define_insn "vmrcpv4sf2"
19852   [(set (match_operand:V4SF 0 "register_operand" "=x")
19853         (vec_merge:V4SF
19854          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19855                       UNSPEC_RCP)
19856          (match_operand:V4SF 2 "register_operand" "0")
19857          (const_int 1)))]
19858   "TARGET_SSE"
19859   "rcpss\t{%1, %0|%0, %1}"
19860   [(set_attr "type" "sse")
19861    (set_attr "mode" "SF")])
19862
19863 (define_insn "rsqrtv4sf2"
19864   [(set (match_operand:V4SF 0 "register_operand" "=x")
19865         (unspec:V4SF
19866          [(match_operand:V4SF 1 "nonimmediate_operand" "xm")] UNSPEC_RSQRT))]
19867   "TARGET_SSE"
19868   "rsqrtps\t{%1, %0|%0, %1}"
19869   [(set_attr "type" "sse")
19870    (set_attr "mode" "V4SF")])
19871
19872 (define_insn "vmrsqrtv4sf2"
19873   [(set (match_operand:V4SF 0 "register_operand" "=x")
19874         (vec_merge:V4SF
19875          (unspec:V4SF [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
19876                       UNSPEC_RSQRT)
19877          (match_operand:V4SF 2 "register_operand" "0")
19878          (const_int 1)))]
19879   "TARGET_SSE"
19880   "rsqrtss\t{%1, %0|%0, %1}"
19881   [(set_attr "type" "sse")
19882    (set_attr "mode" "SF")])
19883
19884 (define_insn "sqrtv4sf2"
19885   [(set (match_operand:V4SF 0 "register_operand" "=x")
19886         (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
19887   "TARGET_SSE"
19888   "sqrtps\t{%1, %0|%0, %1}"
19889   [(set_attr "type" "sse")
19890    (set_attr "mode" "V4SF")])
19891
19892 (define_insn "vmsqrtv4sf2"
19893   [(set (match_operand:V4SF 0 "register_operand" "=x")
19894         (vec_merge:V4SF
19895          (sqrt:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
19896          (match_operand:V4SF 2 "register_operand" "0")
19897          (const_int 1)))]
19898   "TARGET_SSE"
19899   "sqrtss\t{%1, %0|%0, %1}"
19900   [(set_attr "type" "sse")
19901    (set_attr "mode" "SF")])
19902
19903 ;; SSE logical operations.
19904
19905 ;; SSE defines logical operations on floating point values.  This brings
19906 ;; interesting challenge to RTL representation where logicals are only valid
19907 ;; on integral types.  We deal with this by representing the floating point
19908 ;; logical as logical on arguments casted to TImode as this is what hardware
19909 ;; really does.  Unfortunately hardware requires the type information to be
19910 ;; present and thus we must avoid subregs from being simplified and eliminated
19911 ;; in later compilation phases.
19912 ;;
19913 ;; We have following variants from each instruction:
19914 ;; sse_andsf3 - the operation taking V4SF vector operands
19915 ;;              and doing TImode cast on them
19916 ;; *sse_andsf3_memory - the operation taking one memory operand casted to
19917 ;;                      TImode, since backend insist on eliminating casts
19918 ;;                      on memory operands
19919 ;; sse_andti3_sf_1 - the operation taking SF scalar operands.
19920 ;;                   We can not accept memory operand here as instruction reads
19921 ;;                   whole scalar.  This is generated only post reload by GCC
19922 ;;                   scalar float operations that expands to logicals (fabs)
19923 ;; sse_andti3_sf_2 - the operation taking SF scalar input and TImode
19924 ;;                   memory operand.  Eventually combine can be able
19925 ;;                   to synthesize these using splitter.
19926 ;; sse2_anddf3, *sse2_anddf3_memory
19927 ;;              
19928 ;; 
19929 ;; These are not called andti3 etc. because we really really don't want
19930 ;; the compiler to widen DImode ands to TImode ands and then try to move
19931 ;; into DImode subregs of SSE registers, and them together, and move out
19932 ;; of DImode subregs again!
19933 ;; SSE1 single precision floating point logical operation
19934 (define_expand "sse_andv4sf3"
19935   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19936         (and:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19937                 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19938   "TARGET_SSE"
19939   "")
19940
19941 (define_insn "*sse_andv4sf3"
19942   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19943         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19944                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19945   "TARGET_SSE
19946    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19947   "andps\t{%2, %0|%0, %2}"
19948   [(set_attr "type" "sselog")
19949    (set_attr "mode" "V4SF")])
19950
19951 (define_insn "*sse_andsf3"
19952   [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19953         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19954                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19955   "TARGET_SSE
19956    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19957   "andps\t{%2, %0|%0, %2}"
19958   [(set_attr "type" "sselog")
19959    (set_attr "mode" "V4SF")])
19960
19961 (define_expand "sse_nandv4sf3"
19962   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19963         (and:TI (not:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0))
19964                 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19965   "TARGET_SSE"
19966   "")
19967
19968 (define_insn "*sse_nandv4sf3"
19969   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19970         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19971                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19972   "TARGET_SSE"
19973   "andnps\t{%2, %0|%0, %2}"
19974   [(set_attr "type" "sselog")
19975    (set_attr "mode" "V4SF")])
19976
19977 (define_insn "*sse_nandsf3"
19978   [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
19979         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
19980                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19981   "TARGET_SSE"
19982   "andnps\t{%2, %0|%0, %2}"
19983   [(set_attr "type" "sselog")
19984    (set_attr "mode" "V4SF")])
19985
19986 (define_expand "sse_iorv4sf3"
19987   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
19988         (ior:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
19989                 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
19990   "TARGET_SSE"
19991   "")
19992
19993 (define_insn "*sse_iorv4sf3"
19994   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
19995         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
19996                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
19997   "TARGET_SSE
19998    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
19999   "orps\t{%2, %0|%0, %2}"
20000   [(set_attr "type" "sselog")
20001    (set_attr "mode" "V4SF")])
20002
20003 (define_insn "*sse_iorsf3"
20004   [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
20005         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20006                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20007   "TARGET_SSE
20008    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20009   "orps\t{%2, %0|%0, %2}"
20010   [(set_attr "type" "sselog")
20011    (set_attr "mode" "V4SF")])
20012
20013 (define_expand "sse_xorv4sf3"
20014   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
20015         (xor:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
20016                 (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
20017   "TARGET_SSE
20018    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20019   "")
20020
20021 (define_insn "*sse_xorv4sf3"
20022   [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
20023         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20024                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20025   "TARGET_SSE
20026    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20027   "xorps\t{%2, %0|%0, %2}"
20028   [(set_attr "type" "sselog")
20029    (set_attr "mode" "V4SF")])
20030
20031 (define_insn "*sse_xorsf3"
20032   [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
20033         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20034                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20035   "TARGET_SSE
20036    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20037   "xorps\t{%2, %0|%0, %2}"
20038   [(set_attr "type" "sselog")
20039    (set_attr "mode" "V4SF")])
20040
20041 ;; SSE2 double precision floating point logical operation
20042
20043 (define_expand "sse2_andv2df3"
20044   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
20045         (and:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
20046                 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
20047   "TARGET_SSE2"
20048   "")
20049
20050 (define_insn "*sse2_andv2df3"
20051   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
20052         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20053                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20054   "TARGET_SSE2
20055    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20056   "andpd\t{%2, %0|%0, %2}"
20057   [(set_attr "type" "sselog")
20058    (set_attr "mode" "V2DF")])
20059
20060 (define_insn "*sse2_andv2df3"
20061   [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
20062         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20063                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20064   "TARGET_SSE2
20065    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20066   "andpd\t{%2, %0|%0, %2}"
20067   [(set_attr "type" "sselog")
20068    (set_attr "mode" "V2DF")])
20069
20070 (define_expand "sse2_nandv2df3"
20071   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
20072         (and:TI (not:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0))
20073                 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
20074   "TARGET_SSE2"
20075   "")
20076
20077 (define_insn "*sse2_nandv2df3"
20078   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
20079         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20080                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20081   "TARGET_SSE2"
20082   "andnpd\t{%2, %0|%0, %2}"
20083   [(set_attr "type" "sselog")
20084    (set_attr "mode" "V2DF")])
20085
20086 (define_insn "*sse_nandti3_df"
20087   [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
20088         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20089                 (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
20090   "TARGET_SSE2"
20091   "andnpd\t{%2, %0|%0, %2}"
20092   [(set_attr "type" "sselog")
20093    (set_attr "mode" "V2DF")])
20094
20095 (define_expand "sse2_iorv2df3"
20096   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
20097         (ior:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
20098                 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
20099   "TARGET_SSE2"
20100   "")
20101
20102 (define_insn "*sse2_iorv2df3"
20103   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
20104         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20105                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20106   "TARGET_SSE2
20107    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20108   "orpd\t{%2, %0|%0, %2}"
20109   [(set_attr "type" "sselog")
20110    (set_attr "mode" "V2DF")])
20111
20112 (define_insn "*sse2_iordf3"
20113   [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
20114         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20115                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20116   "TARGET_SSE2
20117    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20118   "orpd\t{%2, %0|%0, %2}"
20119   [(set_attr "type" "sselog")
20120    (set_attr "mode" "V2DF")])
20121
20122 (define_expand "sse2_xorv2df3"
20123   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
20124         (xor:TI (subreg:TI (match_operand:V2DF 1 "nonimmediate_operand" "") 0)
20125                 (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
20126   "TARGET_SSE2"
20127   "")
20128
20129 (define_insn "*sse2_xorv2df3"
20130   [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
20131         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20132                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20133   "TARGET_SSE2
20134    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20135   "xorpd\t{%2, %0|%0, %2}"
20136   [(set_attr "type" "sselog")
20137    (set_attr "mode" "V2DF")])
20138
20139 (define_insn "*sse2_xordf3"
20140   [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
20141         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20142                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20143   "TARGET_SSE2
20144    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20145   "xorpd\t{%2, %0|%0, %2}"
20146   [(set_attr "type" "sselog")
20147    (set_attr "mode" "V2DF")])
20148
20149 ;; SSE2 integral logicals.  These patterns must always come after floating
20150 ;; point ones since we don't want compiler to use integer opcodes on floating
20151 ;; point SSE values to avoid matching of subregs in the match_operand.
20152 (define_insn "*sse2_andti3"
20153   [(set (match_operand:TI 0 "register_operand" "=x")
20154         (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20155                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20156   "TARGET_SSE2
20157    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20158   "pand\t{%2, %0|%0, %2}"
20159   [(set_attr "type" "sselog")
20160    (set_attr "mode" "TI")])
20161
20162 (define_insn "sse2_andv2di3"
20163   [(set (match_operand:V2DI 0 "register_operand" "=x")
20164         (and:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20165                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20166   "TARGET_SSE2
20167    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20168   "pand\t{%2, %0|%0, %2}"
20169   [(set_attr "type" "sselog")
20170    (set_attr "mode" "TI")])
20171
20172 (define_insn "*sse2_nandti3"
20173   [(set (match_operand:TI 0 "register_operand" "=x")
20174         (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
20175                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20176   "TARGET_SSE2"
20177   "pandn\t{%2, %0|%0, %2}"
20178   [(set_attr "type" "sselog")
20179    (set_attr "mode" "TI")])
20180
20181 (define_insn "sse2_nandv2di3"
20182   [(set (match_operand:V2DI 0 "register_operand" "=x")
20183         (and:V2DI (not:V2DI (match_operand:V2DI 1 "register_operand" "0"))
20184                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20185   "TARGET_SSE2
20186    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20187   "pandn\t{%2, %0|%0, %2}"
20188   [(set_attr "type" "sselog")
20189    (set_attr "mode" "TI")])
20190
20191 (define_insn "*sse2_iorti3"
20192   [(set (match_operand:TI 0 "register_operand" "=x")
20193         (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20194                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20195   "TARGET_SSE2
20196    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20197   "por\t{%2, %0|%0, %2}"
20198   [(set_attr "type" "sselog")
20199    (set_attr "mode" "TI")])
20200
20201 (define_insn "sse2_iorv2di3"
20202   [(set (match_operand:V2DI 0 "register_operand" "=x")
20203         (ior:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20204                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20205   "TARGET_SSE2
20206    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20207   "por\t{%2, %0|%0, %2}"
20208   [(set_attr "type" "sselog")
20209    (set_attr "mode" "TI")])
20210
20211 (define_insn "*sse2_xorti3"
20212   [(set (match_operand:TI 0 "register_operand" "=x")
20213         (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
20214                 (match_operand:TI 2 "nonimmediate_operand" "xm")))]
20215   "TARGET_SSE2
20216    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20217   "pxor\t{%2, %0|%0, %2}"
20218   [(set_attr "type" "sselog")
20219    (set_attr "mode" "TI")])
20220
20221 (define_insn "sse2_xorv2di3"
20222   [(set (match_operand:V2DI 0 "register_operand" "=x")
20223         (xor:V2DI (match_operand:V2DI 1 "nonimmediate_operand" "%0")
20224                   (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
20225   "TARGET_SSE2
20226    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
20227   "pxor\t{%2, %0|%0, %2}"
20228   [(set_attr "type" "sselog")
20229    (set_attr "mode" "TI")])
20230
20231 ;; Use xor, but don't show input operands so they aren't live before
20232 ;; this insn.
20233 (define_insn "sse_clrv4sf"
20234   [(set (match_operand:V4SF 0 "register_operand" "=x")
20235         (match_operand:V4SF 1 "const0_operand" "X"))]
20236   "TARGET_SSE"
20237 {
20238   if (get_attr_mode (insn) == MODE_TI)
20239     return "pxor\t{%0, %0|%0, %0}";
20240   else
20241     return "xorps\t{%0, %0|%0, %0}";
20242 }
20243   [(set_attr "type" "sselog")
20244    (set_attr "memory" "none")
20245    (set (attr "mode")
20246         (if_then_else
20247            (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
20248                          (const_int 0))
20249                      (ne (symbol_ref "TARGET_SSE2")
20250                          (const_int 0)))
20251                 (eq (symbol_ref "optimize_size")
20252                     (const_int 0)))
20253          (const_string "TI")
20254          (const_string "V4SF")))])
20255
20256 ;; Use xor, but don't show input operands so they aren't live before
20257 ;; this insn.
20258 (define_insn "sse_clrv2df"
20259   [(set (match_operand:V2DF 0 "register_operand" "=x")
20260         (unspec:V2DF [(const_int 0)] UNSPEC_NOP))]
20261   "TARGET_SSE2"
20262   "xorpd\t{%0, %0|%0, %0}"
20263   [(set_attr "type" "sselog")
20264    (set_attr "memory" "none")
20265    (set_attr "mode" "V4SF")])
20266
20267 ;; SSE mask-generating compares
20268
20269 (define_insn "maskcmpv4sf3"
20270   [(set (match_operand:V4SI 0 "register_operand" "=x")
20271         (match_operator:V4SI 3 "sse_comparison_operator"
20272                 [(match_operand:V4SF 1 "register_operand" "0")
20273                  (match_operand:V4SF 2 "register_operand" "x")]))]
20274   "TARGET_SSE"
20275   "cmp%D3ps\t{%2, %0|%0, %2}"
20276   [(set_attr "type" "ssecmp")
20277    (set_attr "mode" "V4SF")])
20278
20279 (define_insn "maskncmpv4sf3"
20280   [(set (match_operand:V4SI 0 "register_operand" "=x")
20281         (not:V4SI
20282          (match_operator:V4SI 3 "sse_comparison_operator"
20283                 [(match_operand:V4SF 1 "register_operand" "0")
20284                  (match_operand:V4SF 2 "register_operand" "x")])))]
20285   "TARGET_SSE"
20286 {
20287   if (GET_CODE (operands[3]) == UNORDERED)
20288     return "cmpordps\t{%2, %0|%0, %2}";
20289   else
20290     return "cmpn%D3ps\t{%2, %0|%0, %2}";
20291 }
20292   [(set_attr "type" "ssecmp")
20293    (set_attr "mode" "V4SF")])
20294
20295 (define_insn "vmmaskcmpv4sf3"
20296   [(set (match_operand:V4SI 0 "register_operand" "=x")
20297         (vec_merge:V4SI
20298          (match_operator:V4SI 3 "sse_comparison_operator"
20299                 [(match_operand:V4SF 1 "register_operand" "0")
20300                  (match_operand:V4SF 2 "register_operand" "x")])
20301          (subreg:V4SI (match_dup 1) 0)
20302          (const_int 1)))]
20303   "TARGET_SSE"
20304   "cmp%D3ss\t{%2, %0|%0, %2}"
20305   [(set_attr "type" "ssecmp")
20306    (set_attr "mode" "SF")])
20307
20308 (define_insn "vmmaskncmpv4sf3"
20309   [(set (match_operand:V4SI 0 "register_operand" "=x")
20310         (vec_merge:V4SI
20311          (not:V4SI
20312           (match_operator:V4SI 3 "sse_comparison_operator"
20313                 [(match_operand:V4SF 1 "register_operand" "0")
20314                  (match_operand:V4SF 2 "register_operand" "x")]))
20315          (subreg:V4SI (match_dup 1) 0)
20316          (const_int 1)))]
20317   "TARGET_SSE"
20318 {
20319   if (GET_CODE (operands[3]) == UNORDERED)
20320     return "cmpordss\t{%2, %0|%0, %2}";
20321   else
20322     return "cmpn%D3ss\t{%2, %0|%0, %2}";
20323 }
20324   [(set_attr "type" "ssecmp")
20325    (set_attr "mode" "SF")])
20326
20327 (define_insn "sse_comi"
20328   [(set (reg:CCFP 17)
20329         (compare:CCFP (vec_select:SF
20330                        (match_operand:V4SF 0 "register_operand" "x")
20331                        (parallel [(const_int 0)]))
20332                       (vec_select:SF
20333                        (match_operand:V4SF 1 "register_operand" "x")
20334                        (parallel [(const_int 0)]))))]
20335   "TARGET_SSE"
20336   "comiss\t{%1, %0|%0, %1}"
20337   [(set_attr "type" "ssecomi")
20338    (set_attr "mode" "SF")])
20339
20340 (define_insn "sse_ucomi"
20341   [(set (reg:CCFPU 17)
20342         (compare:CCFPU (vec_select:SF
20343                         (match_operand:V4SF 0 "register_operand" "x")
20344                         (parallel [(const_int 0)]))
20345                        (vec_select:SF
20346                         (match_operand:V4SF 1 "register_operand" "x")
20347                         (parallel [(const_int 0)]))))]
20348   "TARGET_SSE"
20349   "ucomiss\t{%1, %0|%0, %1}"
20350   [(set_attr "type" "ssecomi")
20351    (set_attr "mode" "SF")])
20352
20353
20354 ;; SSE unpack
20355
20356 (define_insn "sse_unpckhps"
20357   [(set (match_operand:V4SF 0 "register_operand" "=x")
20358         (vec_merge:V4SF
20359          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20360                           (parallel [(const_int 2)
20361                                      (const_int 0)
20362                                      (const_int 3)
20363                                      (const_int 1)]))
20364          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20365                           (parallel [(const_int 0)
20366                                      (const_int 2)
20367                                      (const_int 1)
20368                                      (const_int 3)]))
20369          (const_int 5)))]
20370   "TARGET_SSE"
20371   "unpckhps\t{%2, %0|%0, %2}"
20372   [(set_attr "type" "ssecvt")
20373    (set_attr "mode" "V4SF")])
20374
20375 (define_insn "sse_unpcklps"
20376   [(set (match_operand:V4SF 0 "register_operand" "=x")
20377         (vec_merge:V4SF
20378          (vec_select:V4SF (match_operand:V4SF 1 "register_operand" "0")
20379                           (parallel [(const_int 0)
20380                                      (const_int 2)
20381                                      (const_int 1)
20382                                      (const_int 3)]))
20383          (vec_select:V4SF (match_operand:V4SF 2 "register_operand" "x")
20384                           (parallel [(const_int 2)
20385                                      (const_int 0)
20386                                      (const_int 3)
20387                                      (const_int 1)]))
20388          (const_int 5)))]
20389   "TARGET_SSE"
20390   "unpcklps\t{%2, %0|%0, %2}"
20391   [(set_attr "type" "ssecvt")
20392    (set_attr "mode" "V4SF")])
20393
20394
20395 ;; SSE min/max
20396
20397 (define_insn "smaxv4sf3"
20398   [(set (match_operand:V4SF 0 "register_operand" "=x")
20399         (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20400                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20401   "TARGET_SSE"
20402   "maxps\t{%2, %0|%0, %2}"
20403   [(set_attr "type" "sse")
20404    (set_attr "mode" "V4SF")])
20405
20406 (define_insn "vmsmaxv4sf3"
20407   [(set (match_operand:V4SF 0 "register_operand" "=x")
20408         (vec_merge:V4SF
20409          (smax:V4SF (match_operand:V4SF 1 "register_operand" "0")
20410                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20411          (match_dup 1)
20412          (const_int 1)))]
20413   "TARGET_SSE"
20414   "maxss\t{%2, %0|%0, %2}"
20415   [(set_attr "type" "sse")
20416    (set_attr "mode" "SF")])
20417
20418 (define_insn "sminv4sf3"
20419   [(set (match_operand:V4SF 0 "register_operand" "=x")
20420         (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20421                    (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
20422   "TARGET_SSE"
20423   "minps\t{%2, %0|%0, %2}"
20424   [(set_attr "type" "sse")
20425    (set_attr "mode" "V4SF")])
20426
20427 (define_insn "vmsminv4sf3"
20428   [(set (match_operand:V4SF 0 "register_operand" "=x")
20429         (vec_merge:V4SF
20430          (smin:V4SF (match_operand:V4SF 1 "register_operand" "0")
20431                     (match_operand:V4SF 2 "nonimmediate_operand" "xm"))
20432          (match_dup 1)
20433          (const_int 1)))]
20434   "TARGET_SSE"
20435   "minss\t{%2, %0|%0, %2}"
20436   [(set_attr "type" "sse")
20437    (set_attr "mode" "SF")])
20438
20439 ;; SSE <-> integer/MMX conversions
20440
20441 (define_insn "cvtpi2ps"
20442   [(set (match_operand:V4SF 0 "register_operand" "=x")
20443         (vec_merge:V4SF
20444          (match_operand:V4SF 1 "register_operand" "0")
20445          (vec_duplicate:V4SF
20446           (float:V2SF (match_operand:V2SI 2 "nonimmediate_operand" "ym")))
20447          (const_int 12)))]
20448   "TARGET_SSE"
20449   "cvtpi2ps\t{%2, %0|%0, %2}"
20450   [(set_attr "type" "ssecvt")
20451    (set_attr "mode" "V4SF")])
20452
20453 (define_insn "cvtps2pi"
20454   [(set (match_operand:V2SI 0 "register_operand" "=y")
20455         (vec_select:V2SI
20456          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm"))
20457          (parallel [(const_int 0) (const_int 1)])))]
20458   "TARGET_SSE"
20459   "cvtps2pi\t{%1, %0|%0, %1}"
20460   [(set_attr "type" "ssecvt")
20461    (set_attr "mode" "V4SF")])
20462
20463 (define_insn "cvttps2pi"
20464   [(set (match_operand:V2SI 0 "register_operand" "=y")
20465         (vec_select:V2SI
20466          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
20467                       UNSPEC_FIX)
20468          (parallel [(const_int 0) (const_int 1)])))]
20469   "TARGET_SSE"
20470   "cvttps2pi\t{%1, %0|%0, %1}"
20471   [(set_attr "type" "ssecvt")
20472    (set_attr "mode" "SF")])
20473
20474 (define_insn "cvtsi2ss"
20475   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20476         (vec_merge:V4SF
20477          (match_operand:V4SF 1 "register_operand" "0,0")
20478          (vec_duplicate:V4SF
20479           (float:SF (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
20480          (const_int 14)))]
20481   "TARGET_SSE"
20482   "cvtsi2ss\t{%2, %0|%0, %2}"
20483   [(set_attr "type" "sseicvt")
20484    (set_attr "athlon_decode" "vector,double")
20485    (set_attr "mode" "SF")])
20486
20487 (define_insn "cvtsi2ssq"
20488   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
20489         (vec_merge:V4SF
20490          (match_operand:V4SF 1 "register_operand" "0,0")
20491          (vec_duplicate:V4SF
20492           (float:SF (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
20493          (const_int 14)))]
20494   "TARGET_SSE && TARGET_64BIT"
20495   "cvtsi2ssq\t{%2, %0|%0, %2}"
20496   [(set_attr "type" "sseicvt")
20497    (set_attr "athlon_decode" "vector,double")
20498    (set_attr "mode" "SF")])
20499
20500 (define_insn "cvtss2si"
20501   [(set (match_operand:SI 0 "register_operand" "=r,r")
20502         (vec_select:SI
20503          (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20504          (parallel [(const_int 0)])))]
20505   "TARGET_SSE"
20506   "cvtss2si\t{%1, %0|%0, %1}"
20507   [(set_attr "type" "sseicvt")
20508    (set_attr "athlon_decode" "double,vector")
20509    (set_attr "mode" "SI")])
20510
20511 (define_insn "cvtss2siq"
20512   [(set (match_operand:DI 0 "register_operand" "=r,r")
20513         (vec_select:DI
20514          (fix:V4DI (match_operand:V4SF 1 "nonimmediate_operand" "x,m"))
20515          (parallel [(const_int 0)])))]
20516   "TARGET_SSE"
20517   "cvtss2siq\t{%1, %0|%0, %1}"
20518   [(set_attr "type" "sseicvt")
20519    (set_attr "athlon_decode" "double,vector")
20520    (set_attr "mode" "DI")])
20521
20522 (define_insn "cvttss2si"
20523   [(set (match_operand:SI 0 "register_operand" "=r,r")
20524         (vec_select:SI
20525          (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20526                       UNSPEC_FIX)
20527          (parallel [(const_int 0)])))]
20528   "TARGET_SSE"
20529   "cvttss2si\t{%1, %0|%0, %1}"
20530   [(set_attr "type" "sseicvt")
20531    (set_attr "mode" "SF")
20532    (set_attr "athlon_decode" "double,vector")])
20533
20534 (define_insn "cvttss2siq"
20535   [(set (match_operand:DI 0 "register_operand" "=r,r")
20536         (vec_select:DI
20537          (unspec:V4DI [(match_operand:V4SF 1 "nonimmediate_operand" "x,xm")]
20538                       UNSPEC_FIX)
20539          (parallel [(const_int 0)])))]
20540   "TARGET_SSE && TARGET_64BIT"
20541   "cvttss2siq\t{%1, %0|%0, %1}"
20542   [(set_attr "type" "sseicvt")
20543    (set_attr "mode" "SF")
20544    (set_attr "athlon_decode" "double,vector")])
20545
20546
20547 ;; MMX insns
20548
20549 ;; MMX arithmetic
20550
20551 (define_insn "addv8qi3"
20552   [(set (match_operand:V8QI 0 "register_operand" "=y")
20553         (plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20554                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20555   "TARGET_MMX"
20556   "paddb\t{%2, %0|%0, %2}"
20557   [(set_attr "type" "mmxadd")
20558    (set_attr "mode" "DI")])
20559
20560 (define_insn "addv4hi3"
20561   [(set (match_operand:V4HI 0 "register_operand" "=y")
20562         (plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20563                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20564   "TARGET_MMX"
20565   "paddw\t{%2, %0|%0, %2}"
20566   [(set_attr "type" "mmxadd")
20567    (set_attr "mode" "DI")])
20568
20569 (define_insn "addv2si3"
20570   [(set (match_operand:V2SI 0 "register_operand" "=y")
20571         (plus:V2SI (match_operand:V2SI 1 "register_operand" "%0")
20572                    (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20573   "TARGET_MMX"
20574   "paddd\t{%2, %0|%0, %2}"
20575   [(set_attr "type" "mmxadd")
20576    (set_attr "mode" "DI")])
20577
20578 (define_insn "mmx_adddi3"
20579   [(set (match_operand:DI 0 "register_operand" "=y")
20580         (unspec:DI
20581          [(plus:DI (match_operand:DI 1 "register_operand" "%0")
20582                    (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20583          UNSPEC_NOP))]
20584   "TARGET_MMX"
20585   "paddq\t{%2, %0|%0, %2}"
20586   [(set_attr "type" "mmxadd")
20587    (set_attr "mode" "DI")])
20588
20589 (define_insn "ssaddv8qi3"
20590   [(set (match_operand:V8QI 0 "register_operand" "=y")
20591         (ss_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20592                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20593   "TARGET_MMX"
20594   "paddsb\t{%2, %0|%0, %2}"
20595   [(set_attr "type" "mmxadd")
20596    (set_attr "mode" "DI")])
20597
20598 (define_insn "ssaddv4hi3"
20599   [(set (match_operand:V4HI 0 "register_operand" "=y")
20600         (ss_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20601                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20602   "TARGET_MMX"
20603   "paddsw\t{%2, %0|%0, %2}"
20604   [(set_attr "type" "mmxadd")
20605    (set_attr "mode" "DI")])
20606
20607 (define_insn "usaddv8qi3"
20608   [(set (match_operand:V8QI 0 "register_operand" "=y")
20609         (us_plus:V8QI (match_operand:V8QI 1 "register_operand" "%0")
20610                       (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20611   "TARGET_MMX"
20612   "paddusb\t{%2, %0|%0, %2}"
20613   [(set_attr "type" "mmxadd")
20614    (set_attr "mode" "DI")])
20615
20616 (define_insn "usaddv4hi3"
20617   [(set (match_operand:V4HI 0 "register_operand" "=y")
20618         (us_plus:V4HI (match_operand:V4HI 1 "register_operand" "%0")
20619                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20620   "TARGET_MMX"
20621   "paddusw\t{%2, %0|%0, %2}"
20622   [(set_attr "type" "mmxadd")
20623    (set_attr "mode" "DI")])
20624
20625 (define_insn "subv8qi3"
20626   [(set (match_operand:V8QI 0 "register_operand" "=y")
20627         (minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20628                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20629   "TARGET_MMX"
20630   "psubb\t{%2, %0|%0, %2}"
20631   [(set_attr "type" "mmxadd")
20632    (set_attr "mode" "DI")])
20633
20634 (define_insn "subv4hi3"
20635   [(set (match_operand:V4HI 0 "register_operand" "=y")
20636         (minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20637                     (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20638   "TARGET_MMX"
20639   "psubw\t{%2, %0|%0, %2}"
20640   [(set_attr "type" "mmxadd")
20641    (set_attr "mode" "DI")])
20642
20643 (define_insn "subv2si3"
20644   [(set (match_operand:V2SI 0 "register_operand" "=y")
20645         (minus:V2SI (match_operand:V2SI 1 "register_operand" "0")
20646                     (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20647   "TARGET_MMX"
20648   "psubd\t{%2, %0|%0, %2}"
20649   [(set_attr "type" "mmxadd")
20650    (set_attr "mode" "DI")])
20651
20652 (define_insn "mmx_subdi3"
20653   [(set (match_operand:DI 0 "register_operand" "=y")
20654         (unspec:DI
20655          [(minus:DI (match_operand:DI 1 "register_operand" "0")
20656                     (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20657          UNSPEC_NOP))]
20658   "TARGET_MMX"
20659   "psubq\t{%2, %0|%0, %2}"
20660   [(set_attr "type" "mmxadd")
20661    (set_attr "mode" "DI")])
20662
20663 (define_insn "sssubv8qi3"
20664   [(set (match_operand:V8QI 0 "register_operand" "=y")
20665         (ss_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20666                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20667   "TARGET_MMX"
20668   "psubsb\t{%2, %0|%0, %2}"
20669   [(set_attr "type" "mmxadd")
20670    (set_attr "mode" "DI")])
20671
20672 (define_insn "sssubv4hi3"
20673   [(set (match_operand:V4HI 0 "register_operand" "=y")
20674         (ss_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20675                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20676   "TARGET_MMX"
20677   "psubsw\t{%2, %0|%0, %2}"
20678   [(set_attr "type" "mmxadd")
20679    (set_attr "mode" "DI")])
20680
20681 (define_insn "ussubv8qi3"
20682   [(set (match_operand:V8QI 0 "register_operand" "=y")
20683         (us_minus:V8QI (match_operand:V8QI 1 "register_operand" "0")
20684                        (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20685   "TARGET_MMX"
20686   "psubusb\t{%2, %0|%0, %2}"
20687   [(set_attr "type" "mmxadd")
20688    (set_attr "mode" "DI")])
20689
20690 (define_insn "ussubv4hi3"
20691   [(set (match_operand:V4HI 0 "register_operand" "=y")
20692         (us_minus:V4HI (match_operand:V4HI 1 "register_operand" "0")
20693                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20694   "TARGET_MMX"
20695   "psubusw\t{%2, %0|%0, %2}"
20696   [(set_attr "type" "mmxadd")
20697    (set_attr "mode" "DI")])
20698
20699 (define_insn "mulv4hi3"
20700   [(set (match_operand:V4HI 0 "register_operand" "=y")
20701         (mult:V4HI (match_operand:V4HI 1 "register_operand" "0")
20702                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20703   "TARGET_MMX"
20704   "pmullw\t{%2, %0|%0, %2}"
20705   [(set_attr "type" "mmxmul")
20706    (set_attr "mode" "DI")])
20707
20708 (define_insn "smulv4hi3_highpart"
20709   [(set (match_operand:V4HI 0 "register_operand" "=y")
20710         (truncate:V4HI
20711          (lshiftrt:V4SI
20712           (mult:V4SI (sign_extend:V4SI
20713                       (match_operand:V4HI 1 "register_operand" "0"))
20714                      (sign_extend:V4SI
20715                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20716           (const_int 16))))]
20717   "TARGET_MMX"
20718   "pmulhw\t{%2, %0|%0, %2}"
20719   [(set_attr "type" "mmxmul")
20720    (set_attr "mode" "DI")])
20721
20722 (define_insn "umulv4hi3_highpart"
20723   [(set (match_operand:V4HI 0 "register_operand" "=y")
20724         (truncate:V4HI
20725          (lshiftrt:V4SI
20726           (mult:V4SI (zero_extend:V4SI
20727                       (match_operand:V4HI 1 "register_operand" "0"))
20728                      (zero_extend:V4SI
20729                       (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
20730           (const_int 16))))]
20731   "TARGET_SSE || TARGET_3DNOW_A"
20732   "pmulhuw\t{%2, %0|%0, %2}"
20733   [(set_attr "type" "mmxmul")
20734    (set_attr "mode" "DI")])
20735
20736 (define_insn "mmx_pmaddwd"
20737   [(set (match_operand:V2SI 0 "register_operand" "=y")
20738         (plus:V2SI
20739          (mult:V2SI
20740           (sign_extend:V2SI
20741            (vec_select:V2HI (match_operand:V4HI 1 "register_operand" "0")
20742                             (parallel [(const_int 0) (const_int 2)])))
20743           (sign_extend:V2SI
20744            (vec_select:V2HI (match_operand:V4HI 2 "nonimmediate_operand" "ym")
20745                             (parallel [(const_int 0) (const_int 2)]))))
20746          (mult:V2SI
20747           (sign_extend:V2SI (vec_select:V2HI (match_dup 1)
20748                                              (parallel [(const_int 1)
20749                                                         (const_int 3)])))
20750           (sign_extend:V2SI (vec_select:V2HI (match_dup 2)
20751                                              (parallel [(const_int 1)
20752                                                         (const_int 3)]))))))]
20753   "TARGET_MMX"
20754   "pmaddwd\t{%2, %0|%0, %2}"
20755   [(set_attr "type" "mmxmul")
20756    (set_attr "mode" "DI")])
20757
20758
20759 ;; MMX logical operations
20760 ;; Note we don't want to declare these as regular iordi3 insns to prevent
20761 ;; normal code that also wants to use the FPU from getting broken.
20762 ;; The UNSPECs are there to prevent the combiner from getting overly clever.
20763 (define_insn "mmx_iordi3"
20764   [(set (match_operand:DI 0 "register_operand" "=y")
20765         (unspec:DI
20766          [(ior:DI (match_operand:DI 1 "register_operand" "%0")
20767                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20768          UNSPEC_NOP))]
20769   "TARGET_MMX"
20770   "por\t{%2, %0|%0, %2}"
20771   [(set_attr "type" "mmxadd")
20772    (set_attr "mode" "DI")])
20773
20774 (define_insn "mmx_xordi3"
20775   [(set (match_operand:DI 0 "register_operand" "=y")
20776         (unspec:DI
20777          [(xor:DI (match_operand:DI 1 "register_operand" "%0")
20778                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20779          UNSPEC_NOP))]
20780   "TARGET_MMX"
20781   "pxor\t{%2, %0|%0, %2}"
20782   [(set_attr "type" "mmxadd")
20783    (set_attr "mode" "DI")
20784    (set_attr "memory" "none")])
20785
20786 ;; Same as pxor, but don't show input operands so that we don't think
20787 ;; they are live.
20788 (define_insn "mmx_clrdi"
20789   [(set (match_operand:DI 0 "register_operand" "=y")
20790         (unspec:DI [(const_int 0)] UNSPEC_NOP))]
20791   "TARGET_MMX"
20792   "pxor\t{%0, %0|%0, %0}"
20793   [(set_attr "type" "mmxadd")
20794    (set_attr "mode" "DI")
20795    (set_attr "memory" "none")])
20796
20797 (define_insn "mmx_anddi3"
20798   [(set (match_operand:DI 0 "register_operand" "=y")
20799         (unspec:DI
20800          [(and:DI (match_operand:DI 1 "register_operand" "%0")
20801                   (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20802          UNSPEC_NOP))]
20803   "TARGET_MMX"
20804   "pand\t{%2, %0|%0, %2}"
20805   [(set_attr "type" "mmxadd")
20806    (set_attr "mode" "DI")])
20807
20808 (define_insn "mmx_nanddi3"
20809   [(set (match_operand:DI 0 "register_operand" "=y")
20810         (unspec:DI
20811          [(and:DI (not:DI (match_operand:DI 1 "register_operand" "0"))
20812                           (match_operand:DI 2 "nonimmediate_operand" "ym"))]
20813          UNSPEC_NOP))]
20814   "TARGET_MMX"
20815   "pandn\t{%2, %0|%0, %2}"
20816   [(set_attr "type" "mmxadd")
20817    (set_attr "mode" "DI")])
20818
20819
20820 ;; MMX unsigned averages/sum of absolute differences
20821
20822 (define_insn "mmx_uavgv8qi3"
20823   [(set (match_operand:V8QI 0 "register_operand" "=y")
20824         (ashiftrt:V8QI
20825          (plus:V8QI (plus:V8QI
20826                      (match_operand:V8QI 1 "register_operand" "0")
20827                      (match_operand:V8QI 2 "nonimmediate_operand" "ym"))
20828                     (const_vector:V8QI [(const_int 1)
20829                                         (const_int 1)
20830                                         (const_int 1)
20831                                         (const_int 1)
20832                                         (const_int 1)
20833                                         (const_int 1)
20834                                         (const_int 1)
20835                                         (const_int 1)]))
20836          (const_int 1)))]
20837   "TARGET_SSE || TARGET_3DNOW_A"
20838   "pavgb\t{%2, %0|%0, %2}"
20839   [(set_attr "type" "mmxshft")
20840    (set_attr "mode" "DI")])
20841
20842 (define_insn "mmx_uavgv4hi3"
20843   [(set (match_operand:V4HI 0 "register_operand" "=y")
20844         (ashiftrt:V4HI
20845          (plus:V4HI (plus:V4HI
20846                      (match_operand:V4HI 1 "register_operand" "0")
20847                      (match_operand:V4HI 2 "nonimmediate_operand" "ym"))
20848                     (const_vector:V4HI [(const_int 1)
20849                                         (const_int 1)
20850                                         (const_int 1)
20851                                         (const_int 1)]))
20852          (const_int 1)))]
20853   "TARGET_SSE || TARGET_3DNOW_A"
20854   "pavgw\t{%2, %0|%0, %2}"
20855   [(set_attr "type" "mmxshft")
20856    (set_attr "mode" "DI")])
20857
20858 (define_insn "mmx_psadbw"
20859   [(set (match_operand:DI 0 "register_operand" "=y")
20860         (unspec:DI [(match_operand:V8QI 1 "register_operand" "0")
20861                     (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
20862                    UNSPEC_PSADBW))]
20863   "TARGET_SSE || TARGET_3DNOW_A"
20864   "psadbw\t{%2, %0|%0, %2}"
20865   [(set_attr "type" "mmxshft")
20866    (set_attr "mode" "DI")])
20867
20868
20869 ;; MMX insert/extract/shuffle
20870
20871 (define_insn "mmx_pinsrw"
20872   [(set (match_operand:V4HI 0 "register_operand" "=y")
20873         (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
20874                         (vec_duplicate:V4HI
20875                          (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
20876                         (match_operand:SI 3 "immediate_operand" "i")))]
20877   "TARGET_SSE || TARGET_3DNOW_A"
20878   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
20879   [(set_attr "type" "mmxcvt")
20880    (set_attr "mode" "DI")])
20881
20882 (define_insn "mmx_pextrw"
20883   [(set (match_operand:SI 0 "register_operand" "=r")
20884         (zero_extend:SI (vec_select:HI (match_operand:V4HI 1 "register_operand" "y")
20885                                        (parallel
20886                                         [(match_operand:SI 2 "immediate_operand" "i")]))))]
20887   "TARGET_SSE || TARGET_3DNOW_A"
20888   "pextrw\t{%2, %1, %0|%0, %1, %2}"
20889   [(set_attr "type" "mmxcvt")
20890    (set_attr "mode" "DI")])
20891
20892 (define_insn "mmx_pshufw"
20893   [(set (match_operand:V4HI 0 "register_operand" "=y")
20894         (unspec:V4HI [(match_operand:V4HI 1 "register_operand" "0")
20895                       (match_operand:SI 2 "immediate_operand" "i")]
20896                      UNSPEC_SHUFFLE))]
20897   "TARGET_SSE || TARGET_3DNOW_A"
20898   "pshufw\t{%2, %1, %0|%0, %1, %2}"
20899   [(set_attr "type" "mmxcvt")
20900    (set_attr "mode" "DI")])
20901
20902
20903 ;; MMX mask-generating comparisons
20904
20905 (define_insn "eqv8qi3"
20906   [(set (match_operand:V8QI 0 "register_operand" "=y")
20907         (eq:V8QI (match_operand:V8QI 1 "register_operand" "0")
20908                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20909   "TARGET_MMX"
20910   "pcmpeqb\t{%2, %0|%0, %2}"
20911   [(set_attr "type" "mmxcmp")
20912    (set_attr "mode" "DI")])
20913
20914 (define_insn "eqv4hi3"
20915   [(set (match_operand:V4HI 0 "register_operand" "=y")
20916         (eq:V4HI (match_operand:V4HI 1 "register_operand" "0")
20917                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20918   "TARGET_MMX"
20919   "pcmpeqw\t{%2, %0|%0, %2}"
20920   [(set_attr "type" "mmxcmp")
20921    (set_attr "mode" "DI")])
20922
20923 (define_insn "eqv2si3"
20924   [(set (match_operand:V2SI 0 "register_operand" "=y")
20925         (eq:V2SI (match_operand:V2SI 1 "register_operand" "0")
20926                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20927   "TARGET_MMX"
20928   "pcmpeqd\t{%2, %0|%0, %2}"
20929   [(set_attr "type" "mmxcmp")
20930    (set_attr "mode" "DI")])
20931
20932 (define_insn "gtv8qi3"
20933   [(set (match_operand:V8QI 0 "register_operand" "=y")
20934         (gt:V8QI (match_operand:V8QI 1 "register_operand" "0")
20935                  (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20936   "TARGET_MMX"
20937   "pcmpgtb\t{%2, %0|%0, %2}"
20938   [(set_attr "type" "mmxcmp")
20939    (set_attr "mode" "DI")])
20940
20941 (define_insn "gtv4hi3"
20942   [(set (match_operand:V4HI 0 "register_operand" "=y")
20943         (gt:V4HI (match_operand:V4HI 1 "register_operand" "0")
20944                  (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20945   "TARGET_MMX"
20946   "pcmpgtw\t{%2, %0|%0, %2}"
20947   [(set_attr "type" "mmxcmp")
20948    (set_attr "mode" "DI")])
20949
20950 (define_insn "gtv2si3"
20951   [(set (match_operand:V2SI 0 "register_operand" "=y")
20952         (gt:V2SI (match_operand:V2SI 1 "register_operand" "0")
20953                  (match_operand:V2SI 2 "nonimmediate_operand" "ym")))]
20954   "TARGET_MMX"
20955   "pcmpgtd\t{%2, %0|%0, %2}"
20956   [(set_attr "type" "mmxcmp")
20957    (set_attr "mode" "DI")])
20958
20959
20960 ;; MMX max/min insns
20961
20962 (define_insn "umaxv8qi3"
20963   [(set (match_operand:V8QI 0 "register_operand" "=y")
20964         (umax:V8QI (match_operand:V8QI 1 "register_operand" "0")
20965                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20966   "TARGET_SSE || TARGET_3DNOW_A"
20967   "pmaxub\t{%2, %0|%0, %2}"
20968   [(set_attr "type" "mmxadd")
20969    (set_attr "mode" "DI")])
20970
20971 (define_insn "smaxv4hi3"
20972   [(set (match_operand:V4HI 0 "register_operand" "=y")
20973         (smax:V4HI (match_operand:V4HI 1 "register_operand" "0")
20974                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20975   "TARGET_SSE || TARGET_3DNOW_A"
20976   "pmaxsw\t{%2, %0|%0, %2}"
20977   [(set_attr "type" "mmxadd")
20978    (set_attr "mode" "DI")])
20979
20980 (define_insn "uminv8qi3"
20981   [(set (match_operand:V8QI 0 "register_operand" "=y")
20982         (umin:V8QI (match_operand:V8QI 1 "register_operand" "0")
20983                    (match_operand:V8QI 2 "nonimmediate_operand" "ym")))]
20984   "TARGET_SSE || TARGET_3DNOW_A"
20985   "pminub\t{%2, %0|%0, %2}"
20986   [(set_attr "type" "mmxadd")
20987    (set_attr "mode" "DI")])
20988
20989 (define_insn "sminv4hi3"
20990   [(set (match_operand:V4HI 0 "register_operand" "=y")
20991         (smin:V4HI (match_operand:V4HI 1 "register_operand" "0")
20992                    (match_operand:V4HI 2 "nonimmediate_operand" "ym")))]
20993   "TARGET_SSE || TARGET_3DNOW_A"
20994   "pminsw\t{%2, %0|%0, %2}"
20995   [(set_attr "type" "mmxadd")
20996    (set_attr "mode" "DI")])
20997
20998
20999 ;; MMX shifts
21000
21001 (define_insn "ashrv4hi3"
21002   [(set (match_operand:V4HI 0 "register_operand" "=y")
21003         (ashiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21004                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21005   "TARGET_MMX"
21006   "psraw\t{%2, %0|%0, %2}"
21007   [(set_attr "type" "mmxshft")
21008    (set_attr "mode" "DI")])
21009
21010 (define_insn "ashrv2si3"
21011   [(set (match_operand:V2SI 0 "register_operand" "=y")
21012         (ashiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21013                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21014   "TARGET_MMX"
21015   "psrad\t{%2, %0|%0, %2}"
21016   [(set_attr "type" "mmxshft")
21017    (set_attr "mode" "DI")])
21018
21019 (define_insn "lshrv4hi3"
21020   [(set (match_operand:V4HI 0 "register_operand" "=y")
21021         (lshiftrt:V4HI (match_operand:V4HI 1 "register_operand" "0")
21022                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21023   "TARGET_MMX"
21024   "psrlw\t{%2, %0|%0, %2}"
21025   [(set_attr "type" "mmxshft")
21026    (set_attr "mode" "DI")])
21027
21028 (define_insn "lshrv2si3"
21029   [(set (match_operand:V2SI 0 "register_operand" "=y")
21030         (lshiftrt:V2SI (match_operand:V2SI 1 "register_operand" "0")
21031                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21032   "TARGET_MMX"
21033   "psrld\t{%2, %0|%0, %2}"
21034   [(set_attr "type" "mmxshft")
21035    (set_attr "mode" "DI")])
21036
21037 ;; See logical MMX insns.
21038 (define_insn "mmx_lshrdi3"
21039   [(set (match_operand:DI 0 "register_operand" "=y")
21040         (unspec:DI
21041           [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
21042                        (match_operand:DI 2 "nonmemory_operand" "yi"))]
21043           UNSPEC_NOP))]
21044   "TARGET_MMX"
21045   "psrlq\t{%2, %0|%0, %2}"
21046   [(set_attr "type" "mmxshft")
21047    (set_attr "mode" "DI")])
21048
21049 (define_insn "ashlv4hi3"
21050   [(set (match_operand:V4HI 0 "register_operand" "=y")
21051         (ashift:V4HI (match_operand:V4HI 1 "register_operand" "0")
21052                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21053   "TARGET_MMX"
21054   "psllw\t{%2, %0|%0, %2}"
21055   [(set_attr "type" "mmxshft")
21056    (set_attr "mode" "DI")])
21057
21058 (define_insn "ashlv2si3"
21059   [(set (match_operand:V2SI 0 "register_operand" "=y")
21060         (ashift:V2SI (match_operand:V2SI 1 "register_operand" "0")
21061                        (match_operand:DI 2 "nonmemory_operand" "yi")))]
21062   "TARGET_MMX"
21063   "pslld\t{%2, %0|%0, %2}"
21064   [(set_attr "type" "mmxshft")
21065    (set_attr "mode" "DI")])
21066
21067 ;; See logical MMX insns.
21068 (define_insn "mmx_ashldi3"
21069   [(set (match_operand:DI 0 "register_operand" "=y")
21070         (unspec:DI
21071          [(ashift:DI (match_operand:DI 1 "register_operand" "0")
21072                      (match_operand:DI 2 "nonmemory_operand" "yi"))]
21073          UNSPEC_NOP))]
21074   "TARGET_MMX"
21075   "psllq\t{%2, %0|%0, %2}"
21076   [(set_attr "type" "mmxshft")
21077    (set_attr "mode" "DI")])
21078
21079
21080 ;; MMX pack/unpack insns.
21081
21082 (define_insn "mmx_packsswb"
21083   [(set (match_operand:V8QI 0 "register_operand" "=y")
21084         (vec_concat:V8QI
21085          (ss_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21086          (ss_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21087   "TARGET_MMX"
21088   "packsswb\t{%2, %0|%0, %2}"
21089   [(set_attr "type" "mmxshft")
21090    (set_attr "mode" "DI")])
21091
21092 (define_insn "mmx_packssdw"
21093   [(set (match_operand:V4HI 0 "register_operand" "=y")
21094         (vec_concat:V4HI
21095          (ss_truncate:V2HI (match_operand:V2SI 1 "register_operand" "0"))
21096          (ss_truncate:V2HI (match_operand:V2SI 2 "register_operand" "y"))))]
21097   "TARGET_MMX"
21098   "packssdw\t{%2, %0|%0, %2}"
21099   [(set_attr "type" "mmxshft")
21100    (set_attr "mode" "DI")])
21101
21102 (define_insn "mmx_packuswb"
21103   [(set (match_operand:V8QI 0 "register_operand" "=y")
21104         (vec_concat:V8QI
21105          (us_truncate:V4QI (match_operand:V4HI 1 "register_operand" "0"))
21106          (us_truncate:V4QI (match_operand:V4HI 2 "register_operand" "y"))))]
21107   "TARGET_MMX"
21108   "packuswb\t{%2, %0|%0, %2}"
21109   [(set_attr "type" "mmxshft")
21110    (set_attr "mode" "DI")])
21111
21112 (define_insn "mmx_punpckhbw"
21113   [(set (match_operand:V8QI 0 "register_operand" "=y")
21114         (vec_merge:V8QI
21115          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21116                           (parallel [(const_int 4)
21117                                      (const_int 0)
21118                                      (const_int 5)
21119                                      (const_int 1)
21120                                      (const_int 6)
21121                                      (const_int 2)
21122                                      (const_int 7)
21123                                      (const_int 3)]))
21124          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21125                           (parallel [(const_int 0)
21126                                      (const_int 4)
21127                                      (const_int 1)
21128                                      (const_int 5)
21129                                      (const_int 2)
21130                                      (const_int 6)
21131                                      (const_int 3)
21132                                      (const_int 7)]))
21133          (const_int 85)))]
21134   "TARGET_MMX"
21135   "punpckhbw\t{%2, %0|%0, %2}"
21136   [(set_attr "type" "mmxcvt")
21137    (set_attr "mode" "DI")])
21138
21139 (define_insn "mmx_punpckhwd"
21140   [(set (match_operand:V4HI 0 "register_operand" "=y")
21141         (vec_merge:V4HI
21142          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21143                           (parallel [(const_int 0)
21144                                      (const_int 2)
21145                                      (const_int 1)
21146                                      (const_int 3)]))
21147          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21148                           (parallel [(const_int 2)
21149                                      (const_int 0)
21150                                      (const_int 3)
21151                                      (const_int 1)]))
21152          (const_int 5)))]
21153   "TARGET_MMX"
21154   "punpckhwd\t{%2, %0|%0, %2}"
21155   [(set_attr "type" "mmxcvt")
21156    (set_attr "mode" "DI")])
21157
21158 (define_insn "mmx_punpckhdq"
21159   [(set (match_operand:V2SI 0 "register_operand" "=y")
21160         (vec_merge:V2SI
21161          (match_operand:V2SI 1 "register_operand" "0")
21162          (vec_select:V2SI (match_operand:V2SI 2 "register_operand" "y")
21163                           (parallel [(const_int 1)
21164                                      (const_int 0)]))
21165          (const_int 1)))]
21166   "TARGET_MMX"
21167   "punpckhdq\t{%2, %0|%0, %2}"
21168   [(set_attr "type" "mmxcvt")
21169    (set_attr "mode" "DI")])
21170
21171 (define_insn "mmx_punpcklbw"
21172   [(set (match_operand:V8QI 0 "register_operand" "=y")
21173         (vec_merge:V8QI
21174          (vec_select:V8QI (match_operand:V8QI 1 "register_operand" "0")
21175                           (parallel [(const_int 0)
21176                                      (const_int 4)
21177                                      (const_int 1)
21178                                      (const_int 5)
21179                                      (const_int 2)
21180                                      (const_int 6)
21181                                      (const_int 3)
21182                                      (const_int 7)]))
21183          (vec_select:V8QI (match_operand:V8QI 2 "register_operand" "y")
21184                           (parallel [(const_int 4)
21185                                      (const_int 0)
21186                                      (const_int 5)
21187                                      (const_int 1)
21188                                      (const_int 6)
21189                                      (const_int 2)
21190                                      (const_int 7)
21191                                      (const_int 3)]))
21192          (const_int 85)))]
21193   "TARGET_MMX"
21194   "punpcklbw\t{%2, %0|%0, %2}"
21195   [(set_attr "type" "mmxcvt")
21196    (set_attr "mode" "DI")])
21197
21198 (define_insn "mmx_punpcklwd"
21199   [(set (match_operand:V4HI 0 "register_operand" "=y")
21200         (vec_merge:V4HI
21201          (vec_select:V4HI (match_operand:V4HI 1 "register_operand" "0")
21202                           (parallel [(const_int 2)
21203                                      (const_int 0)
21204                                      (const_int 3)
21205                                      (const_int 1)]))
21206          (vec_select:V4HI (match_operand:V4HI 2 "register_operand" "y")
21207                           (parallel [(const_int 0)
21208                                      (const_int 2)
21209                                      (const_int 1)
21210                                      (const_int 3)]))
21211          (const_int 5)))]
21212   "TARGET_MMX"
21213   "punpcklwd\t{%2, %0|%0, %2}"
21214   [(set_attr "type" "mmxcvt")
21215    (set_attr "mode" "DI")])
21216
21217 (define_insn "mmx_punpckldq"
21218   [(set (match_operand:V2SI 0 "register_operand" "=y")
21219         (vec_merge:V2SI
21220          (vec_select:V2SI (match_operand:V2SI 1 "register_operand" "0")
21221                            (parallel [(const_int 1)
21222                                       (const_int 0)]))
21223          (match_operand:V2SI 2 "register_operand" "y")
21224          (const_int 1)))]
21225   "TARGET_MMX"
21226   "punpckldq\t{%2, %0|%0, %2}"
21227   [(set_attr "type" "mmxcvt")
21228    (set_attr "mode" "DI")])
21229
21230
21231 ;; Miscellaneous stuff
21232
21233 (define_insn "emms"
21234   [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
21235    (clobber (reg:XF 8))
21236    (clobber (reg:XF 9))
21237    (clobber (reg:XF 10))
21238    (clobber (reg:XF 11))
21239    (clobber (reg:XF 12))
21240    (clobber (reg:XF 13))
21241    (clobber (reg:XF 14))
21242    (clobber (reg:XF 15))
21243    (clobber (reg:DI 29))
21244    (clobber (reg:DI 30))
21245    (clobber (reg:DI 31))
21246    (clobber (reg:DI 32))
21247    (clobber (reg:DI 33))
21248    (clobber (reg:DI 34))
21249    (clobber (reg:DI 35))
21250    (clobber (reg:DI 36))]
21251   "TARGET_MMX"
21252   "emms"
21253   [(set_attr "type" "mmx")
21254    (set_attr "memory" "unknown")])
21255
21256 (define_insn "ldmxcsr"
21257   [(unspec_volatile [(match_operand:SI 0 "memory_operand" "m")]
21258                     UNSPECV_LDMXCSR)]
21259   "TARGET_SSE"
21260   "ldmxcsr\t%0"
21261   [(set_attr "type" "sse")
21262    (set_attr "memory" "load")])
21263
21264 (define_insn "stmxcsr"
21265   [(set (match_operand:SI 0 "memory_operand" "=m")
21266         (unspec_volatile:SI [(const_int 0)] UNSPECV_STMXCSR))]
21267   "TARGET_SSE"
21268   "stmxcsr\t%0"
21269   [(set_attr "type" "sse")
21270    (set_attr "memory" "store")])
21271
21272 (define_expand "sfence"
21273   [(set (match_dup 0)
21274         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21275   "TARGET_SSE || TARGET_3DNOW_A"
21276 {
21277   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
21278   MEM_VOLATILE_P (operands[0]) = 1;
21279 })
21280
21281 (define_insn "*sfence_insn"
21282   [(set (match_operand:BLK 0 "" "")
21283         (unspec:BLK [(match_dup 0)] UNSPEC_SFENCE))]
21284   "TARGET_SSE || TARGET_3DNOW_A"
21285   "sfence"
21286   [(set_attr "type" "sse")
21287    (set_attr "memory" "unknown")])
21288
21289 (define_expand "sse_prologue_save"
21290   [(parallel [(set (match_operand:BLK 0 "" "")
21291                    (unspec:BLK [(reg:DI 21)
21292                                 (reg:DI 22)
21293                                 (reg:DI 23)
21294                                 (reg:DI 24)
21295                                 (reg:DI 25)
21296                                 (reg:DI 26)
21297                                 (reg:DI 27)
21298                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21299               (use (match_operand:DI 1 "register_operand" ""))
21300               (use (match_operand:DI 2 "immediate_operand" ""))
21301               (use (label_ref:DI (match_operand 3 "" "")))])]
21302   "TARGET_64BIT"
21303   "")
21304
21305 (define_insn "*sse_prologue_save_insn"
21306   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21307                           (match_operand:DI 4 "const_int_operand" "n")))
21308         (unspec:BLK [(reg:DI 21)
21309                      (reg:DI 22)
21310                      (reg:DI 23)
21311                      (reg:DI 24)
21312                      (reg:DI 25)
21313                      (reg:DI 26)
21314                      (reg:DI 27)
21315                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21316    (use (match_operand:DI 1 "register_operand" "r"))
21317    (use (match_operand:DI 2 "const_int_operand" "i"))
21318    (use (label_ref:DI (match_operand 3 "" "X")))]
21319   "TARGET_64BIT
21320    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
21321    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21322   "*
21323 {
21324   int i;
21325   operands[0] = gen_rtx_MEM (Pmode,
21326                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21327   output_asm_insn (\"jmp\\t%A1\", operands);
21328   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21329     {
21330       operands[4] = adjust_address (operands[0], DImode, i*16);
21331       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21332       PUT_MODE (operands[4], TImode);
21333       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21334         output_asm_insn (\"rex\", operands);
21335       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21336     }
21337   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21338                              CODE_LABEL_NUMBER (operands[3]));
21339   RET;
21340 }
21341   "
21342   [(set_attr "type" "other")
21343    (set_attr "length_immediate" "0")
21344    (set_attr "length_address" "0")
21345    (set_attr "length" "135")
21346    (set_attr "memory" "store")
21347    (set_attr "modrm" "0")
21348    (set_attr "mode" "DI")])
21349
21350 ;; 3Dnow! instructions
21351
21352 (define_insn "addv2sf3"
21353   [(set (match_operand:V2SF 0 "register_operand" "=y")
21354         (plus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21355                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21356   "TARGET_3DNOW"
21357   "pfadd\\t{%2, %0|%0, %2}"
21358   [(set_attr "type" "mmxadd")
21359    (set_attr "mode" "V2SF")])
21360
21361 (define_insn "subv2sf3"
21362   [(set (match_operand:V2SF 0 "register_operand" "=y")
21363         (minus:V2SF (match_operand:V2SF 1 "register_operand" "0")
21364                     (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21365   "TARGET_3DNOW"
21366   "pfsub\\t{%2, %0|%0, %2}"
21367   [(set_attr "type" "mmxadd")
21368    (set_attr "mode" "V2SF")])
21369
21370 (define_insn "subrv2sf3"
21371   [(set (match_operand:V2SF 0 "register_operand" "=y")
21372         (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "ym")
21373                     (match_operand:V2SF 1 "register_operand" "0")))]
21374   "TARGET_3DNOW"
21375   "pfsubr\\t{%2, %0|%0, %2}"
21376   [(set_attr "type" "mmxadd")
21377    (set_attr "mode" "V2SF")])
21378
21379 (define_insn "gtv2sf3"
21380   [(set (match_operand:V2SI 0 "register_operand" "=y")
21381         (gt:V2SI (match_operand:V2SF 1 "register_operand" "0")
21382                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21383  "TARGET_3DNOW"
21384   "pfcmpgt\\t{%2, %0|%0, %2}"
21385   [(set_attr "type" "mmxcmp")
21386    (set_attr "mode" "V2SF")])
21387
21388 (define_insn "gev2sf3"
21389   [(set (match_operand:V2SI 0 "register_operand" "=y")
21390         (ge:V2SI (match_operand:V2SF 1 "register_operand" "0")
21391                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21392   "TARGET_3DNOW"
21393   "pfcmpge\\t{%2, %0|%0, %2}"
21394   [(set_attr "type" "mmxcmp")
21395    (set_attr "mode" "V2SF")])
21396
21397 (define_insn "eqv2sf3"
21398   [(set (match_operand:V2SI 0 "register_operand" "=y")
21399         (eq:V2SI (match_operand:V2SF 1 "register_operand" "0")
21400                  (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21401   "TARGET_3DNOW"
21402   "pfcmpeq\\t{%2, %0|%0, %2}"
21403   [(set_attr "type" "mmxcmp")
21404    (set_attr "mode" "V2SF")])
21405
21406 (define_insn "pfmaxv2sf3"
21407   [(set (match_operand:V2SF 0 "register_operand" "=y")
21408         (smax:V2SF (match_operand:V2SF 1 "register_operand" "0")
21409                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21410   "TARGET_3DNOW"
21411   "pfmax\\t{%2, %0|%0, %2}"
21412   [(set_attr "type" "mmxadd")
21413    (set_attr "mode" "V2SF")])
21414
21415 (define_insn "pfminv2sf3"
21416   [(set (match_operand:V2SF 0 "register_operand" "=y")
21417         (smin:V2SF (match_operand:V2SF 1 "register_operand" "0")
21418                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21419   "TARGET_3DNOW"
21420   "pfmin\\t{%2, %0|%0, %2}"
21421   [(set_attr "type" "mmxadd")
21422    (set_attr "mode" "V2SF")])
21423
21424 (define_insn "mulv2sf3"
21425   [(set (match_operand:V2SF 0 "register_operand" "=y")
21426         (mult:V2SF (match_operand:V2SF 1 "register_operand" "0")
21427                    (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
21428   "TARGET_3DNOW"
21429   "pfmul\\t{%2, %0|%0, %2}"
21430   [(set_attr "type" "mmxmul")
21431    (set_attr "mode" "V2SF")])
21432
21433 (define_insn "femms"
21434   [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
21435    (clobber (reg:XF 8))
21436    (clobber (reg:XF 9))
21437    (clobber (reg:XF 10))
21438    (clobber (reg:XF 11))
21439    (clobber (reg:XF 12))
21440    (clobber (reg:XF 13))
21441    (clobber (reg:XF 14))
21442    (clobber (reg:XF 15))
21443    (clobber (reg:DI 29))
21444    (clobber (reg:DI 30))
21445    (clobber (reg:DI 31))
21446    (clobber (reg:DI 32))
21447    (clobber (reg:DI 33))
21448    (clobber (reg:DI 34))
21449    (clobber (reg:DI 35))
21450    (clobber (reg:DI 36))]
21451   "TARGET_3DNOW"
21452   "femms"
21453   [(set_attr "type" "mmx")
21454    (set_attr "memory" "none")]) 
21455
21456 (define_insn "pf2id"
21457   [(set (match_operand:V2SI 0 "register_operand" "=y")
21458         (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))]
21459   "TARGET_3DNOW"
21460   "pf2id\\t{%1, %0|%0, %1}"
21461   [(set_attr "type" "mmxcvt")
21462    (set_attr "mode" "V2SF")])
21463
21464 (define_insn "pf2iw"
21465   [(set (match_operand:V2SI 0 "register_operand" "=y")
21466         (sign_extend:V2SI
21467            (ss_truncate:V2HI
21468               (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))]
21469   "TARGET_3DNOW_A"
21470   "pf2iw\\t{%1, %0|%0, %1}"
21471   [(set_attr "type" "mmxcvt")
21472    (set_attr "mode" "V2SF")])
21473
21474 (define_insn "pfacc"
21475   [(set (match_operand:V2SF 0 "register_operand" "=y")
21476         (vec_concat:V2SF
21477            (plus:SF
21478               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21479                              (parallel [(const_int  0)]))
21480               (vec_select:SF (match_dup 1)
21481                              (parallel [(const_int 1)])))
21482            (plus:SF
21483               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21484                              (parallel [(const_int  0)]))
21485               (vec_select:SF (match_dup 2)
21486                              (parallel [(const_int 1)])))))]
21487   "TARGET_3DNOW"
21488   "pfacc\\t{%2, %0|%0, %2}"
21489   [(set_attr "type" "mmxadd")
21490    (set_attr "mode" "V2SF")])
21491
21492 (define_insn "pfnacc"
21493   [(set (match_operand:V2SF 0 "register_operand" "=y")
21494         (vec_concat:V2SF
21495            (minus:SF
21496               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21497                              (parallel [(const_int 0)]))
21498               (vec_select:SF (match_dup 1)
21499                              (parallel [(const_int 1)])))
21500            (minus:SF
21501               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21502                              (parallel [(const_int  0)]))
21503               (vec_select:SF (match_dup 2)
21504                              (parallel [(const_int 1)])))))]
21505   "TARGET_3DNOW_A"
21506   "pfnacc\\t{%2, %0|%0, %2}"
21507   [(set_attr "type" "mmxadd")
21508    (set_attr "mode" "V2SF")])
21509
21510 (define_insn "pfpnacc"
21511   [(set (match_operand:V2SF 0 "register_operand" "=y")
21512         (vec_concat:V2SF
21513            (minus:SF
21514               (vec_select:SF (match_operand:V2SF 1 "register_operand" "0")
21515                              (parallel [(const_int 0)]))
21516               (vec_select:SF (match_dup 1)
21517                              (parallel [(const_int 1)])))
21518            (plus:SF
21519               (vec_select:SF (match_operand:V2SF 2 "nonimmediate_operand" "y")
21520                              (parallel [(const_int 0)]))
21521               (vec_select:SF (match_dup 2)
21522                              (parallel [(const_int 1)])))))]
21523   "TARGET_3DNOW_A"
21524   "pfpnacc\\t{%2, %0|%0, %2}"
21525   [(set_attr "type" "mmxadd")
21526    (set_attr "mode" "V2SF")])
21527
21528 (define_insn "pi2fw"
21529   [(set (match_operand:V2SF 0 "register_operand" "=y")
21530         (float:V2SF
21531            (vec_concat:V2SI
21532               (sign_extend:SI
21533                  (truncate:HI
21534                     (vec_select:SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21535                                    (parallel [(const_int 0)]))))
21536               (sign_extend:SI
21537                  (truncate:HI
21538                     (vec_select:SI (match_dup 1)
21539                                    (parallel [(const_int  1)])))))))]
21540   "TARGET_3DNOW_A"
21541   "pi2fw\\t{%1, %0|%0, %1}"
21542   [(set_attr "type" "mmxcvt")
21543    (set_attr "mode" "V2SF")])
21544
21545 (define_insn "floatv2si2"
21546   [(set (match_operand:V2SF 0 "register_operand" "=y")
21547         (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
21548   "TARGET_3DNOW"
21549   "pi2fd\\t{%1, %0|%0, %1}"
21550   [(set_attr "type" "mmxcvt")
21551    (set_attr "mode" "V2SF")])
21552
21553 ;; This insn is identical to pavgb in operation, but the opcode is
21554 ;; different.  To avoid accidentally matching pavgb, use an unspec.
21555
21556 (define_insn "pavgusb"
21557  [(set (match_operand:V8QI 0 "register_operand" "=y")
21558        (unspec:V8QI
21559           [(match_operand:V8QI 1 "register_operand" "0")
21560            (match_operand:V8QI 2 "nonimmediate_operand" "ym")]
21561           UNSPEC_PAVGUSB))]
21562   "TARGET_3DNOW"
21563   "pavgusb\\t{%2, %0|%0, %2}"
21564   [(set_attr "type" "mmxshft")
21565    (set_attr "mode" "TI")])
21566
21567 ;; 3DNow reciprocal and sqrt
21568  
21569 (define_insn "pfrcpv2sf2"
21570   [(set (match_operand:V2SF 0 "register_operand" "=y")
21571         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21572         UNSPEC_PFRCP))]
21573   "TARGET_3DNOW"
21574   "pfrcp\\t{%1, %0|%0, %1}"
21575   [(set_attr "type" "mmx")
21576    (set_attr "mode" "TI")])
21577
21578 (define_insn "pfrcpit1v2sf3"
21579   [(set (match_operand:V2SF 0 "register_operand" "=y")
21580         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21581                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21582                      UNSPEC_PFRCPIT1))]
21583   "TARGET_3DNOW"
21584   "pfrcpit1\\t{%2, %0|%0, %2}"
21585   [(set_attr "type" "mmx")
21586    (set_attr "mode" "TI")])
21587
21588 (define_insn "pfrcpit2v2sf3"
21589   [(set (match_operand:V2SF 0 "register_operand" "=y")
21590         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21591                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21592                      UNSPEC_PFRCPIT2))]
21593   "TARGET_3DNOW"
21594   "pfrcpit2\\t{%2, %0|%0, %2}"
21595   [(set_attr "type" "mmx")
21596    (set_attr "mode" "TI")])
21597
21598 (define_insn "pfrsqrtv2sf2"
21599   [(set (match_operand:V2SF 0 "register_operand" "=y")
21600         (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")]
21601                      UNSPEC_PFRSQRT))]
21602   "TARGET_3DNOW"
21603   "pfrsqrt\\t{%1, %0|%0, %1}"
21604   [(set_attr "type" "mmx")
21605    (set_attr "mode" "TI")])
21606                 
21607 (define_insn "pfrsqit1v2sf3"
21608   [(set (match_operand:V2SF 0 "register_operand" "=y")
21609         (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0")
21610                       (match_operand:V2SF 2 "nonimmediate_operand" "ym")]
21611                      UNSPEC_PFRSQIT1))]
21612   "TARGET_3DNOW"
21613   "pfrsqit1\\t{%2, %0|%0, %2}"
21614   [(set_attr "type" "mmx")
21615    (set_attr "mode" "TI")])
21616
21617 (define_insn "pmulhrwv4hi3"
21618   [(set (match_operand:V4HI 0 "register_operand" "=y")
21619         (truncate:V4HI
21620            (lshiftrt:V4SI
21621               (plus:V4SI
21622                  (mult:V4SI
21623                     (sign_extend:V4SI
21624                        (match_operand:V4HI 1 "register_operand" "0"))
21625                     (sign_extend:V4SI
21626                        (match_operand:V4HI 2 "nonimmediate_operand" "ym")))
21627                  (const_vector:V4SI [(const_int 32768)
21628                                      (const_int 32768)
21629                                      (const_int 32768)
21630                                      (const_int 32768)]))
21631               (const_int 16))))]
21632   "TARGET_3DNOW"
21633   "pmulhrw\\t{%2, %0|%0, %2}"
21634   [(set_attr "type" "mmxmul")
21635    (set_attr "mode" "TI")])
21636
21637 (define_insn "pswapdv2si2"
21638   [(set (match_operand:V2SI 0 "register_operand" "=y")
21639         (vec_select:V2SI (match_operand:V2SI 1 "nonimmediate_operand" "ym")
21640                          (parallel [(const_int 1) (const_int 0)])))]
21641   "TARGET_3DNOW_A"
21642   "pswapd\\t{%1, %0|%0, %1}"
21643   [(set_attr "type" "mmxcvt")
21644    (set_attr "mode" "TI")])
21645
21646 (define_insn "pswapdv2sf2"
21647   [(set (match_operand:V2SF 0 "register_operand" "=y")
21648         (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym")
21649                          (parallel [(const_int 1) (const_int 0)])))]
21650   "TARGET_3DNOW_A"
21651   "pswapd\\t{%1, %0|%0, %1}"
21652   [(set_attr "type" "mmxcvt")
21653    (set_attr "mode" "TI")])
21654
21655 (define_expand "prefetch"
21656   [(prefetch (match_operand 0 "address_operand" "")
21657              (match_operand:SI 1 "const_int_operand" "")
21658              (match_operand:SI 2 "const_int_operand" ""))]
21659   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21660 {
21661   int rw = INTVAL (operands[1]);
21662   int locality = INTVAL (operands[2]);
21663
21664   if (rw != 0 && rw != 1)
21665     abort ();
21666   if (locality < 0 || locality > 3)
21667     abort ();
21668   if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
21669     abort ();
21670
21671   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21672      suported by SSE counterpart or the SSE prefetch is not available
21673      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21674      of locality.  */
21675   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21676     operands[2] = GEN_INT (3);
21677   else
21678     operands[1] = const0_rtx;
21679 })
21680
21681 (define_insn "*prefetch_sse"
21682   [(prefetch (match_operand:SI 0 "address_operand" "p")
21683              (const_int 0)
21684              (match_operand:SI 1 "const_int_operand" ""))]
21685   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21686 {
21687   static const char * const patterns[4] = {
21688    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21689   };
21690
21691   int locality = INTVAL (operands[1]);
21692   if (locality < 0 || locality > 3)
21693     abort ();
21694
21695   return patterns[locality];  
21696 }
21697   [(set_attr "type" "sse")
21698    (set_attr "memory" "none")])
21699
21700 (define_insn "*prefetch_sse_rex"
21701   [(prefetch (match_operand:DI 0 "address_operand" "p")
21702              (const_int 0)
21703              (match_operand:SI 1 "const_int_operand" ""))]
21704   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21705 {
21706   static const char * const patterns[4] = {
21707    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21708   };
21709
21710   int locality = INTVAL (operands[1]);
21711   if (locality < 0 || locality > 3)
21712     abort ();
21713
21714   return patterns[locality];  
21715 }
21716   [(set_attr "type" "sse")
21717    (set_attr "memory" "none")])
21718
21719 (define_insn "*prefetch_3dnow"
21720   [(prefetch (match_operand:SI 0 "address_operand" "p")
21721              (match_operand:SI 1 "const_int_operand" "n")
21722              (const_int 3))]
21723   "TARGET_3DNOW && !TARGET_64BIT"
21724 {
21725   if (INTVAL (operands[1]) == 0)
21726     return "prefetch\t%a0";
21727   else
21728     return "prefetchw\t%a0";
21729 }
21730   [(set_attr "type" "mmx")
21731    (set_attr "memory" "none")])
21732
21733 (define_insn "*prefetch_3dnow_rex"
21734   [(prefetch (match_operand:DI 0 "address_operand" "p")
21735              (match_operand:SI 1 "const_int_operand" "n")
21736              (const_int 3))]
21737   "TARGET_3DNOW && TARGET_64BIT"
21738 {
21739   if (INTVAL (operands[1]) == 0)
21740     return "prefetch\t%a0";
21741   else
21742     return "prefetchw\t%a0";
21743 }
21744   [(set_attr "type" "mmx")
21745    (set_attr "memory" "none")])
21746
21747 ;; SSE2 support
21748
21749 (define_insn "addv2df3"
21750   [(set (match_operand:V2DF 0 "register_operand" "=x")
21751         (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21752                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21753   "TARGET_SSE2"
21754   "addpd\t{%2, %0|%0, %2}"
21755   [(set_attr "type" "sseadd")
21756    (set_attr "mode" "V2DF")])
21757
21758 (define_insn "vmaddv2df3"
21759   [(set (match_operand:V2DF 0 "register_operand" "=x")
21760         (vec_merge:V2DF (plus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21761                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21762                         (match_dup 1)
21763                         (const_int 1)))]
21764   "TARGET_SSE2"
21765   "addsd\t{%2, %0|%0, %2}"
21766   [(set_attr "type" "sseadd")
21767    (set_attr "mode" "DF")])
21768
21769 (define_insn "subv2df3"
21770   [(set (match_operand:V2DF 0 "register_operand" "=x")
21771         (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21772                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21773   "TARGET_SSE2"
21774   "subpd\t{%2, %0|%0, %2}"
21775   [(set_attr "type" "sseadd")
21776    (set_attr "mode" "V2DF")])
21777
21778 (define_insn "vmsubv2df3"
21779   [(set (match_operand:V2DF 0 "register_operand" "=x")
21780         (vec_merge:V2DF (minus:V2DF (match_operand:V2DF 1 "register_operand" "0")
21781                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21782                         (match_dup 1)
21783                         (const_int 1)))]
21784   "TARGET_SSE2"
21785   "subsd\t{%2, %0|%0, %2}"
21786   [(set_attr "type" "sseadd")
21787    (set_attr "mode" "DF")])
21788
21789 (define_insn "mulv2df3"
21790   [(set (match_operand:V2DF 0 "register_operand" "=x")
21791         (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21792                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21793   "TARGET_SSE2"
21794   "mulpd\t{%2, %0|%0, %2}"
21795   [(set_attr "type" "ssemul")
21796    (set_attr "mode" "V2DF")])
21797
21798 (define_insn "vmmulv2df3"
21799   [(set (match_operand:V2DF 0 "register_operand" "=x")
21800         (vec_merge:V2DF (mult:V2DF (match_operand:V2DF 1 "register_operand" "0")
21801                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21802                         (match_dup 1)
21803                         (const_int 1)))]
21804   "TARGET_SSE2"
21805   "mulsd\t{%2, %0|%0, %2}"
21806   [(set_attr "type" "ssemul")
21807    (set_attr "mode" "DF")])
21808
21809 (define_insn "divv2df3"
21810   [(set (match_operand:V2DF 0 "register_operand" "=x")
21811         (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21812                   (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21813   "TARGET_SSE2"
21814   "divpd\t{%2, %0|%0, %2}"
21815   [(set_attr "type" "ssediv")
21816    (set_attr "mode" "V2DF")])
21817
21818 (define_insn "vmdivv2df3"
21819   [(set (match_operand:V2DF 0 "register_operand" "=x")
21820         (vec_merge:V2DF (div:V2DF (match_operand:V2DF 1 "register_operand" "0")
21821                                   (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21822                         (match_dup 1)
21823                         (const_int 1)))]
21824   "TARGET_SSE2"
21825   "divsd\t{%2, %0|%0, %2}"
21826   [(set_attr "type" "ssediv")
21827    (set_attr "mode" "DF")])
21828
21829 ;; SSE min/max
21830
21831 (define_insn "smaxv2df3"
21832   [(set (match_operand:V2DF 0 "register_operand" "=x")
21833         (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21834                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21835   "TARGET_SSE2"
21836   "maxpd\t{%2, %0|%0, %2}"
21837   [(set_attr "type" "sseadd")
21838    (set_attr "mode" "V2DF")])
21839
21840 (define_insn "vmsmaxv2df3"
21841   [(set (match_operand:V2DF 0 "register_operand" "=x")
21842         (vec_merge:V2DF (smax:V2DF (match_operand:V2DF 1 "register_operand" "0")
21843                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21844                         (match_dup 1)
21845                         (const_int 1)))]
21846   "TARGET_SSE2"
21847   "maxsd\t{%2, %0|%0, %2}"
21848   [(set_attr "type" "sseadd")
21849    (set_attr "mode" "DF")])
21850
21851 (define_insn "sminv2df3"
21852   [(set (match_operand:V2DF 0 "register_operand" "=x")
21853         (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21854                    (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
21855   "TARGET_SSE2"
21856   "minpd\t{%2, %0|%0, %2}"
21857   [(set_attr "type" "sseadd")
21858    (set_attr "mode" "V2DF")])
21859
21860 (define_insn "vmsminv2df3"
21861   [(set (match_operand:V2DF 0 "register_operand" "=x")
21862         (vec_merge:V2DF (smin:V2DF (match_operand:V2DF 1 "register_operand" "0")
21863                                    (match_operand:V2DF 2 "nonimmediate_operand" "xm"))
21864                         (match_dup 1)
21865                         (const_int 1)))]
21866   "TARGET_SSE2"
21867   "minsd\t{%2, %0|%0, %2}"
21868   [(set_attr "type" "sseadd")
21869    (set_attr "mode" "DF")])
21870 ;; SSE2 square root.  There doesn't appear to be an extension for the
21871 ;; reciprocal/rsqrt instructions if the Intel manual is to be believed.
21872
21873 (define_insn "sqrtv2df2"
21874   [(set (match_operand:V2DF 0 "register_operand" "=x")
21875         (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm")))]
21876   "TARGET_SSE2"
21877   "sqrtpd\t{%1, %0|%0, %1}"
21878   [(set_attr "type" "sse")
21879    (set_attr "mode" "V2DF")])
21880
21881 (define_insn "vmsqrtv2df2"
21882   [(set (match_operand:V2DF 0 "register_operand" "=x")
21883         (vec_merge:V2DF (sqrt:V2DF (match_operand:V2DF 1 "register_operand" "xm"))
21884                         (match_operand:V2DF 2 "register_operand" "0")
21885                         (const_int 1)))]
21886   "TARGET_SSE2"
21887   "sqrtsd\t{%1, %0|%0, %1}"
21888   [(set_attr "type" "sse")
21889    (set_attr "mode" "SF")])
21890
21891 ;; SSE mask-generating compares
21892
21893 (define_insn "maskcmpv2df3"
21894   [(set (match_operand:V2DI 0 "register_operand" "=x")
21895         (match_operator:V2DI 3 "sse_comparison_operator"
21896                              [(match_operand:V2DF 1 "register_operand" "0")
21897                               (match_operand:V2DF 2 "nonimmediate_operand" "x")]))]
21898   "TARGET_SSE2"
21899   "cmp%D3pd\t{%2, %0|%0, %2}"
21900   [(set_attr "type" "ssecmp")
21901    (set_attr "mode" "V2DF")])
21902
21903 (define_insn "maskncmpv2df3"
21904   [(set (match_operand:V2DI 0 "register_operand" "=x")
21905         (not:V2DI
21906          (match_operator:V2DI 3 "sse_comparison_operator"
21907                               [(match_operand:V2DF 1 "register_operand" "0")
21908                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])))]
21909   "TARGET_SSE2"
21910 {
21911   if (GET_CODE (operands[3]) == UNORDERED)
21912     return "cmpordps\t{%2, %0|%0, %2}";
21913   else
21914     return "cmpn%D3pd\t{%2, %0|%0, %2}";
21915 }
21916   [(set_attr "type" "ssecmp")
21917    (set_attr "mode" "V2DF")])
21918
21919 (define_insn "vmmaskcmpv2df3"
21920   [(set (match_operand:V2DI 0 "register_operand" "=x")
21921         (vec_merge:V2DI
21922          (match_operator:V2DI 3 "sse_comparison_operator"
21923                               [(match_operand:V2DF 1 "register_operand" "0")
21924                                (match_operand:V2DF 2 "nonimmediate_operand" "x")])
21925          (subreg:V2DI (match_dup 1) 0)
21926          (const_int 1)))]
21927   "TARGET_SSE2"
21928   "cmp%D3sd\t{%2, %0|%0, %2}"
21929   [(set_attr "type" "ssecmp")
21930    (set_attr "mode" "DF")])
21931
21932 (define_insn "vmmaskncmpv2df3"
21933   [(set (match_operand:V2DI 0 "register_operand" "=x")
21934         (vec_merge:V2DI
21935          (not:V2DI
21936           (match_operator:V2DI 3 "sse_comparison_operator"
21937                                [(match_operand:V2DF 1 "register_operand" "0")
21938                                 (match_operand:V2DF 2 "nonimmediate_operand" "x")]))
21939          (subreg:V2DI (match_dup 1) 0)
21940          (const_int 1)))]
21941   "TARGET_SSE2"
21942 {
21943   if (GET_CODE (operands[3]) == UNORDERED)
21944     return "cmpordsd\t{%2, %0|%0, %2}";
21945   else
21946     return "cmpn%D3sd\t{%2, %0|%0, %2}";
21947 }
21948   [(set_attr "type" "ssecmp")
21949    (set_attr "mode" "DF")])
21950
21951 (define_insn "sse2_comi"
21952   [(set (reg:CCFP 17)
21953         (compare:CCFP (vec_select:DF
21954                        (match_operand:V2DF 0 "register_operand" "x")
21955                        (parallel [(const_int 0)]))
21956                       (vec_select:DF
21957                        (match_operand:V2DF 1 "register_operand" "x")
21958                        (parallel [(const_int 0)]))))]
21959   "TARGET_SSE2"
21960   "comisd\t{%1, %0|%0, %1}"
21961   [(set_attr "type" "ssecomi")
21962    (set_attr "mode" "DF")])
21963
21964 (define_insn "sse2_ucomi"
21965   [(set (reg:CCFPU 17)
21966         (compare:CCFPU (vec_select:DF
21967                          (match_operand:V2DF 0 "register_operand" "x")
21968                          (parallel [(const_int 0)]))
21969                         (vec_select:DF
21970                          (match_operand:V2DF 1 "register_operand" "x")
21971                          (parallel [(const_int 0)]))))]
21972   "TARGET_SSE2"
21973   "ucomisd\t{%1, %0|%0, %1}"
21974   [(set_attr "type" "ssecomi")
21975    (set_attr "mode" "DF")])
21976
21977 ;; SSE Strange Moves.
21978
21979 (define_insn "sse2_movmskpd"
21980   [(set (match_operand:SI 0 "register_operand" "=r")
21981         (unspec:SI [(match_operand:V2DF 1 "register_operand" "x")]
21982                    UNSPEC_MOVMSK))]
21983   "TARGET_SSE2"
21984   "movmskpd\t{%1, %0|%0, %1}"
21985   [(set_attr "type" "ssecvt")
21986    (set_attr "mode" "V2DF")])
21987
21988 (define_insn "sse2_pmovmskb"
21989   [(set (match_operand:SI 0 "register_operand" "=r")
21990         (unspec:SI [(match_operand:V16QI 1 "register_operand" "x")]
21991                    UNSPEC_MOVMSK))]
21992   "TARGET_SSE2"
21993   "pmovmskb\t{%1, %0|%0, %1}"
21994   [(set_attr "type" "ssecvt")
21995    (set_attr "mode" "V2DF")])
21996
21997 (define_insn "sse2_maskmovdqu"
21998   [(set (mem:V16QI (match_operand:SI 0 "register_operand" "D"))
21999         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22000                        (match_operand:V16QI 2 "register_operand" "x")]
22001                       UNSPEC_MASKMOV))]
22002   "TARGET_SSE2"
22003   ;; @@@ check ordering of operands in intel/nonintel syntax
22004   "maskmovdqu\t{%2, %1|%1, %2}"
22005   [(set_attr "type" "ssecvt")
22006    (set_attr "mode" "TI")])
22007
22008 (define_insn "sse2_maskmovdqu_rex64"
22009   [(set (mem:V16QI (match_operand:DI 0 "register_operand" "D"))
22010         (unspec:V16QI [(match_operand:V16QI 1 "register_operand" "x")
22011                        (match_operand:V16QI 2 "register_operand" "x")]
22012                       UNSPEC_MASKMOV))]
22013   "TARGET_SSE2"
22014   ;; @@@ check ordering of operands in intel/nonintel syntax
22015   "maskmovdqu\t{%2, %1|%1, %2}"
22016   [(set_attr "type" "ssecvt")
22017    (set_attr "mode" "TI")])
22018
22019 (define_insn "sse2_movntv2df"
22020   [(set (match_operand:V2DF 0 "memory_operand" "=m")
22021         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "x")]
22022                      UNSPEC_MOVNT))]
22023   "TARGET_SSE2"
22024   "movntpd\t{%1, %0|%0, %1}"
22025   [(set_attr "type" "ssecvt")
22026    (set_attr "mode" "V2DF")])
22027
22028 (define_insn "sse2_movntv2di"
22029   [(set (match_operand:V2DI 0 "memory_operand" "=m")
22030         (unspec:V2DI [(match_operand:V2DI 1 "register_operand" "x")]
22031                      UNSPEC_MOVNT))]
22032   "TARGET_SSE2"
22033   "movntdq\t{%1, %0|%0, %1}"
22034   [(set_attr "type" "ssecvt")
22035    (set_attr "mode" "TI")])
22036
22037 (define_insn "sse2_movntsi"
22038   [(set (match_operand:SI 0 "memory_operand" "=m")
22039         (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
22040                    UNSPEC_MOVNT))]
22041   "TARGET_SSE2"
22042   "movnti\t{%1, %0|%0, %1}"
22043   [(set_attr "type" "ssecvt")
22044    (set_attr "mode" "V2DF")])
22045
22046 ;; SSE <-> integer/MMX conversions
22047
22048 ;; Conversions between SI and SF
22049
22050 (define_insn "cvtdq2ps"
22051   [(set (match_operand:V4SF 0 "register_operand" "=x")
22052         (float:V4SF (match_operand:V4SI 1 "nonimmediate_operand" "xm")))]
22053   "TARGET_SSE2"
22054   "cvtdq2ps\t{%1, %0|%0, %1}"
22055   [(set_attr "type" "ssecvt")
22056    (set_attr "mode" "V2DF")])
22057
22058 (define_insn "cvtps2dq"
22059   [(set (match_operand:V4SI 0 "register_operand" "=x")
22060         (fix:V4SI (match_operand:V4SF 1 "nonimmediate_operand" "xm")))]
22061   "TARGET_SSE2"
22062   "cvtps2dq\t{%1, %0|%0, %1}"
22063   [(set_attr "type" "ssecvt")
22064    (set_attr "mode" "TI")])
22065
22066 (define_insn "cvttps2dq"
22067   [(set (match_operand:V4SI 0 "register_operand" "=x")
22068         (unspec:V4SI [(match_operand:V4SF 1 "nonimmediate_operand" "xm")]
22069                      UNSPEC_FIX))]
22070   "TARGET_SSE2"
22071   "cvttps2dq\t{%1, %0|%0, %1}"
22072   [(set_attr "type" "ssecvt")
22073    (set_attr "mode" "TI")])
22074
22075 ;; Conversions between SI and DF
22076
22077 (define_insn "cvtdq2pd"
22078   [(set (match_operand:V2DF 0 "register_operand" "=x")
22079         (float:V2DF (vec_select:V2SI
22080                      (match_operand:V4SI 1 "nonimmediate_operand" "xm")
22081                      (parallel
22082                       [(const_int 0)
22083                        (const_int 1)]))))]
22084   "TARGET_SSE2"
22085   "cvtdq2pd\t{%1, %0|%0, %1}"
22086   [(set_attr "type" "ssecvt")
22087    (set_attr "mode" "V2DF")])
22088
22089 (define_insn "cvtpd2dq"
22090   [(set (match_operand:V4SI 0 "register_operand" "=x")
22091         (vec_concat:V4SI
22092          (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm"))
22093          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22094   "TARGET_SSE2"
22095   "cvtpd2dq\t{%1, %0|%0, %1}"
22096   [(set_attr "type" "ssecvt")
22097    (set_attr "mode" "TI")])
22098
22099 (define_insn "cvttpd2dq"
22100   [(set (match_operand:V4SI 0 "register_operand" "=x")
22101         (vec_concat:V4SI
22102          (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22103                       UNSPEC_FIX)
22104          (const_vector:V2SI [(const_int 0) (const_int 0)])))]
22105   "TARGET_SSE2"
22106   "cvttpd2dq\t{%1, %0|%0, %1}"
22107   [(set_attr "type" "ssecvt")
22108    (set_attr "mode" "TI")])
22109
22110 (define_insn "cvtpd2pi"
22111   [(set (match_operand:V2SI 0 "register_operand" "=y")
22112         (fix:V2SI (match_operand:V2DF 1 "nonimmediate_operand" "xm")))]
22113   "TARGET_SSE2"
22114   "cvtpd2pi\t{%1, %0|%0, %1}"
22115   [(set_attr "type" "ssecvt")
22116    (set_attr "mode" "TI")])
22117
22118 (define_insn "cvttpd2pi"
22119   [(set (match_operand:V2SI 0 "register_operand" "=y")
22120         (unspec:V2SI [(match_operand:V2DF 1 "nonimmediate_operand" "xm")]
22121                      UNSPEC_FIX))]
22122   "TARGET_SSE2"
22123   "cvttpd2pi\t{%1, %0|%0, %1}"
22124   [(set_attr "type" "ssecvt")
22125    (set_attr "mode" "TI")])
22126
22127 (define_insn "cvtpi2pd"
22128   [(set (match_operand:V2DF 0 "register_operand" "=x")
22129         (float:V2DF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))]
22130   "TARGET_SSE2"
22131   "cvtpi2pd\t{%1, %0|%0, %1}"
22132   [(set_attr "type" "ssecvt")
22133    (set_attr "mode" "TI")])
22134
22135 ;; Conversions between SI and DF
22136
22137 (define_insn "cvtsd2si"
22138   [(set (match_operand:SI 0 "register_operand" "=r,r")
22139         (fix:SI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22140                                (parallel [(const_int 0)]))))]
22141   "TARGET_SSE2"
22142   "cvtsd2si\t{%1, %0|%0, %1}"
22143   [(set_attr "type" "sseicvt")
22144    (set_attr "athlon_decode" "double,vector")
22145    (set_attr "mode" "SI")])
22146
22147 (define_insn "cvtsd2siq"
22148   [(set (match_operand:DI 0 "register_operand" "=r,r")
22149         (fix:DI (vec_select:DF (match_operand:V2DF 1 "register_operand" "x,m")
22150                                (parallel [(const_int 0)]))))]
22151   "TARGET_SSE2 && TARGET_64BIT"
22152   "cvtsd2siq\t{%1, %0|%0, %1}"
22153   [(set_attr "type" "sseicvt")
22154    (set_attr "athlon_decode" "double,vector")
22155    (set_attr "mode" "DI")])
22156
22157 (define_insn "cvttsd2si"
22158   [(set (match_operand:SI 0 "register_operand" "=r,r")
22159         (unspec:SI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22160                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
22161   "TARGET_SSE2"
22162   "cvttsd2si\t{%1, %0|%0, %1}"
22163   [(set_attr "type" "sseicvt")
22164    (set_attr "mode" "SI")
22165    (set_attr "athlon_decode" "double,vector")])
22166
22167 (define_insn "cvttsd2siq"
22168   [(set (match_operand:DI 0 "register_operand" "=r,r")
22169         (unspec:DI [(vec_select:DF (match_operand:V2DF 1 "register_operand" "x,xm")
22170                                    (parallel [(const_int 0)]))] UNSPEC_FIX))]
22171   "TARGET_SSE2 && TARGET_64BIT"
22172   "cvttsd2siq\t{%1, %0|%0, %1}"
22173   [(set_attr "type" "sseicvt")
22174    (set_attr "mode" "DI")
22175    (set_attr "athlon_decode" "double,vector")])
22176
22177 (define_insn "cvtsi2sd"
22178   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22179         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22180                         (vec_duplicate:V2DF
22181                           (float:DF
22182                             (match_operand:SI 2 "nonimmediate_operand" "r,rm")))
22183                         (const_int 2)))]
22184   "TARGET_SSE2"
22185   "cvtsi2sd\t{%2, %0|%0, %2}"
22186   [(set_attr "type" "sseicvt")
22187    (set_attr "mode" "DF")
22188    (set_attr "athlon_decode" "double,direct")])
22189
22190 (define_insn "cvtsi2sdq"
22191   [(set (match_operand:V2DF 0 "register_operand" "=x,x")
22192         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0,0")
22193                         (vec_duplicate:V2DF
22194                           (float:DF
22195                             (match_operand:DI 2 "nonimmediate_operand" "r,rm")))
22196                         (const_int 2)))]
22197   "TARGET_SSE2 && TARGET_64BIT"
22198   "cvtsi2sdq\t{%2, %0|%0, %2}"
22199   [(set_attr "type" "sseicvt")
22200    (set_attr "mode" "DF")
22201    (set_attr "athlon_decode" "double,direct")])
22202
22203 ;; Conversions between SF and DF
22204
22205 (define_insn "cvtsd2ss"
22206   [(set (match_operand:V4SF 0 "register_operand" "=x,x")
22207         (vec_merge:V4SF (match_operand:V4SF 1 "register_operand" "0,0")
22208                         (vec_duplicate:V4SF
22209                           (float_truncate:V2SF
22210                             (match_operand:V2DF 2 "nonimmediate_operand" "x,xm")))
22211                         (const_int 14)))]
22212   "TARGET_SSE2"
22213   "cvtsd2ss\t{%2, %0|%0, %2}"
22214   [(set_attr "type" "ssecvt")
22215    (set_attr "athlon_decode" "vector,double")
22216    (set_attr "mode" "SF")])
22217
22218 (define_insn "cvtss2sd"
22219   [(set (match_operand:V2DF 0 "register_operand" "=x")
22220         (vec_merge:V2DF (match_operand:V2DF 1 "register_operand" "0")
22221                         (float_extend:V2DF
22222                           (vec_select:V2SF
22223                             (match_operand:V4SF 2 "nonimmediate_operand" "xm")
22224                             (parallel [(const_int 0)
22225                                        (const_int 1)])))
22226                         (const_int 2)))]
22227   "TARGET_SSE2"
22228   "cvtss2sd\t{%2, %0|%0, %2}"
22229   [(set_attr "type" "ssecvt")
22230    (set_attr "mode" "DF")])
22231
22232 (define_insn "cvtpd2ps"
22233   [(set (match_operand:V4SF 0 "register_operand" "=x")
22234         (subreg:V4SF
22235           (vec_concat:V4SI
22236             (subreg:V2SI (float_truncate:V2SF
22237                            (match_operand:V2DF 1 "nonimmediate_operand" "xm")) 0)
22238             (const_vector:V2SI [(const_int 0) (const_int 0)])) 0))]
22239   "TARGET_SSE2"
22240   "cvtpd2ps\t{%1, %0|%0, %1}"
22241   [(set_attr "type" "ssecvt")
22242    (set_attr "mode" "V4SF")])
22243
22244 (define_insn "cvtps2pd"
22245   [(set (match_operand:V2DF 0 "register_operand" "=x")
22246         (float_extend:V2DF
22247           (vec_select:V2SF (match_operand:V4SF 1 "nonimmediate_operand" "xm")
22248                            (parallel [(const_int 0)
22249                                       (const_int 1)]))))]
22250   "TARGET_SSE2"
22251   "cvtps2pd\t{%1, %0|%0, %1}"
22252   [(set_attr "type" "ssecvt")
22253    (set_attr "mode" "V2DF")])
22254
22255 ;; SSE2 variants of MMX insns
22256
22257 ;; MMX arithmetic
22258
22259 (define_insn "addv16qi3"
22260   [(set (match_operand:V16QI 0 "register_operand" "=x")
22261         (plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22262                     (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22263   "TARGET_SSE2"
22264   "paddb\t{%2, %0|%0, %2}"
22265   [(set_attr "type" "sseiadd")
22266    (set_attr "mode" "TI")])
22267
22268 (define_insn "addv8hi3"
22269   [(set (match_operand:V8HI 0 "register_operand" "=x")
22270         (plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22271                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22272   "TARGET_SSE2"
22273   "paddw\t{%2, %0|%0, %2}"
22274   [(set_attr "type" "sseiadd")
22275    (set_attr "mode" "TI")])
22276
22277 (define_insn "addv4si3"
22278   [(set (match_operand:V4SI 0 "register_operand" "=x")
22279         (plus:V4SI (match_operand:V4SI 1 "register_operand" "%0")
22280                    (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22281   "TARGET_SSE2"
22282   "paddd\t{%2, %0|%0, %2}"
22283   [(set_attr "type" "sseiadd")
22284    (set_attr "mode" "TI")])
22285
22286 (define_insn "addv2di3"
22287   [(set (match_operand:V2DI 0 "register_operand" "=x")
22288         (plus:V2DI (match_operand:V2DI 1 "register_operand" "%0")
22289                    (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22290   "TARGET_SSE2"
22291   "paddq\t{%2, %0|%0, %2}"
22292   [(set_attr "type" "sseiadd")
22293    (set_attr "mode" "TI")])
22294
22295 (define_insn "ssaddv16qi3"
22296   [(set (match_operand:V16QI 0 "register_operand" "=x")
22297         (ss_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22298                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22299   "TARGET_SSE2"
22300   "paddsb\t{%2, %0|%0, %2}"
22301   [(set_attr "type" "sseiadd")
22302    (set_attr "mode" "TI")])
22303
22304 (define_insn "ssaddv8hi3"
22305   [(set (match_operand:V8HI 0 "register_operand" "=x")
22306         (ss_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22307                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22308   "TARGET_SSE2"
22309   "paddsw\t{%2, %0|%0, %2}"
22310   [(set_attr "type" "sseiadd")
22311    (set_attr "mode" "TI")])
22312
22313 (define_insn "usaddv16qi3"
22314   [(set (match_operand:V16QI 0 "register_operand" "=x")
22315         (us_plus:V16QI (match_operand:V16QI 1 "register_operand" "%0")
22316                        (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22317   "TARGET_SSE2"
22318   "paddusb\t{%2, %0|%0, %2}"
22319   [(set_attr "type" "sseiadd")
22320    (set_attr "mode" "TI")])
22321
22322 (define_insn "usaddv8hi3"
22323   [(set (match_operand:V8HI 0 "register_operand" "=x")
22324         (us_plus:V8HI (match_operand:V8HI 1 "register_operand" "%0")
22325                       (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22326   "TARGET_SSE2"
22327   "paddusw\t{%2, %0|%0, %2}"
22328   [(set_attr "type" "sseiadd")
22329    (set_attr "mode" "TI")])
22330
22331 (define_insn "subv16qi3"
22332   [(set (match_operand:V16QI 0 "register_operand" "=x")
22333         (minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22334                      (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22335   "TARGET_SSE2"
22336   "psubb\t{%2, %0|%0, %2}"
22337   [(set_attr "type" "sseiadd")
22338    (set_attr "mode" "TI")])
22339
22340 (define_insn "subv8hi3"
22341   [(set (match_operand:V8HI 0 "register_operand" "=x")
22342         (minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22343                     (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22344   "TARGET_SSE2"
22345   "psubw\t{%2, %0|%0, %2}"
22346   [(set_attr "type" "sseiadd")
22347    (set_attr "mode" "TI")])
22348
22349 (define_insn "subv4si3"
22350   [(set (match_operand:V4SI 0 "register_operand" "=x")
22351         (minus:V4SI (match_operand:V4SI 1 "register_operand" "0")
22352                     (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22353   "TARGET_SSE2"
22354   "psubd\t{%2, %0|%0, %2}"
22355   [(set_attr "type" "sseiadd")
22356    (set_attr "mode" "TI")])
22357
22358 (define_insn "subv2di3"
22359   [(set (match_operand:V2DI 0 "register_operand" "=x")
22360         (minus:V2DI (match_operand:V2DI 1 "register_operand" "0")
22361                     (match_operand:V2DI 2 "nonimmediate_operand" "xm")))]
22362   "TARGET_SSE2"
22363   "psubq\t{%2, %0|%0, %2}"
22364   [(set_attr "type" "sseiadd")
22365    (set_attr "mode" "TI")])
22366
22367 (define_insn "sssubv16qi3"
22368   [(set (match_operand:V16QI 0 "register_operand" "=x")
22369         (ss_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22370                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22371   "TARGET_SSE2"
22372   "psubsb\t{%2, %0|%0, %2}"
22373   [(set_attr "type" "sseiadd")
22374    (set_attr "mode" "TI")])
22375
22376 (define_insn "sssubv8hi3"
22377   [(set (match_operand:V8HI 0 "register_operand" "=x")
22378         (ss_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22379                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22380   "TARGET_SSE2"
22381   "psubsw\t{%2, %0|%0, %2}"
22382   [(set_attr "type" "sseiadd")
22383    (set_attr "mode" "TI")])
22384
22385 (define_insn "ussubv16qi3"
22386   [(set (match_operand:V16QI 0 "register_operand" "=x")
22387         (us_minus:V16QI (match_operand:V16QI 1 "register_operand" "0")
22388                         (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22389   "TARGET_SSE2"
22390   "psubusb\t{%2, %0|%0, %2}"
22391   [(set_attr "type" "sseiadd")
22392    (set_attr "mode" "TI")])
22393
22394 (define_insn "ussubv8hi3"
22395   [(set (match_operand:V8HI 0 "register_operand" "=x")
22396         (us_minus:V8HI (match_operand:V8HI 1 "register_operand" "0")
22397                        (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22398   "TARGET_SSE2"
22399   "psubusw\t{%2, %0|%0, %2}"
22400   [(set_attr "type" "sseiadd")
22401    (set_attr "mode" "TI")])
22402
22403 (define_insn "mulv8hi3"
22404   [(set (match_operand:V8HI 0 "register_operand" "=x")
22405         (mult:V8HI (match_operand:V8HI 1 "register_operand" "0")
22406                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22407   "TARGET_SSE2"
22408   "pmullw\t{%2, %0|%0, %2}"
22409   [(set_attr "type" "sseimul")
22410    (set_attr "mode" "TI")])
22411
22412 (define_insn "smulv8hi3_highpart"
22413   [(set (match_operand:V8HI 0 "register_operand" "=x")
22414         (truncate:V8HI
22415          (lshiftrt:V8SI
22416           (mult:V8SI (sign_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22417                      (sign_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22418           (const_int 16))))]
22419   "TARGET_SSE2"
22420   "pmulhw\t{%2, %0|%0, %2}"
22421   [(set_attr "type" "sseimul")
22422    (set_attr "mode" "TI")])
22423
22424 (define_insn "umulv8hi3_highpart"
22425   [(set (match_operand:V8HI 0 "register_operand" "=x")
22426         (truncate:V8HI
22427          (lshiftrt:V8SI
22428           (mult:V8SI (zero_extend:V8SI (match_operand:V8HI 1 "register_operand" "0"))
22429                      (zero_extend:V8SI (match_operand:V8HI 2 "nonimmediate_operand" "xm")))
22430           (const_int 16))))]
22431   "TARGET_SSE2"
22432   "pmulhuw\t{%2, %0|%0, %2}"
22433   [(set_attr "type" "sseimul")
22434    (set_attr "mode" "TI")])
22435
22436 (define_insn "sse2_umulsidi3"
22437   [(set (match_operand:DI 0 "register_operand" "=y")
22438         (mult:DI (zero_extend:DI (vec_select:SI
22439                                   (match_operand:V2SI 1 "register_operand" "0")
22440                                   (parallel [(const_int 0)])))
22441                  (zero_extend:DI (vec_select:SI
22442                                   (match_operand:V2SI 2 "nonimmediate_operand" "ym")
22443                                   (parallel [(const_int 0)])))))]
22444   "TARGET_SSE2"
22445   "pmuludq\t{%2, %0|%0, %2}"
22446   [(set_attr "type" "sseimul")
22447    (set_attr "mode" "TI")])
22448
22449 (define_insn "sse2_umulv2siv2di3"
22450   [(set (match_operand:V2DI 0 "register_operand" "=x")
22451         (mult:V2DI (zero_extend:V2DI
22452                      (vec_select:V2SI
22453                        (match_operand:V4SI 1 "register_operand" "0")
22454                        (parallel [(const_int 0) (const_int 2)])))
22455                    (zero_extend:V2DI
22456                      (vec_select:V2SI
22457                        (match_operand:V4SI 2 "nonimmediate_operand" "xm")
22458                        (parallel [(const_int 0) (const_int 2)])))))]
22459   "TARGET_SSE2"
22460   "pmuludq\t{%2, %0|%0, %2}"
22461   [(set_attr "type" "sseimul")
22462    (set_attr "mode" "TI")])
22463
22464 (define_insn "sse2_pmaddwd"
22465   [(set (match_operand:V4SI 0 "register_operand" "=x")
22466         (plus:V4SI
22467          (mult:V4SI
22468           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 1 "register_operand" "0")
22469                                              (parallel [(const_int 0)
22470                                                         (const_int 2)
22471                                                         (const_int 4)
22472                                                         (const_int 6)])))
22473           (sign_extend:V4SI (vec_select:V4HI (match_operand:V8HI 2 "nonimmediate_operand" "xm")
22474                                              (parallel [(const_int 0)
22475                                                         (const_int 2)
22476                                                         (const_int 4)
22477                                                         (const_int 6)]))))
22478          (mult:V4SI
22479           (sign_extend:V4SI (vec_select:V4HI (match_dup 1)
22480                                              (parallel [(const_int 1)
22481                                                         (const_int 3)
22482                                                         (const_int 5)
22483                                                         (const_int 7)])))
22484           (sign_extend:V4SI (vec_select:V4HI (match_dup 2)
22485                                              (parallel [(const_int 1)
22486                                                         (const_int 3)
22487                                                         (const_int 5)
22488                                                         (const_int 7)]))))))]
22489   "TARGET_SSE2"
22490   "pmaddwd\t{%2, %0|%0, %2}"
22491   [(set_attr "type" "sseiadd")
22492    (set_attr "mode" "TI")])
22493
22494 ;; Same as pxor, but don't show input operands so that we don't think
22495 ;; they are live.
22496 (define_insn "sse2_clrti"
22497   [(set (match_operand:TI 0 "register_operand" "=x") (const_int 0))]
22498   "TARGET_SSE2"
22499 {
22500   if (get_attr_mode (insn) == MODE_TI)
22501     return "pxor\t%0, %0";
22502   else
22503     return "xorps\t%0, %0";
22504 }
22505   [(set_attr "type" "ssemov")
22506    (set_attr "memory" "none")
22507    (set (attr "mode")
22508               (if_then_else
22509                 (ne (symbol_ref "optimize_size")
22510                     (const_int 0))
22511                 (const_string "V4SF")
22512                 (const_string "TI")))])
22513
22514 ;; MMX unsigned averages/sum of absolute differences
22515
22516 (define_insn "sse2_uavgv16qi3"
22517   [(set (match_operand:V16QI 0 "register_operand" "=x")
22518         (ashiftrt:V16QI
22519          (plus:V16QI (plus:V16QI
22520                      (match_operand:V16QI 1 "register_operand" "0")
22521                      (match_operand:V16QI 2 "nonimmediate_operand" "xm"))
22522                      (const_vector:V16QI [(const_int 1) (const_int 1)
22523                                           (const_int 1) (const_int 1)
22524                                           (const_int 1) (const_int 1)
22525                                           (const_int 1) (const_int 1)
22526                                           (const_int 1) (const_int 1)
22527                                           (const_int 1) (const_int 1)
22528                                           (const_int 1) (const_int 1)
22529                                           (const_int 1) (const_int 1)]))
22530          (const_int 1)))]
22531   "TARGET_SSE2"
22532   "pavgb\t{%2, %0|%0, %2}"
22533   [(set_attr "type" "sseiadd")
22534    (set_attr "mode" "TI")])
22535
22536 (define_insn "sse2_uavgv8hi3"
22537   [(set (match_operand:V8HI 0 "register_operand" "=x")
22538         (ashiftrt:V8HI
22539          (plus:V8HI (plus:V8HI
22540                      (match_operand:V8HI 1 "register_operand" "0")
22541                      (match_operand:V8HI 2 "nonimmediate_operand" "xm"))
22542                     (const_vector:V8HI [(const_int 1) (const_int 1)
22543                                         (const_int 1) (const_int 1)
22544                                         (const_int 1) (const_int 1)
22545                                         (const_int 1) (const_int 1)]))
22546          (const_int 1)))]
22547   "TARGET_SSE2"
22548   "pavgw\t{%2, %0|%0, %2}"
22549   [(set_attr "type" "sseiadd")
22550    (set_attr "mode" "TI")])
22551
22552 ;; @@@ this isn't the right representation.
22553 (define_insn "sse2_psadbw"
22554   [(set (match_operand:V2DI 0 "register_operand" "=x")
22555         (unspec:V2DI [(match_operand:V16QI 1 "register_operand" "0")
22556                       (match_operand:V16QI 2 "nonimmediate_operand" "xm")]
22557                      UNSPEC_PSADBW))]
22558   "TARGET_SSE2"
22559   "psadbw\t{%2, %0|%0, %2}"
22560   [(set_attr "type" "sseiadd")
22561    (set_attr "mode" "TI")])
22562
22563
22564 ;; MMX insert/extract/shuffle
22565
22566 (define_insn "sse2_pinsrw"
22567   [(set (match_operand:V8HI 0 "register_operand" "=x")
22568         (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
22569                         (vec_duplicate:V8HI
22570                          (truncate:HI
22571                            (match_operand:SI 2 "nonimmediate_operand" "rm")))
22572                         (match_operand:SI 3 "immediate_operand" "i")))]
22573   "TARGET_SSE2"
22574   "pinsrw\t{%3, %2, %0|%0, %2, %3}"
22575   [(set_attr "type" "ssecvt")
22576    (set_attr "mode" "TI")])
22577
22578 (define_insn "sse2_pextrw"
22579   [(set (match_operand:SI 0 "register_operand" "=r")
22580         (zero_extend:SI
22581           (vec_select:HI (match_operand:V8HI 1 "register_operand" "x")
22582                          (parallel
22583                           [(match_operand:SI 2 "immediate_operand" "i")]))))]
22584   "TARGET_SSE2"
22585   "pextrw\t{%2, %1, %0|%0, %1, %2}"
22586   [(set_attr "type" "ssecvt")
22587    (set_attr "mode" "TI")])
22588
22589 (define_insn "sse2_pshufd"
22590   [(set (match_operand:V4SI 0 "register_operand" "=x")
22591         (unspec:V4SI [(match_operand:V4SI 1 "register_operand" "0")
22592                       (match_operand:SI 2 "immediate_operand" "i")]
22593                      UNSPEC_SHUFFLE))]
22594   "TARGET_SSE2"
22595   "pshufd\t{%2, %1, %0|%0, %1, %2}"
22596   [(set_attr "type" "ssecvt")
22597    (set_attr "mode" "TI")])
22598
22599 (define_insn "sse2_pshuflw"
22600   [(set (match_operand:V8HI 0 "register_operand" "=x")
22601         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22602                       (match_operand:SI 2 "immediate_operand" "i")]
22603                      UNSPEC_PSHUFLW))]
22604   "TARGET_SSE2"
22605   "pshuflw\t{%2, %1, %0|%0, %1, %2}"
22606   [(set_attr "type" "ssecvt")
22607    (set_attr "mode" "TI")])
22608
22609 (define_insn "sse2_pshufhw"
22610   [(set (match_operand:V8HI 0 "register_operand" "=x")
22611         (unspec:V8HI [(match_operand:V8HI 1 "register_operand" "0")
22612                       (match_operand:SI 2 "immediate_operand" "i")]
22613                      UNSPEC_PSHUFHW))]
22614   "TARGET_SSE2"
22615   "pshufhw\t{%2, %1, %0|%0, %1, %2}"
22616   [(set_attr "type" "ssecvt")
22617    (set_attr "mode" "TI")])
22618
22619 ;; MMX mask-generating comparisons
22620
22621 (define_insn "eqv16qi3"
22622   [(set (match_operand:V16QI 0 "register_operand" "=x")
22623         (eq:V16QI (match_operand:V16QI 1 "register_operand" "0")
22624                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22625   "TARGET_SSE2"
22626   "pcmpeqb\t{%2, %0|%0, %2}"
22627   [(set_attr "type" "ssecmp")
22628    (set_attr "mode" "TI")])
22629
22630 (define_insn "eqv8hi3"
22631   [(set (match_operand:V8HI 0 "register_operand" "=x")
22632         (eq:V8HI (match_operand:V8HI 1 "register_operand" "0")
22633                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22634   "TARGET_SSE2"
22635   "pcmpeqw\t{%2, %0|%0, %2}"
22636   [(set_attr "type" "ssecmp")
22637    (set_attr "mode" "TI")])
22638
22639 (define_insn "eqv4si3"
22640   [(set (match_operand:V4SI 0 "register_operand" "=x")
22641         (eq:V4SI (match_operand:V4SI 1 "register_operand" "0")
22642                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22643   "TARGET_SSE2"
22644   "pcmpeqd\t{%2, %0|%0, %2}"
22645   [(set_attr "type" "ssecmp")
22646    (set_attr "mode" "TI")])
22647
22648 (define_insn "gtv16qi3"
22649   [(set (match_operand:V16QI 0 "register_operand" "=x")
22650         (gt:V16QI (match_operand:V16QI 1 "register_operand" "0")
22651                  (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22652   "TARGET_SSE2"
22653   "pcmpgtb\t{%2, %0|%0, %2}"
22654   [(set_attr "type" "ssecmp")
22655    (set_attr "mode" "TI")])
22656
22657 (define_insn "gtv8hi3"
22658   [(set (match_operand:V8HI 0 "register_operand" "=x")
22659         (gt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22660                  (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22661   "TARGET_SSE2"
22662   "pcmpgtw\t{%2, %0|%0, %2}"
22663   [(set_attr "type" "ssecmp")
22664    (set_attr "mode" "TI")])
22665
22666 (define_insn "gtv4si3"
22667   [(set (match_operand:V4SI 0 "register_operand" "=x")
22668         (gt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22669                  (match_operand:V4SI 2 "nonimmediate_operand" "xm")))]
22670   "TARGET_SSE2"
22671   "pcmpgtd\t{%2, %0|%0, %2}"
22672   [(set_attr "type" "ssecmp")
22673    (set_attr "mode" "TI")])
22674
22675
22676 ;; MMX max/min insns
22677
22678 (define_insn "umaxv16qi3"
22679   [(set (match_operand:V16QI 0 "register_operand" "=x")
22680         (umax:V16QI (match_operand:V16QI 1 "register_operand" "0")
22681                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22682   "TARGET_SSE2"
22683   "pmaxub\t{%2, %0|%0, %2}"
22684   [(set_attr "type" "sseiadd")
22685    (set_attr "mode" "TI")])
22686
22687 (define_insn "smaxv8hi3"
22688   [(set (match_operand:V8HI 0 "register_operand" "=x")
22689         (smax:V8HI (match_operand:V8HI 1 "register_operand" "0")
22690                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22691   "TARGET_SSE2"
22692   "pmaxsw\t{%2, %0|%0, %2}"
22693   [(set_attr "type" "sseiadd")
22694    (set_attr "mode" "TI")])
22695
22696 (define_insn "uminv16qi3"
22697   [(set (match_operand:V16QI 0 "register_operand" "=x")
22698         (umin:V16QI (match_operand:V16QI 1 "register_operand" "0")
22699                    (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
22700   "TARGET_SSE2"
22701   "pminub\t{%2, %0|%0, %2}"
22702   [(set_attr "type" "sseiadd")
22703    (set_attr "mode" "TI")])
22704
22705 (define_insn "sminv8hi3"
22706   [(set (match_operand:V8HI 0 "register_operand" "=x")
22707         (smin:V8HI (match_operand:V8HI 1 "register_operand" "0")
22708                    (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
22709   "TARGET_SSE2"
22710   "pminsw\t{%2, %0|%0, %2}"
22711   [(set_attr "type" "sseiadd")
22712    (set_attr "mode" "TI")])
22713
22714
22715 ;; MMX shifts
22716
22717 (define_insn "ashrv8hi3"
22718   [(set (match_operand:V8HI 0 "register_operand" "=x")
22719         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22720                        (match_operand:TI 2 "nonmemory_operand" "xi")))]
22721   "TARGET_SSE2"
22722   "psraw\t{%2, %0|%0, %2}"
22723   [(set_attr "type" "sseishft")
22724    (set_attr "mode" "TI")])
22725
22726 (define_insn "ashrv4si3"
22727   [(set (match_operand:V4SI 0 "register_operand" "=x")
22728         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22729                        (match_operand:TI 2 "nonmemory_operand" "xi")))]
22730   "TARGET_SSE2"
22731   "psrad\t{%2, %0|%0, %2}"
22732   [(set_attr "type" "sseishft")
22733    (set_attr "mode" "TI")])
22734
22735 (define_insn "lshrv8hi3"
22736   [(set (match_operand:V8HI 0 "register_operand" "=x")
22737         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22738                        (match_operand:TI 2 "nonmemory_operand" "xi")))]
22739   "TARGET_SSE2"
22740   "psrlw\t{%2, %0|%0, %2}"
22741   [(set_attr "type" "sseishft")
22742    (set_attr "mode" "TI")])
22743
22744 (define_insn "lshrv4si3"
22745   [(set (match_operand:V4SI 0 "register_operand" "=x")
22746         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22747                        (match_operand:TI 2 "nonmemory_operand" "xi")))]
22748   "TARGET_SSE2"
22749   "psrld\t{%2, %0|%0, %2}"
22750   [(set_attr "type" "sseishft")
22751    (set_attr "mode" "TI")])
22752
22753 (define_insn "lshrv2di3"
22754   [(set (match_operand:V2DI 0 "register_operand" "=x")
22755         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22756                        (match_operand:TI 2 "nonmemory_operand" "xi")))]
22757   "TARGET_SSE2"
22758   "psrlq\t{%2, %0|%0, %2}"
22759   [(set_attr "type" "sseishft")
22760    (set_attr "mode" "TI")])
22761
22762 (define_insn "ashlv8hi3"
22763   [(set (match_operand:V8HI 0 "register_operand" "=x")
22764         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22765                      (match_operand:TI 2 "nonmemory_operand" "xi")))]
22766   "TARGET_SSE2"
22767   "psllw\t{%2, %0|%0, %2}"
22768   [(set_attr "type" "sseishft")
22769    (set_attr "mode" "TI")])
22770
22771 (define_insn "ashlv4si3"
22772   [(set (match_operand:V4SI 0 "register_operand" "=x")
22773         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22774                      (match_operand:TI 2 "nonmemory_operand" "xi")))]
22775   "TARGET_SSE2"
22776   "pslld\t{%2, %0|%0, %2}"
22777   [(set_attr "type" "sseishft")
22778    (set_attr "mode" "TI")])
22779
22780 (define_insn "ashlv2di3"
22781   [(set (match_operand:V2DI 0 "register_operand" "=x")
22782         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22783                      (match_operand:TI 2 "nonmemory_operand" "xi")))]
22784   "TARGET_SSE2"
22785   "psllq\t{%2, %0|%0, %2}"
22786   [(set_attr "type" "sseishft")
22787    (set_attr "mode" "TI")])
22788
22789 (define_insn "ashrv8hi3_ti"
22790   [(set (match_operand:V8HI 0 "register_operand" "=x")
22791         (ashiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22792                        (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22793   "TARGET_SSE2"
22794   "psraw\t{%2, %0|%0, %2}"
22795   [(set_attr "type" "sseishft")
22796    (set_attr "mode" "TI")])
22797
22798 (define_insn "ashrv4si3_ti"
22799   [(set (match_operand:V4SI 0 "register_operand" "=x")
22800         (ashiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22801                        (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22802   "TARGET_SSE2"
22803   "psrad\t{%2, %0|%0, %2}"
22804   [(set_attr "type" "sseishft")
22805    (set_attr "mode" "TI")])
22806
22807 (define_insn "lshrv8hi3_ti"
22808   [(set (match_operand:V8HI 0 "register_operand" "=x")
22809         (lshiftrt:V8HI (match_operand:V8HI 1 "register_operand" "0")
22810                        (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22811   "TARGET_SSE2"
22812   "psrlw\t{%2, %0|%0, %2}"
22813   [(set_attr "type" "sseishft")
22814    (set_attr "mode" "TI")])
22815
22816 (define_insn "lshrv4si3_ti"
22817   [(set (match_operand:V4SI 0 "register_operand" "=x")
22818         (lshiftrt:V4SI (match_operand:V4SI 1 "register_operand" "0")
22819                        (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22820   "TARGET_SSE2"
22821   "psrld\t{%2, %0|%0, %2}"
22822   [(set_attr "type" "sseishft")
22823    (set_attr "mode" "TI")])
22824
22825 (define_insn "lshrv2di3_ti"
22826   [(set (match_operand:V2DI 0 "register_operand" "=x")
22827         (lshiftrt:V2DI (match_operand:V2DI 1 "register_operand" "0")
22828                        (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22829   "TARGET_SSE2"
22830   "psrlq\t{%2, %0|%0, %2}"
22831   [(set_attr "type" "sseishft")
22832    (set_attr "mode" "TI")])
22833
22834 (define_insn "ashlv8hi3_ti"
22835   [(set (match_operand:V8HI 0 "register_operand" "=x")
22836         (ashift:V8HI (match_operand:V8HI 1 "register_operand" "0")
22837                      (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22838   "TARGET_SSE2"
22839   "psllw\t{%2, %0|%0, %2}"
22840   [(set_attr "type" "sseishft")
22841    (set_attr "mode" "TI")])
22842
22843 (define_insn "ashlv4si3_ti"
22844   [(set (match_operand:V4SI 0 "register_operand" "=x")
22845         (ashift:V4SI (match_operand:V4SI 1 "register_operand" "0")
22846                      (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22847   "TARGET_SSE2"
22848   "pslld\t{%2, %0|%0, %2}"
22849   [(set_attr "type" "sseishft")
22850    (set_attr "mode" "TI")])
22851
22852 (define_insn "ashlv2di3_ti"
22853   [(set (match_operand:V2DI 0 "register_operand" "=x")
22854         (ashift:V2DI (match_operand:V2DI 1 "register_operand" "0")
22855                      (subreg:TI (match_operand:V2DI 2 "nonmemory_operand" "xi") 0)))]
22856   "TARGET_SSE2"
22857   "psllq\t{%2, %0|%0, %2}"
22858   [(set_attr "type" "sseishft")
22859    (set_attr "mode" "TI")])
22860
22861 ;; See logical MMX insns for the reason for the unspec.  Strictly speaking
22862 ;; we wouldn't need here it since we never generate TImode arithmetic.
22863
22864 ;; There has to be some kind of prize for the weirdest new instruction...
22865 (define_insn "sse2_ashlti3"
22866   [(set (match_operand:TI 0 "register_operand" "=x")
22867         (unspec:TI
22868          [(ashift:TI (match_operand:TI 1 "register_operand" "0")
22869                      (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22870                                (const_int 8)))] UNSPEC_NOP))]
22871   "TARGET_SSE2"
22872   "pslldq\t{%2, %0|%0, %2}"
22873   [(set_attr "type" "sseishft")
22874    (set_attr "mode" "TI")])
22875
22876 (define_insn "sse2_lshrti3"
22877   [(set (match_operand:TI 0 "register_operand" "=x")
22878         (unspec:TI
22879          [(lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
22880                        (mult:SI (match_operand:SI 2 "immediate_operand" "i")
22881                                 (const_int 8)))] UNSPEC_NOP))]
22882   "TARGET_SSE2"
22883   "psrldq\t{%2, %0|%0, %2}"
22884   [(set_attr "type" "sseishft")
22885    (set_attr "mode" "TI")])
22886
22887 ;; SSE unpack
22888
22889 (define_insn "sse2_unpckhpd"
22890   [(set (match_operand:V2DF 0 "register_operand" "=x")
22891         (vec_concat:V2DF
22892          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22893                         (parallel [(const_int 1)]))
22894          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22895                         (parallel [(const_int 0)]))))]
22896   "TARGET_SSE2"
22897   "unpckhpd\t{%2, %0|%0, %2}"
22898   [(set_attr "type" "ssecvt")
22899    (set_attr "mode" "TI")])
22900
22901 (define_insn "sse2_unpcklpd"
22902   [(set (match_operand:V2DF 0 "register_operand" "=x")
22903         (vec_concat:V2DF
22904          (vec_select:DF (match_operand:V2DF 1 "register_operand" "0")
22905                         (parallel [(const_int 0)]))
22906          (vec_select:DF (match_operand:V2DF 2 "register_operand" "x")
22907                         (parallel [(const_int 1)]))))]
22908   "TARGET_SSE2"
22909   "unpcklpd\t{%2, %0|%0, %2}"
22910   [(set_attr "type" "ssecvt")
22911    (set_attr "mode" "TI")])
22912
22913 ;; MMX pack/unpack insns.
22914
22915 (define_insn "sse2_packsswb"
22916   [(set (match_operand:V16QI 0 "register_operand" "=x")
22917         (vec_concat:V16QI
22918          (ss_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22919          (ss_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22920   "TARGET_SSE2"
22921   "packsswb\t{%2, %0|%0, %2}"
22922   [(set_attr "type" "ssecvt")
22923    (set_attr "mode" "TI")])
22924
22925 (define_insn "sse2_packssdw"
22926   [(set (match_operand:V8HI 0 "register_operand" "=x")
22927         (vec_concat:V8HI
22928          (ss_truncate:V4HI (match_operand:V4SI 1 "register_operand" "0"))
22929          (ss_truncate:V4HI (match_operand:V4SI 2 "register_operand" "x"))))]
22930   "TARGET_SSE2"
22931   "packssdw\t{%2, %0|%0, %2}"
22932   [(set_attr "type" "ssecvt")
22933    (set_attr "mode" "TI")])
22934
22935 (define_insn "sse2_packuswb"
22936   [(set (match_operand:V16QI 0 "register_operand" "=x")
22937         (vec_concat:V16QI
22938          (us_truncate:V8QI (match_operand:V8HI 1 "register_operand" "0"))
22939          (us_truncate:V8QI (match_operand:V8HI 2 "register_operand" "x"))))]
22940   "TARGET_SSE2"
22941   "packuswb\t{%2, %0|%0, %2}"
22942   [(set_attr "type" "ssecvt")
22943    (set_attr "mode" "TI")])
22944
22945 (define_insn "sse2_punpckhbw"
22946   [(set (match_operand:V16QI 0 "register_operand" "=x")
22947         (vec_merge:V16QI
22948          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
22949                            (parallel [(const_int 8) (const_int 0)
22950                                       (const_int 9) (const_int 1)
22951                                       (const_int 10) (const_int 2)
22952                                       (const_int 11) (const_int 3)
22953                                       (const_int 12) (const_int 4)
22954                                       (const_int 13) (const_int 5)
22955                                       (const_int 14) (const_int 6)
22956                                       (const_int 15) (const_int 7)]))
22957          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
22958                            (parallel [(const_int 0) (const_int 8)
22959                                       (const_int 1) (const_int 9)
22960                                       (const_int 2) (const_int 10)
22961                                       (const_int 3) (const_int 11)
22962                                       (const_int 4) (const_int 12)
22963                                       (const_int 5) (const_int 13)
22964                                       (const_int 6) (const_int 14)
22965                                       (const_int 7) (const_int 15)]))
22966          (const_int 21845)))]
22967   "TARGET_SSE2"
22968   "punpckhbw\t{%2, %0|%0, %2}"
22969   [(set_attr "type" "ssecvt")
22970    (set_attr "mode" "TI")])
22971
22972 (define_insn "sse2_punpckhwd"
22973   [(set (match_operand:V8HI 0 "register_operand" "=x")
22974         (vec_merge:V8HI
22975          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
22976                           (parallel [(const_int 4) (const_int 0)
22977                                      (const_int 5) (const_int 1)
22978                                      (const_int 6) (const_int 2)
22979                                      (const_int 7) (const_int 3)]))
22980          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
22981                           (parallel [(const_int 0) (const_int 4)
22982                                      (const_int 1) (const_int 5)
22983                                      (const_int 2) (const_int 6)
22984                                      (const_int 3) (const_int 7)]))
22985          (const_int 85)))]
22986   "TARGET_SSE2"
22987   "punpckhwd\t{%2, %0|%0, %2}"
22988   [(set_attr "type" "ssecvt")
22989    (set_attr "mode" "TI")])
22990
22991 (define_insn "sse2_punpckhdq"
22992   [(set (match_operand:V4SI 0 "register_operand" "=x")
22993         (vec_merge:V4SI
22994          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
22995                           (parallel [(const_int 2) (const_int 0)
22996                                      (const_int 3) (const_int 1)]))
22997          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
22998                           (parallel [(const_int 0) (const_int 2)
22999                                      (const_int 1) (const_int 3)]))
23000          (const_int 5)))]
23001   "TARGET_SSE2"
23002   "punpckhdq\t{%2, %0|%0, %2}"
23003   [(set_attr "type" "ssecvt")
23004    (set_attr "mode" "TI")])
23005
23006 (define_insn "sse2_punpcklbw"
23007   [(set (match_operand:V16QI 0 "register_operand" "=x")
23008         (vec_merge:V16QI
23009          (vec_select:V16QI (match_operand:V16QI 1 "register_operand" "0")
23010                            (parallel [(const_int 0) (const_int 8)
23011                                       (const_int 1) (const_int 9)
23012                                       (const_int 2) (const_int 10)
23013                                       (const_int 3) (const_int 11)
23014                                       (const_int 4) (const_int 12)
23015                                       (const_int 5) (const_int 13)
23016                                       (const_int 6) (const_int 14)
23017                                       (const_int 7) (const_int 15)]))
23018          (vec_select:V16QI (match_operand:V16QI 2 "register_operand" "x")
23019                            (parallel [(const_int 8) (const_int 0)
23020                                       (const_int 9) (const_int 1)
23021                                       (const_int 10) (const_int 2)
23022                                       (const_int 11) (const_int 3)
23023                                       (const_int 12) (const_int 4)
23024                                       (const_int 13) (const_int 5)
23025                                       (const_int 14) (const_int 6)
23026                                       (const_int 15) (const_int 7)]))
23027          (const_int 21845)))]
23028   "TARGET_SSE2"
23029   "punpcklbw\t{%2, %0|%0, %2}"
23030   [(set_attr "type" "ssecvt")
23031    (set_attr "mode" "TI")])
23032
23033 (define_insn "sse2_punpcklwd"
23034   [(set (match_operand:V8HI 0 "register_operand" "=x")
23035         (vec_merge:V8HI
23036          (vec_select:V8HI (match_operand:V8HI 1 "register_operand" "0")
23037                           (parallel [(const_int 0) (const_int 4)
23038                                      (const_int 1) (const_int 5)
23039                                      (const_int 2) (const_int 6)
23040                                      (const_int 3) (const_int 7)]))
23041          (vec_select:V8HI (match_operand:V8HI 2 "register_operand" "x")
23042                           (parallel [(const_int 4) (const_int 0)
23043                                      (const_int 5) (const_int 1)
23044                                      (const_int 6) (const_int 2)
23045                                      (const_int 7) (const_int 3)]))
23046          (const_int 85)))]
23047   "TARGET_SSE2"
23048   "punpcklwd\t{%2, %0|%0, %2}"
23049   [(set_attr "type" "ssecvt")
23050    (set_attr "mode" "TI")])
23051
23052 (define_insn "sse2_punpckldq"
23053   [(set (match_operand:V4SI 0 "register_operand" "=x")
23054         (vec_merge:V4SI
23055          (vec_select:V4SI (match_operand:V4SI 1 "register_operand" "0")
23056                           (parallel [(const_int 0) (const_int 2)
23057                                      (const_int 1) (const_int 3)]))
23058          (vec_select:V4SI (match_operand:V4SI 2 "register_operand" "x")
23059                           (parallel [(const_int 2) (const_int 0)
23060                                      (const_int 3) (const_int 1)]))
23061          (const_int 5)))]
23062   "TARGET_SSE2"
23063   "punpckldq\t{%2, %0|%0, %2}"
23064   [(set_attr "type" "ssecvt")
23065    (set_attr "mode" "TI")])
23066
23067 (define_insn "sse2_punpcklqdq"
23068   [(set (match_operand:V2DI 0 "register_operand" "=x")
23069         (vec_merge:V2DI
23070          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23071                           (parallel [(const_int 1)
23072                                      (const_int 0)]))
23073          (match_operand:V2DI 1 "register_operand" "0")
23074          (const_int 1)))]
23075   "TARGET_SSE2"
23076   "punpcklqdq\t{%2, %0|%0, %2}"
23077   [(set_attr "type" "ssecvt")
23078    (set_attr "mode" "TI")])
23079
23080 (define_insn "sse2_punpckhqdq"
23081   [(set (match_operand:V2DI 0 "register_operand" "=x")
23082         (vec_merge:V2DI
23083          (match_operand:V2DI 1 "register_operand" "0")
23084          (vec_select:V2DI (match_operand:V2DI 2 "register_operand" "x")
23085                           (parallel [(const_int 1)
23086                                      (const_int 0)]))
23087          (const_int 1)))]
23088   "TARGET_SSE2"
23089   "punpckhqdq\t{%2, %0|%0, %2}"
23090   [(set_attr "type" "ssecvt")
23091    (set_attr "mode" "TI")])
23092
23093 ;; SSE2 moves
23094
23095 (define_insn "sse2_movapd"
23096   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23097         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23098                      UNSPEC_MOVA))]
23099   "TARGET_SSE2
23100    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23101   "movapd\t{%1, %0|%0, %1}"
23102   [(set_attr "type" "ssemov")
23103    (set_attr "mode" "V2DF")])
23104
23105 (define_insn "sse2_movupd"
23106   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23107         (unspec:V2DF [(match_operand:V2DF 1 "nonimmediate_operand" "xm,x")]
23108                      UNSPEC_MOVU))]
23109   "TARGET_SSE2
23110    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23111   "movupd\t{%1, %0|%0, %1}"
23112   [(set_attr "type" "ssecvt")
23113    (set_attr "mode" "V2DF")])
23114
23115 (define_insn "sse2_movdqa"
23116   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23117         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23118                        UNSPEC_MOVA))]
23119   "TARGET_SSE2
23120    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23121   "movdqa\t{%1, %0|%0, %1}"
23122   [(set_attr "type" "ssemov")
23123    (set_attr "mode" "TI")])
23124
23125 (define_insn "sse2_movdqu"
23126   [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
23127         (unspec:V16QI [(match_operand:V16QI 1 "nonimmediate_operand" "xm,x")]
23128                        UNSPEC_MOVU))]
23129   "TARGET_SSE2
23130    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
23131   "movdqu\t{%1, %0|%0, %1}"
23132   [(set_attr "type" "ssecvt")
23133    (set_attr "mode" "TI")])
23134
23135 (define_insn "sse2_movdq2q"
23136   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y")
23137         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x")
23138                        (parallel [(const_int 0)])))]
23139   "TARGET_SSE2 && !TARGET_64BIT"
23140   "@
23141    movq\t{%1, %0|%0, %1}
23142    movdq2q\t{%1, %0|%0, %1}"
23143   [(set_attr "type" "ssecvt")
23144    (set_attr "mode" "TI")])
23145
23146 (define_insn "sse2_movdq2q_rex64"
23147   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,y,r")
23148         (vec_select:DI (match_operand:V2DI 1 "register_operand" "x,x,x")
23149                        (parallel [(const_int 0)])))]
23150   "TARGET_SSE2 && TARGET_64BIT"
23151   "@
23152    movq\t{%1, %0|%0, %1}
23153    movdq2q\t{%1, %0|%0, %1}
23154    movd\t{%1, %0|%0, %1}"
23155   [(set_attr "type" "ssecvt")
23156    (set_attr "mode" "TI")])
23157
23158 (define_insn "sse2_movq2dq"
23159   [(set (match_operand:V2DI 0 "register_operand" "=x,?x")
23160         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y")
23161                          (const_int 0)))]
23162   "TARGET_SSE2 && !TARGET_64BIT"
23163   "@
23164    movq\t{%1, %0|%0, %1}
23165    movq2dq\t{%1, %0|%0, %1}"
23166   [(set_attr "type" "ssecvt,ssemov")
23167    (set_attr "mode" "TI")])
23168
23169 (define_insn "sse2_movq2dq_rex64"
23170   [(set (match_operand:V2DI 0 "register_operand" "=x,?x,?x")
23171         (vec_concat:V2DI (match_operand:DI 1 "nonimmediate_operand" "m,y,r")
23172                          (const_int 0)))]
23173   "TARGET_SSE2 && TARGET_64BIT"
23174   "@
23175    movq\t{%1, %0|%0, %1}
23176    movq2dq\t{%1, %0|%0, %1}
23177    movd\t{%1, %0|%0, %1}"
23178   [(set_attr "type" "ssecvt,ssemov,ssecvt")
23179    (set_attr "mode" "TI")])
23180
23181 (define_insn "sse2_movq"
23182   [(set (match_operand:V2DI 0 "register_operand" "=x")
23183         (vec_concat:V2DI (vec_select:DI
23184                           (match_operand:V2DI 1 "nonimmediate_operand" "xm")
23185                           (parallel [(const_int 0)]))
23186                          (const_int 0)))]
23187   "TARGET_SSE2"
23188   "movq\t{%1, %0|%0, %1}"
23189   [(set_attr "type" "ssemov")
23190    (set_attr "mode" "TI")])
23191
23192 (define_insn "sse2_loadd"
23193   [(set (match_operand:V4SI 0 "register_operand" "=x")
23194         (vec_merge:V4SI
23195          (vec_duplicate:V4SI (match_operand:SI 1 "nonimmediate_operand" "mr"))
23196          (const_vector:V4SI [(const_int 0)
23197                              (const_int 0)
23198                              (const_int 0)
23199                              (const_int 0)])
23200          (const_int 1)))]
23201   "TARGET_SSE2"
23202   "movd\t{%1, %0|%0, %1}"
23203   [(set_attr "type" "ssemov")
23204    (set_attr "mode" "TI")])
23205
23206 (define_insn "sse2_stored"
23207   [(set (match_operand:SI 0 "nonimmediate_operand" "=mr")
23208         (vec_select:SI
23209          (match_operand:V4SI 1 "register_operand" "x")
23210          (parallel [(const_int 0)])))]
23211   "TARGET_SSE2"
23212   "movd\t{%1, %0|%0, %1}"
23213   [(set_attr "type" "ssemov")
23214    (set_attr "mode" "TI")])
23215
23216 (define_insn "sse2_movhpd"
23217   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23218         (vec_merge:V2DF
23219          (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
23220          (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
23221          (const_int 2)))]
23222   "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
23223   "movhpd\t{%2, %0|%0, %2}"
23224   [(set_attr "type" "ssecvt")
23225    (set_attr "mode" "V2DF")])
23226
23227 (define_insn "sse2_movlpd"
23228   [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,m")
23229         (vec_merge:V2DF
23230          (match_operand:V2DF 1 "nonimmediate_operand" "0,0")
23231          (match_operand:V2DF 2 "nonimmediate_operand" "m,x")
23232          (const_int 1)))]
23233   "TARGET_SSE2 && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[2]) == MEM)"
23234   "movlpd\t{%2, %0|%0, %2}"
23235   [(set_attr "type" "ssecvt")
23236    (set_attr "mode" "V2DF")])
23237
23238 (define_expand "sse2_loadsd"
23239   [(match_operand:V2DF 0 "register_operand" "")
23240    (match_operand:DF 1 "memory_operand" "")]
23241   "TARGET_SSE2"
23242 {
23243   emit_insn (gen_sse2_loadsd_1 (operands[0], operands[1],
23244                                 CONST0_RTX (V2DFmode)));
23245   DONE;
23246 })
23247
23248 (define_insn "sse2_loadsd_1"
23249   [(set (match_operand:V2DF 0 "register_operand" "=x")
23250         (vec_merge:V2DF
23251          (vec_duplicate:V2DF (match_operand:DF 1 "memory_operand" "m"))
23252          (match_operand:V2DF 2 "const0_operand" "X")
23253          (const_int 1)))]
23254   "TARGET_SSE2"
23255   "movsd\t{%1, %0|%0, %1}"
23256   [(set_attr "type" "ssecvt")
23257    (set_attr "mode" "DF")])
23258
23259 (define_insn "sse2_movsd"
23260   [(set (match_operand:V2DF 0 "register_operand" "=x")
23261         (vec_merge:V2DF
23262          (match_operand:V2DF 1 "register_operand" "0")
23263          (match_operand:V2DF 2 "register_operand" "x")
23264          (const_int 1)))]
23265   "TARGET_SSE2"
23266   "movsd\t{%2, %0|%0, %2}"
23267   [(set_attr "type" "ssecvt")
23268    (set_attr "mode" "DF")])
23269
23270 (define_insn "sse2_storesd"
23271   [(set (match_operand:DF 0 "memory_operand" "=m")
23272         (vec_select:DF
23273          (match_operand:V2DF 1 "register_operand" "x")
23274          (parallel [(const_int 0)])))]
23275   "TARGET_SSE2"
23276   "movsd\t{%1, %0|%0, %1}"
23277   [(set_attr "type" "ssecvt")
23278    (set_attr "mode" "DF")])
23279
23280 (define_insn "sse2_shufpd"
23281   [(set (match_operand:V2DF 0 "register_operand" "=x")
23282         (unspec:V2DF [(match_operand:V2DF 1 "register_operand" "0")
23283                       (match_operand:V2DF 2 "nonimmediate_operand" "xm")
23284                       (match_operand:SI 3 "immediate_operand" "i")]
23285                      UNSPEC_SHUFFLE))]
23286   "TARGET_SSE2"
23287   ;; @@@ check operand order for intel/nonintel syntax
23288   "shufpd\t{%3, %2, %0|%0, %2, %3}"
23289   [(set_attr "type" "ssecvt")
23290    (set_attr "mode" "V2DF")])
23291
23292 (define_insn "sse2_clflush"
23293   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
23294                     UNSPECV_CLFLUSH)]
23295   "TARGET_SSE2"
23296   "clflush %0"
23297   [(set_attr "type" "sse")
23298    (set_attr "memory" "unknown")])
23299
23300 (define_expand "sse2_mfence"
23301   [(set (match_dup 0)
23302         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23303   "TARGET_SSE2"
23304 {
23305   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23306   MEM_VOLATILE_P (operands[0]) = 1;
23307 })
23308
23309 (define_insn "*mfence_insn"
23310   [(set (match_operand:BLK 0 "" "")
23311         (unspec:BLK [(match_dup 0)] UNSPEC_MFENCE))]
23312   "TARGET_SSE2"
23313   "mfence"
23314   [(set_attr "type" "sse")
23315    (set_attr "memory" "unknown")])
23316
23317 (define_expand "sse2_lfence"
23318   [(set (match_dup 0)
23319         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23320   "TARGET_SSE2"
23321 {
23322   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
23323   MEM_VOLATILE_P (operands[0]) = 1;
23324 })
23325
23326 (define_insn "*lfence_insn"
23327   [(set (match_operand:BLK 0 "" "")
23328         (unspec:BLK [(match_dup 0)] UNSPEC_LFENCE))]
23329   "TARGET_SSE2"
23330   "lfence"
23331   [(set_attr "type" "sse")
23332    (set_attr "memory" "unknown")])