OSDN Git Service

* optabs.h (enum optab_index): Add new OTI_scalb.
[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, 2004, 2005, 2006, 2007
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 GCC.
9 ;;
10 ;; GCC 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 ;; GCC 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 GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, 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 ;; The special asm out single letter directives following a '%' are:
31 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
32 ;;     operands[1].
33 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
34 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
35 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
36 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
37 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
38 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
39 ;; 'J' Print the appropriate jump operand.
40 ;;
41 ;; 'b' Print the QImode name of the register for the indicated operand.
42 ;;     %b0 would print %al if operands[0] is reg 0.
43 ;; 'w' Likewise, print the HImode name of the register.
44 ;; 'k' Likewise, print the SImode name of the register.
45 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
46 ;; 'y' Print "st(0)" instead of "st" as a register.
47
48 ;; UNSPEC usage:
49
50 (define_constants
51   [; Relocation specifiers
52    (UNSPEC_GOT                  0)
53    (UNSPEC_GOTOFF               1)
54    (UNSPEC_GOTPCREL             2)
55    (UNSPEC_GOTTPOFF             3)
56    (UNSPEC_TPOFF                4)
57    (UNSPEC_NTPOFF               5)
58    (UNSPEC_DTPOFF               6)
59    (UNSPEC_GOTNTPOFF            7)
60    (UNSPEC_INDNTPOFF            8)
61
62    ; Prologue support
63    (UNSPEC_STACK_ALLOC          11)
64    (UNSPEC_SET_GOT              12)
65    (UNSPEC_SSE_PROLOGUE_SAVE    13)
66    (UNSPEC_REG_SAVE             14)
67    (UNSPEC_DEF_CFA              15)
68
69    ; TLS support
70    (UNSPEC_TP                   16)
71    (UNSPEC_TLS_GD               17)
72    (UNSPEC_TLS_LD_BASE          18)
73    (UNSPEC_TLSDESC              19)
74
75    ; Other random patterns
76    (UNSPEC_SCAS                 20)
77    (UNSPEC_FNSTSW               21)
78    (UNSPEC_SAHF                 22)
79    (UNSPEC_FSTCW                23)
80    (UNSPEC_ADD_CARRY            24)
81    (UNSPEC_FLDCW                25)
82    (UNSPEC_REP                  26)
83    (UNSPEC_EH_RETURN            27)
84    (UNSPEC_LD_MPIC              28)     ; load_macho_picbase
85    (UNSPEC_TRUNC_NOOP           29)
86
87    ; For SSE/MMX support:
88    (UNSPEC_FIX_NOTRUNC          30)
89    (UNSPEC_MASKMOV              31)
90    (UNSPEC_MOVMSK               32)
91    (UNSPEC_MOVNT                33)
92    (UNSPEC_MOVU                 34)
93    (UNSPEC_RCP                  35)
94    (UNSPEC_RSQRT                36)
95    (UNSPEC_SFENCE               37)
96    (UNSPEC_NOP                  38)     ; prevents combiner cleverness
97    (UNSPEC_PFRCP                39)
98    (UNSPEC_PFRCPIT1             40)
99    (UNSPEC_PFRCPIT2             41)
100    (UNSPEC_PFRSQRT              42)
101    (UNSPEC_PFRSQIT1             43)
102    (UNSPEC_MFENCE               44)
103    (UNSPEC_LFENCE               45)
104    (UNSPEC_PSADBW               46)
105    (UNSPEC_LDDQU                47)
106
107    ; Generic math support
108    (UNSPEC_COPYSIGN             50)
109    (UNSPEC_IEEE_MIN             51)     ; not commutative
110    (UNSPEC_IEEE_MAX             52)     ; not commutative
111
112    ; x87 Floating point
113    (UNSPEC_SIN                  60)
114    (UNSPEC_COS                  61)
115    (UNSPEC_FPATAN               62)
116    (UNSPEC_FYL2X                63)
117    (UNSPEC_FYL2XP1              64)
118    (UNSPEC_FRNDINT              65)
119    (UNSPEC_FIST                 66)
120    (UNSPEC_F2XM1                67)
121    (UNSPEC_TAN                  68)
122    (UNSPEC_FXAM                 69)
123
124    ; x87 Rounding
125    (UNSPEC_FRNDINT_FLOOR        70)
126    (UNSPEC_FRNDINT_CEIL         71)
127    (UNSPEC_FRNDINT_TRUNC        72)
128    (UNSPEC_FRNDINT_MASK_PM      73)
129    (UNSPEC_FIST_FLOOR           74)
130    (UNSPEC_FIST_CEIL            75)
131
132    ; x87 Double output FP
133    (UNSPEC_SINCOS_COS           80)
134    (UNSPEC_SINCOS_SIN           81)
135    (UNSPEC_XTRACT_FRACT         84)
136    (UNSPEC_XTRACT_EXP           85)
137    (UNSPEC_FSCALE_FRACT         86)
138    (UNSPEC_FSCALE_EXP           87)
139    (UNSPEC_FPREM_F              88)
140    (UNSPEC_FPREM_U              89)
141    (UNSPEC_FPREM1_F             90)
142    (UNSPEC_FPREM1_U             91)
143
144    ; SSP patterns
145    (UNSPEC_SP_SET               100)
146    (UNSPEC_SP_TEST              101)
147    (UNSPEC_SP_TLS_SET           102)
148    (UNSPEC_SP_TLS_TEST          103)
149
150    ; SSSE3
151    (UNSPEC_PSHUFB               120)
152    (UNSPEC_PSIGN                121)
153    (UNSPEC_PALIGNR              122)
154
155    ; For SSE4A support
156    (UNSPEC_EXTRQI               130)
157    (UNSPEC_EXTRQ                131)   
158    (UNSPEC_INSERTQI             132)
159    (UNSPEC_INSERTQ              133)
160   ])
161
162 (define_constants
163   [(UNSPECV_BLOCKAGE            0)
164    (UNSPECV_STACK_PROBE         1)
165    (UNSPECV_EMMS                2)
166    (UNSPECV_LDMXCSR             3)
167    (UNSPECV_STMXCSR             4)
168    (UNSPECV_FEMMS               5)
169    (UNSPECV_CLFLUSH             6)
170    (UNSPECV_ALIGN               7)
171    (UNSPECV_MONITOR             8)
172    (UNSPECV_MWAIT               9)
173    (UNSPECV_CMPXCHG_1           10)
174    (UNSPECV_CMPXCHG_2           11)
175    (UNSPECV_XCHG                12)
176    (UNSPECV_LOCK                13)
177   ])
178
179 ;; Registers by name.
180 (define_constants
181   [(BP_REG                       6)
182    (SP_REG                       7)
183    (FLAGS_REG                   17)
184    (FPSR_REG                    18)
185    (FPCR_REG                    19)
186    (R10_REG                     39)
187    (R11_REG                     40)
188   ])
189
190 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
191 ;; from i386.c.
192
193 ;; In C guard expressions, put expressions which may be compile-time
194 ;; constants first.  This allows for better optimization.  For
195 ;; example, write "TARGET_64BIT && reload_completed", not
196 ;; "reload_completed && TARGET_64BIT".
197
198 \f
199 ;; Processor type.  This attribute must exactly match the processor_type
200 ;; enumeration in i386.h.
201 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
202                     nocona,core2,generic32,generic64,amdfam10"
203   (const (symbol_ref "ix86_tune")))
204
205 ;; A basic instruction type.  Refinements due to arguments to be
206 ;; provided in other attributes.
207 (define_attr "type"
208   "other,multi,
209    alu,alu1,negnot,imov,imovx,lea,
210    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
211    icmp,test,ibr,setcc,icmov,
212    push,pop,call,callv,leave,
213    str,bitmanip,
214    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
215    sselog,sselog1,sseiadd,sseishft,sseimul,
216    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins,
217    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
218   (const_string "other"))
219
220 ;; Main data type used by the insn
221 (define_attr "mode"
222   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
223   (const_string "unknown"))
224
225 ;; The CPU unit operations uses.
226 (define_attr "unit" "integer,i387,sse,mmx,unknown"
227   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
228            (const_string "i387")
229          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
230                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins")
231            (const_string "sse")
232          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
233            (const_string "mmx")
234          (eq_attr "type" "other")
235            (const_string "unknown")]
236          (const_string "integer")))
237
238 ;; The (bounding maximum) length of an instruction immediate.
239 (define_attr "length_immediate" ""
240   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
241                           bitmanip")
242            (const_int 0)
243          (eq_attr "unit" "i387,sse,mmx")
244            (const_int 0)
245          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
246                           imul,icmp,push,pop")
247            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
248          (eq_attr "type" "imov,test")
249            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
250          (eq_attr "type" "call")
251            (if_then_else (match_operand 0 "constant_call_address_operand" "")
252              (const_int 4)
253              (const_int 0))
254          (eq_attr "type" "callv")
255            (if_then_else (match_operand 1 "constant_call_address_operand" "")
256              (const_int 4)
257              (const_int 0))
258          ;; We don't know the size before shorten_branches.  Expect
259          ;; the instruction to fit for better scheduling.
260          (eq_attr "type" "ibr")
261            (const_int 1)
262          ]
263          (symbol_ref "/* Update immediate_length and other attributes! */
264                       gcc_unreachable (),1")))
265
266 ;; The (bounding maximum) length of an instruction address.
267 (define_attr "length_address" ""
268   (cond [(eq_attr "type" "str,other,multi,fxch")
269            (const_int 0)
270          (and (eq_attr "type" "call")
271               (match_operand 0 "constant_call_address_operand" ""))
272              (const_int 0)
273          (and (eq_attr "type" "callv")
274               (match_operand 1 "constant_call_address_operand" ""))
275              (const_int 0)
276          ]
277          (symbol_ref "ix86_attr_length_address_default (insn)")))
278
279 ;; Set when length prefix is used.
280 (define_attr "prefix_data16" ""
281   (if_then_else (ior (eq_attr "mode" "HI")
282                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
283     (const_int 1)
284     (const_int 0)))
285
286 ;; Set when string REP prefix is used.
287 (define_attr "prefix_rep" ""
288   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
289     (const_int 1)
290     (const_int 0)))
291
292 ;; Set when 0f opcode prefix is used.
293 (define_attr "prefix_0f" ""
294   (if_then_else
295     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
296          (eq_attr "unit" "sse,mmx"))
297     (const_int 1)
298     (const_int 0)))
299
300 ;; Set when REX opcode prefix is used.
301 (define_attr "prefix_rex" ""
302   (cond [(and (eq_attr "mode" "DI")
303               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
304            (const_int 1)
305          (and (eq_attr "mode" "QI")
306               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
307                   (const_int 0)))
308            (const_int 1)
309          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
310              (const_int 0))
311            (const_int 1)
312         ]
313         (const_int 0)))
314
315 ;; Set when modrm byte is used.
316 (define_attr "modrm" ""
317   (cond [(eq_attr "type" "str,leave")
318            (const_int 0)
319          (eq_attr "unit" "i387")
320            (const_int 0)
321          (and (eq_attr "type" "incdec")
322               (ior (match_operand:SI 1 "register_operand" "")
323                    (match_operand:HI 1 "register_operand" "")))
324            (const_int 0)
325          (and (eq_attr "type" "push")
326               (not (match_operand 1 "memory_operand" "")))
327            (const_int 0)
328          (and (eq_attr "type" "pop")
329               (not (match_operand 0 "memory_operand" "")))
330            (const_int 0)
331          (and (eq_attr "type" "imov")
332               (ior (and (match_operand 0 "register_operand" "")
333                         (match_operand 1 "immediate_operand" ""))
334                    (ior (and (match_operand 0 "ax_reg_operand" "")
335                              (match_operand 1 "memory_displacement_only_operand" ""))
336                         (and (match_operand 0 "memory_displacement_only_operand" "")
337                              (match_operand 1 "ax_reg_operand" "")))))
338            (const_int 0)
339          (and (eq_attr "type" "call")
340               (match_operand 0 "constant_call_address_operand" ""))
341              (const_int 0)
342          (and (eq_attr "type" "callv")
343               (match_operand 1 "constant_call_address_operand" ""))
344              (const_int 0)
345          ]
346          (const_int 1)))
347
348 ;; The (bounding maximum) length of an instruction in bytes.
349 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
350 ;; Later we may want to split them and compute proper length as for
351 ;; other insns.
352 (define_attr "length" ""
353   (cond [(eq_attr "type" "other,multi,fistp,frndint")
354            (const_int 16)
355          (eq_attr "type" "fcmp")
356            (const_int 4)
357          (eq_attr "unit" "i387")
358            (plus (const_int 2)
359                  (plus (attr "prefix_data16")
360                        (attr "length_address")))]
361          (plus (plus (attr "modrm")
362                      (plus (attr "prefix_0f")
363                            (plus (attr "prefix_rex")
364                                  (const_int 1))))
365                (plus (attr "prefix_rep")
366                      (plus (attr "prefix_data16")
367                            (plus (attr "length_immediate")
368                                  (attr "length_address")))))))
369
370 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
371 ;; `store' if there is a simple memory reference therein, or `unknown'
372 ;; if the instruction is complex.
373
374 (define_attr "memory" "none,load,store,both,unknown"
375   (cond [(eq_attr "type" "other,multi,str")
376            (const_string "unknown")
377          (eq_attr "type" "lea,fcmov,fpspc")
378            (const_string "none")
379          (eq_attr "type" "fistp,leave")
380            (const_string "both")
381          (eq_attr "type" "frndint")
382            (const_string "load")
383          (eq_attr "type" "push")
384            (if_then_else (match_operand 1 "memory_operand" "")
385              (const_string "both")
386              (const_string "store"))
387          (eq_attr "type" "pop")
388            (if_then_else (match_operand 0 "memory_operand" "")
389              (const_string "both")
390              (const_string "load"))
391          (eq_attr "type" "setcc")
392            (if_then_else (match_operand 0 "memory_operand" "")
393              (const_string "store")
394              (const_string "none"))
395          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
396            (if_then_else (ior (match_operand 0 "memory_operand" "")
397                               (match_operand 1 "memory_operand" ""))
398              (const_string "load")
399              (const_string "none"))
400          (eq_attr "type" "ibr")
401            (if_then_else (match_operand 0 "memory_operand" "")
402              (const_string "load")
403              (const_string "none"))
404          (eq_attr "type" "call")
405            (if_then_else (match_operand 0 "constant_call_address_operand" "")
406              (const_string "none")
407              (const_string "load"))
408          (eq_attr "type" "callv")
409            (if_then_else (match_operand 1 "constant_call_address_operand" "")
410              (const_string "none")
411              (const_string "load"))
412          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
413               (match_operand 1 "memory_operand" ""))
414            (const_string "both")
415          (and (match_operand 0 "memory_operand" "")
416               (match_operand 1 "memory_operand" ""))
417            (const_string "both")
418          (match_operand 0 "memory_operand" "")
419            (const_string "store")
420          (match_operand 1 "memory_operand" "")
421            (const_string "load")
422          (and (eq_attr "type"
423                  "!alu1,negnot,ishift1,
424                    imov,imovx,icmp,test,bitmanip,
425                    fmov,fcmp,fsgn,
426                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
427                    mmx,mmxmov,mmxcmp,mmxcvt")
428               (match_operand 2 "memory_operand" ""))
429            (const_string "load")
430          (and (eq_attr "type" "icmov")
431               (match_operand 3 "memory_operand" ""))
432            (const_string "load")
433         ]
434         (const_string "none")))
435
436 ;; Indicates if an instruction has both an immediate and a displacement.
437
438 (define_attr "imm_disp" "false,true,unknown"
439   (cond [(eq_attr "type" "other,multi")
440            (const_string "unknown")
441          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
442               (and (match_operand 0 "memory_displacement_operand" "")
443                    (match_operand 1 "immediate_operand" "")))
444            (const_string "true")
445          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
446               (and (match_operand 0 "memory_displacement_operand" "")
447                    (match_operand 2 "immediate_operand" "")))
448            (const_string "true")
449         ]
450         (const_string "false")))
451
452 ;; Indicates if an FP operation has an integer source.
453
454 (define_attr "fp_int_src" "false,true"
455   (const_string "false"))
456
457 ;; Defines rounding mode of an FP operation.
458
459 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
460   (const_string "any"))
461
462 ;; Describe a user's asm statement.
463 (define_asm_attributes
464   [(set_attr "length" "128")
465    (set_attr "type" "multi")])
466
467 ;; All x87 floating point modes
468 (define_mode_macro X87MODEF [SF DF XF])
469
470 ;; x87 SFmode and DFMode floating point modes
471 (define_mode_macro X87MODEF12 [SF DF])
472
473 ;; All integer modes handled by x87 fisttp operator.
474 (define_mode_macro X87MODEI [HI SI DI])
475
476 ;; All integer modes handled by integer x87 operators.
477 (define_mode_macro X87MODEI12 [HI SI])
478
479 ;; All SSE floating point modes
480 (define_mode_macro SSEMODEF [SF DF])
481
482 ;; All integer modes handled by SSE cvtts?2si* operators.
483 (define_mode_macro SSEMODEI24 [SI DI])
484
485 ;; SSE asm suffix for floating point modes
486 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
487
488 ;; SSE vector mode corresponding to a scalar mode
489 (define_mode_attr ssevecmode
490   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
491 \f
492 ;; Scheduling descriptions
493
494 (include "pentium.md")
495 (include "ppro.md")
496 (include "k6.md")
497 (include "athlon.md")
498 (include "geode.md")
499
500 \f
501 ;; Operand and operator predicates and constraints
502
503 (include "predicates.md")
504 (include "constraints.md")
505
506 \f
507 ;; Compare instructions.
508
509 ;; All compare insns have expanders that save the operands away without
510 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
511 ;; after the cmp) will actually emit the cmpM.
512
513 (define_expand "cmpti"
514   [(set (reg:CC FLAGS_REG)
515         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
516                     (match_operand:TI 1 "x86_64_general_operand" "")))]
517   "TARGET_64BIT"
518 {
519   if (MEM_P (operands[0]) && MEM_P (operands[1]))
520     operands[0] = force_reg (TImode, operands[0]);
521   ix86_compare_op0 = operands[0];
522   ix86_compare_op1 = operands[1];
523   DONE;
524 })
525
526 (define_expand "cmpdi"
527   [(set (reg:CC FLAGS_REG)
528         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
529                     (match_operand:DI 1 "x86_64_general_operand" "")))]
530   ""
531 {
532   if (MEM_P (operands[0]) && MEM_P (operands[1]))
533     operands[0] = force_reg (DImode, operands[0]);
534   ix86_compare_op0 = operands[0];
535   ix86_compare_op1 = operands[1];
536   DONE;
537 })
538
539 (define_expand "cmpsi"
540   [(set (reg:CC FLAGS_REG)
541         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
542                     (match_operand:SI 1 "general_operand" "")))]
543   ""
544 {
545   if (MEM_P (operands[0]) && MEM_P (operands[1]))
546     operands[0] = force_reg (SImode, operands[0]);
547   ix86_compare_op0 = operands[0];
548   ix86_compare_op1 = operands[1];
549   DONE;
550 })
551
552 (define_expand "cmphi"
553   [(set (reg:CC FLAGS_REG)
554         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
555                     (match_operand:HI 1 "general_operand" "")))]
556   ""
557 {
558   if (MEM_P (operands[0]) && MEM_P (operands[1]))
559     operands[0] = force_reg (HImode, operands[0]);
560   ix86_compare_op0 = operands[0];
561   ix86_compare_op1 = operands[1];
562   DONE;
563 })
564
565 (define_expand "cmpqi"
566   [(set (reg:CC FLAGS_REG)
567         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
568                     (match_operand:QI 1 "general_operand" "")))]
569   "TARGET_QIMODE_MATH"
570 {
571   if (MEM_P (operands[0]) && MEM_P (operands[1]))
572     operands[0] = force_reg (QImode, operands[0]);
573   ix86_compare_op0 = operands[0];
574   ix86_compare_op1 = operands[1];
575   DONE;
576 })
577
578 (define_insn "cmpdi_ccno_1_rex64"
579   [(set (reg FLAGS_REG)
580         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
581                  (match_operand:DI 1 "const0_operand" "n,n")))]
582   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
583   "@
584    test{q}\t%0, %0
585    cmp{q}\t{%1, %0|%0, %1}"
586   [(set_attr "type" "test,icmp")
587    (set_attr "length_immediate" "0,1")
588    (set_attr "mode" "DI")])
589
590 (define_insn "*cmpdi_minus_1_rex64"
591   [(set (reg FLAGS_REG)
592         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
593                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
594                  (const_int 0)))]
595   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
596   "cmp{q}\t{%1, %0|%0, %1}"
597   [(set_attr "type" "icmp")
598    (set_attr "mode" "DI")])
599
600 (define_expand "cmpdi_1_rex64"
601   [(set (reg:CC FLAGS_REG)
602         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
603                     (match_operand:DI 1 "general_operand" "")))]
604   "TARGET_64BIT"
605   "")
606
607 (define_insn "cmpdi_1_insn_rex64"
608   [(set (reg FLAGS_REG)
609         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
610                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
611   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
612   "cmp{q}\t{%1, %0|%0, %1}"
613   [(set_attr "type" "icmp")
614    (set_attr "mode" "DI")])
615
616
617 (define_insn "*cmpsi_ccno_1"
618   [(set (reg FLAGS_REG)
619         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
620                  (match_operand:SI 1 "const0_operand" "n,n")))]
621   "ix86_match_ccmode (insn, CCNOmode)"
622   "@
623    test{l}\t%0, %0
624    cmp{l}\t{%1, %0|%0, %1}"
625   [(set_attr "type" "test,icmp")
626    (set_attr "length_immediate" "0,1")
627    (set_attr "mode" "SI")])
628
629 (define_insn "*cmpsi_minus_1"
630   [(set (reg FLAGS_REG)
631         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
632                            (match_operand:SI 1 "general_operand" "ri,mr"))
633                  (const_int 0)))]
634   "ix86_match_ccmode (insn, CCGOCmode)"
635   "cmp{l}\t{%1, %0|%0, %1}"
636   [(set_attr "type" "icmp")
637    (set_attr "mode" "SI")])
638
639 (define_expand "cmpsi_1"
640   [(set (reg:CC FLAGS_REG)
641         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
642                     (match_operand:SI 1 "general_operand" "ri,mr")))]
643   ""
644   "")
645
646 (define_insn "*cmpsi_1_insn"
647   [(set (reg FLAGS_REG)
648         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
649                  (match_operand:SI 1 "general_operand" "ri,mr")))]
650   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
651     && ix86_match_ccmode (insn, CCmode)"
652   "cmp{l}\t{%1, %0|%0, %1}"
653   [(set_attr "type" "icmp")
654    (set_attr "mode" "SI")])
655
656 (define_insn "*cmphi_ccno_1"
657   [(set (reg FLAGS_REG)
658         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
659                  (match_operand:HI 1 "const0_operand" "n,n")))]
660   "ix86_match_ccmode (insn, CCNOmode)"
661   "@
662    test{w}\t%0, %0
663    cmp{w}\t{%1, %0|%0, %1}"
664   [(set_attr "type" "test,icmp")
665    (set_attr "length_immediate" "0,1")
666    (set_attr "mode" "HI")])
667
668 (define_insn "*cmphi_minus_1"
669   [(set (reg FLAGS_REG)
670         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
671                            (match_operand:HI 1 "general_operand" "ri,mr"))
672                  (const_int 0)))]
673   "ix86_match_ccmode (insn, CCGOCmode)"
674   "cmp{w}\t{%1, %0|%0, %1}"
675   [(set_attr "type" "icmp")
676    (set_attr "mode" "HI")])
677
678 (define_insn "*cmphi_1"
679   [(set (reg FLAGS_REG)
680         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
681                  (match_operand:HI 1 "general_operand" "ri,mr")))]
682   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
683    && ix86_match_ccmode (insn, CCmode)"
684   "cmp{w}\t{%1, %0|%0, %1}"
685   [(set_attr "type" "icmp")
686    (set_attr "mode" "HI")])
687
688 (define_insn "*cmpqi_ccno_1"
689   [(set (reg FLAGS_REG)
690         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
691                  (match_operand:QI 1 "const0_operand" "n,n")))]
692   "ix86_match_ccmode (insn, CCNOmode)"
693   "@
694    test{b}\t%0, %0
695    cmp{b}\t{$0, %0|%0, 0}"
696   [(set_attr "type" "test,icmp")
697    (set_attr "length_immediate" "0,1")
698    (set_attr "mode" "QI")])
699
700 (define_insn "*cmpqi_1"
701   [(set (reg FLAGS_REG)
702         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
703                  (match_operand:QI 1 "general_operand" "qi,mq")))]
704   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
705     && ix86_match_ccmode (insn, CCmode)"
706   "cmp{b}\t{%1, %0|%0, %1}"
707   [(set_attr "type" "icmp")
708    (set_attr "mode" "QI")])
709
710 (define_insn "*cmpqi_minus_1"
711   [(set (reg FLAGS_REG)
712         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
713                            (match_operand:QI 1 "general_operand" "qi,mq"))
714                  (const_int 0)))]
715   "ix86_match_ccmode (insn, CCGOCmode)"
716   "cmp{b}\t{%1, %0|%0, %1}"
717   [(set_attr "type" "icmp")
718    (set_attr "mode" "QI")])
719
720 (define_insn "*cmpqi_ext_1"
721   [(set (reg FLAGS_REG)
722         (compare
723           (match_operand:QI 0 "general_operand" "Qm")
724           (subreg:QI
725             (zero_extract:SI
726               (match_operand 1 "ext_register_operand" "Q")
727               (const_int 8)
728               (const_int 8)) 0)))]
729   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
730   "cmp{b}\t{%h1, %0|%0, %h1}"
731   [(set_attr "type" "icmp")
732    (set_attr "mode" "QI")])
733
734 (define_insn "*cmpqi_ext_1_rex64"
735   [(set (reg FLAGS_REG)
736         (compare
737           (match_operand:QI 0 "register_operand" "Q")
738           (subreg:QI
739             (zero_extract:SI
740               (match_operand 1 "ext_register_operand" "Q")
741               (const_int 8)
742               (const_int 8)) 0)))]
743   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
744   "cmp{b}\t{%h1, %0|%0, %h1}"
745   [(set_attr "type" "icmp")
746    (set_attr "mode" "QI")])
747
748 (define_insn "*cmpqi_ext_2"
749   [(set (reg FLAGS_REG)
750         (compare
751           (subreg:QI
752             (zero_extract:SI
753               (match_operand 0 "ext_register_operand" "Q")
754               (const_int 8)
755               (const_int 8)) 0)
756           (match_operand:QI 1 "const0_operand" "n")))]
757   "ix86_match_ccmode (insn, CCNOmode)"
758   "test{b}\t%h0, %h0"
759   [(set_attr "type" "test")
760    (set_attr "length_immediate" "0")
761    (set_attr "mode" "QI")])
762
763 (define_expand "cmpqi_ext_3"
764   [(set (reg:CC FLAGS_REG)
765         (compare:CC
766           (subreg:QI
767             (zero_extract:SI
768               (match_operand 0 "ext_register_operand" "")
769               (const_int 8)
770               (const_int 8)) 0)
771           (match_operand:QI 1 "general_operand" "")))]
772   ""
773   "")
774
775 (define_insn "cmpqi_ext_3_insn"
776   [(set (reg FLAGS_REG)
777         (compare
778           (subreg:QI
779             (zero_extract:SI
780               (match_operand 0 "ext_register_operand" "Q")
781               (const_int 8)
782               (const_int 8)) 0)
783           (match_operand:QI 1 "general_operand" "Qmn")))]
784   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
785   "cmp{b}\t{%1, %h0|%h0, %1}"
786   [(set_attr "type" "icmp")
787    (set_attr "mode" "QI")])
788
789 (define_insn "cmpqi_ext_3_insn_rex64"
790   [(set (reg FLAGS_REG)
791         (compare
792           (subreg:QI
793             (zero_extract:SI
794               (match_operand 0 "ext_register_operand" "Q")
795               (const_int 8)
796               (const_int 8)) 0)
797           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
798   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
799   "cmp{b}\t{%1, %h0|%h0, %1}"
800   [(set_attr "type" "icmp")
801    (set_attr "mode" "QI")])
802
803 (define_insn "*cmpqi_ext_4"
804   [(set (reg FLAGS_REG)
805         (compare
806           (subreg:QI
807             (zero_extract:SI
808               (match_operand 0 "ext_register_operand" "Q")
809               (const_int 8)
810               (const_int 8)) 0)
811           (subreg:QI
812             (zero_extract:SI
813               (match_operand 1 "ext_register_operand" "Q")
814               (const_int 8)
815               (const_int 8)) 0)))]
816   "ix86_match_ccmode (insn, CCmode)"
817   "cmp{b}\t{%h1, %h0|%h0, %h1}"
818   [(set_attr "type" "icmp")
819    (set_attr "mode" "QI")])
820
821 ;; These implement float point compares.
822 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
823 ;; which would allow mix and match FP modes on the compares.  Which is what
824 ;; the old patterns did, but with many more of them.
825
826 (define_expand "cmpxf"
827   [(set (reg:CC FLAGS_REG)
828         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
829                     (match_operand:XF 1 "nonmemory_operand" "")))]
830   "TARGET_80387"
831 {
832   ix86_compare_op0 = operands[0];
833   ix86_compare_op1 = operands[1];
834   DONE;
835 })
836
837 (define_expand "cmpdf"
838   [(set (reg:CC FLAGS_REG)
839         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
840                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
841   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
842 {
843   ix86_compare_op0 = operands[0];
844   ix86_compare_op1 = operands[1];
845   DONE;
846 })
847
848 (define_expand "cmpsf"
849   [(set (reg:CC FLAGS_REG)
850         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
851                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
852   "TARGET_80387 || TARGET_SSE_MATH"
853 {
854   ix86_compare_op0 = operands[0];
855   ix86_compare_op1 = operands[1];
856   DONE;
857 })
858
859 ;; FP compares, step 1:
860 ;; Set the FP condition codes.
861 ;;
862 ;; CCFPmode     compare with exceptions
863 ;; CCFPUmode    compare with no exceptions
864
865 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
866 ;; used to manage the reg stack popping would not be preserved.
867
868 (define_insn "*cmpfp_0"
869   [(set (match_operand:HI 0 "register_operand" "=a")
870         (unspec:HI
871           [(compare:CCFP
872              (match_operand 1 "register_operand" "f")
873              (match_operand 2 "const0_operand" "X"))]
874         UNSPEC_FNSTSW))]
875   "TARGET_80387
876    && FLOAT_MODE_P (GET_MODE (operands[1]))
877    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
878   "* return output_fp_compare (insn, operands, 0, 0);"
879   [(set_attr "type" "multi")
880    (set_attr "unit" "i387")
881    (set (attr "mode")
882      (cond [(match_operand:SF 1 "" "")
883               (const_string "SF")
884             (match_operand:DF 1 "" "")
885               (const_string "DF")
886            ]
887            (const_string "XF")))])
888
889 (define_insn "*cmpfp_sf"
890   [(set (match_operand:HI 0 "register_operand" "=a")
891         (unspec:HI
892           [(compare:CCFP
893              (match_operand:SF 1 "register_operand" "f")
894              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
895           UNSPEC_FNSTSW))]
896   "TARGET_80387"
897   "* return output_fp_compare (insn, operands, 0, 0);"
898   [(set_attr "type" "multi")
899    (set_attr "unit" "i387")
900    (set_attr "mode" "SF")])
901
902 (define_insn "*cmpfp_df"
903   [(set (match_operand:HI 0 "register_operand" "=a")
904         (unspec:HI
905           [(compare:CCFP
906              (match_operand:DF 1 "register_operand" "f")
907              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
908           UNSPEC_FNSTSW))]
909   "TARGET_80387"
910   "* return output_fp_compare (insn, operands, 0, 0);"
911   [(set_attr "type" "multi")
912    (set_attr "unit" "i387")
913    (set_attr "mode" "DF")])
914
915 (define_insn "*cmpfp_xf"
916   [(set (match_operand:HI 0 "register_operand" "=a")
917         (unspec:HI
918           [(compare:CCFP
919              (match_operand:XF 1 "register_operand" "f")
920              (match_operand:XF 2 "register_operand" "f"))]
921           UNSPEC_FNSTSW))]
922   "TARGET_80387"
923   "* return output_fp_compare (insn, operands, 0, 0);"
924   [(set_attr "type" "multi")
925    (set_attr "unit" "i387")
926    (set_attr "mode" "XF")])
927
928 (define_insn "*cmpfp_u"
929   [(set (match_operand:HI 0 "register_operand" "=a")
930         (unspec:HI
931           [(compare:CCFPU
932              (match_operand 1 "register_operand" "f")
933              (match_operand 2 "register_operand" "f"))]
934           UNSPEC_FNSTSW))]
935   "TARGET_80387
936    && FLOAT_MODE_P (GET_MODE (operands[1]))
937    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
938   "* return output_fp_compare (insn, operands, 0, 1);"
939   [(set_attr "type" "multi")
940    (set_attr "unit" "i387")
941    (set (attr "mode")
942      (cond [(match_operand:SF 1 "" "")
943               (const_string "SF")
944             (match_operand:DF 1 "" "")
945               (const_string "DF")
946            ]
947            (const_string "XF")))])
948
949 (define_insn "*cmpfp_<mode>"
950   [(set (match_operand:HI 0 "register_operand" "=a")
951         (unspec:HI
952           [(compare:CCFP
953              (match_operand 1 "register_operand" "f")
954              (match_operator 3 "float_operator"
955                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
956           UNSPEC_FNSTSW))]
957   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
958    && FLOAT_MODE_P (GET_MODE (operands[1]))
959    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
960   "* return output_fp_compare (insn, operands, 0, 0);"
961   [(set_attr "type" "multi")
962    (set_attr "unit" "i387")
963    (set_attr "fp_int_src" "true")
964    (set_attr "mode" "<MODE>")])
965
966 ;; FP compares, step 2
967 ;; Move the fpsw to ax.
968
969 (define_insn "x86_fnstsw_1"
970   [(set (match_operand:HI 0 "register_operand" "=a")
971         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
972   "TARGET_80387"
973   "fnstsw\t%0"
974   [(set_attr "length" "2")
975    (set_attr "mode" "SI")
976    (set_attr "unit" "i387")])
977
978 ;; FP compares, step 3
979 ;; Get ax into flags, general case.
980
981 (define_insn "x86_sahf_1"
982   [(set (reg:CC FLAGS_REG)
983         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
984   "!TARGET_64BIT"
985   "sahf"
986   [(set_attr "length" "1")
987    (set_attr "athlon_decode" "vector")
988    (set_attr "amdfam10_decode" "direct")
989    (set_attr "mode" "SI")])
990
991 ;; Pentium Pro can do steps 1 through 3 in one go.
992 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes) 
993 (define_insn "*cmpfp_i_mixed"
994   [(set (reg:CCFP FLAGS_REG)
995         (compare:CCFP (match_operand 0 "register_operand" "f,x")
996                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
997   "TARGET_MIX_SSE_I387
998    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
999    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1000   "* return output_fp_compare (insn, operands, 1, 0);"
1001   [(set_attr "type" "fcmp,ssecomi")
1002    (set (attr "mode")
1003      (if_then_else (match_operand:SF 1 "" "")
1004         (const_string "SF")
1005         (const_string "DF")))
1006    (set_attr "athlon_decode" "vector")
1007    (set_attr "amdfam10_decode" "direct")])
1008
1009 (define_insn "*cmpfp_i_sse"
1010   [(set (reg:CCFP FLAGS_REG)
1011         (compare:CCFP (match_operand 0 "register_operand" "x")
1012                       (match_operand 1 "nonimmediate_operand" "xm")))]
1013   "TARGET_SSE_MATH
1014    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1015    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1016   "* return output_fp_compare (insn, operands, 1, 0);"
1017   [(set_attr "type" "ssecomi")
1018    (set (attr "mode")
1019      (if_then_else (match_operand:SF 1 "" "")
1020         (const_string "SF")
1021         (const_string "DF")))
1022    (set_attr "athlon_decode" "vector")
1023    (set_attr "amdfam10_decode" "direct")])
1024
1025 (define_insn "*cmpfp_i_i387"
1026   [(set (reg:CCFP FLAGS_REG)
1027         (compare:CCFP (match_operand 0 "register_operand" "f")
1028                       (match_operand 1 "register_operand" "f")))]
1029   "TARGET_80387 && TARGET_CMOVE
1030    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1031    && FLOAT_MODE_P (GET_MODE (operands[0]))
1032    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1033   "* return output_fp_compare (insn, operands, 1, 0);"
1034   [(set_attr "type" "fcmp")
1035    (set (attr "mode")
1036      (cond [(match_operand:SF 1 "" "")
1037               (const_string "SF")
1038             (match_operand:DF 1 "" "")
1039               (const_string "DF")
1040            ]
1041            (const_string "XF")))
1042    (set_attr "athlon_decode" "vector")
1043    (set_attr "amdfam10_decode" "direct")])
1044
1045 (define_insn "*cmpfp_iu_mixed"
1046   [(set (reg:CCFPU FLAGS_REG)
1047         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1048                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1049   "TARGET_MIX_SSE_I387
1050    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1051    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1052   "* return output_fp_compare (insn, operands, 1, 1);"
1053   [(set_attr "type" "fcmp,ssecomi")
1054    (set (attr "mode")
1055      (if_then_else (match_operand:SF 1 "" "")
1056         (const_string "SF")
1057         (const_string "DF")))
1058    (set_attr "athlon_decode" "vector")
1059    (set_attr "amdfam10_decode" "direct")])
1060
1061 (define_insn "*cmpfp_iu_sse"
1062   [(set (reg:CCFPU FLAGS_REG)
1063         (compare:CCFPU (match_operand 0 "register_operand" "x")
1064                        (match_operand 1 "nonimmediate_operand" "xm")))]
1065   "TARGET_SSE_MATH
1066    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1067    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1068   "* return output_fp_compare (insn, operands, 1, 1);"
1069   [(set_attr "type" "ssecomi")
1070    (set (attr "mode")
1071      (if_then_else (match_operand:SF 1 "" "")
1072         (const_string "SF")
1073         (const_string "DF")))
1074    (set_attr "athlon_decode" "vector")
1075    (set_attr "amdfam10_decode" "direct")])
1076
1077 (define_insn "*cmpfp_iu_387"
1078   [(set (reg:CCFPU FLAGS_REG)
1079         (compare:CCFPU (match_operand 0 "register_operand" "f")
1080                        (match_operand 1 "register_operand" "f")))]
1081   "TARGET_80387 && TARGET_CMOVE
1082    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1083    && FLOAT_MODE_P (GET_MODE (operands[0]))
1084    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1085   "* return output_fp_compare (insn, operands, 1, 1);"
1086   [(set_attr "type" "fcmp")
1087    (set (attr "mode")
1088      (cond [(match_operand:SF 1 "" "")
1089               (const_string "SF")
1090             (match_operand:DF 1 "" "")
1091               (const_string "DF")
1092            ]
1093            (const_string "XF")))
1094    (set_attr "athlon_decode" "vector")
1095    (set_attr "amdfam10_decode" "direct")])
1096 \f
1097 ;; Move instructions.
1098
1099 ;; General case of fullword move.
1100
1101 (define_expand "movsi"
1102   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1103         (match_operand:SI 1 "general_operand" ""))]
1104   ""
1105   "ix86_expand_move (SImode, operands); DONE;")
1106
1107 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1108 ;; general_operand.
1109 ;;
1110 ;; %%% We don't use a post-inc memory reference because x86 is not a
1111 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1112 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1113 ;; targets without our curiosities, and it is just as easy to represent
1114 ;; this differently.
1115
1116 (define_insn "*pushsi2"
1117   [(set (match_operand:SI 0 "push_operand" "=<")
1118         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1119   "!TARGET_64BIT"
1120   "push{l}\t%1"
1121   [(set_attr "type" "push")
1122    (set_attr "mode" "SI")])
1123
1124 ;; For 64BIT abi we always round up to 8 bytes.
1125 (define_insn "*pushsi2_rex64"
1126   [(set (match_operand:SI 0 "push_operand" "=X")
1127         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1128   "TARGET_64BIT"
1129   "push{q}\t%q1"
1130   [(set_attr "type" "push")
1131    (set_attr "mode" "SI")])
1132
1133 (define_insn "*pushsi2_prologue"
1134   [(set (match_operand:SI 0 "push_operand" "=<")
1135         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1136    (clobber (mem:BLK (scratch)))]
1137   "!TARGET_64BIT"
1138   "push{l}\t%1"
1139   [(set_attr "type" "push")
1140    (set_attr "mode" "SI")])
1141
1142 (define_insn "*popsi1_epilogue"
1143   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1144         (mem:SI (reg:SI SP_REG)))
1145    (set (reg:SI SP_REG)
1146         (plus:SI (reg:SI SP_REG) (const_int 4)))
1147    (clobber (mem:BLK (scratch)))]
1148   "!TARGET_64BIT"
1149   "pop{l}\t%0"
1150   [(set_attr "type" "pop")
1151    (set_attr "mode" "SI")])
1152
1153 (define_insn "popsi1"
1154   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1155         (mem:SI (reg:SI SP_REG)))
1156    (set (reg:SI SP_REG)
1157         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1158   "!TARGET_64BIT"
1159   "pop{l}\t%0"
1160   [(set_attr "type" "pop")
1161    (set_attr "mode" "SI")])
1162
1163 (define_insn "*movsi_xor"
1164   [(set (match_operand:SI 0 "register_operand" "=r")
1165         (match_operand:SI 1 "const0_operand" "i"))
1166    (clobber (reg:CC FLAGS_REG))]
1167   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1168   "xor{l}\t%0, %0"
1169   [(set_attr "type" "alu1")
1170    (set_attr "mode" "SI")
1171    (set_attr "length_immediate" "0")])
1172
1173 (define_insn "*movsi_or"
1174   [(set (match_operand:SI 0 "register_operand" "=r")
1175         (match_operand:SI 1 "immediate_operand" "i"))
1176    (clobber (reg:CC FLAGS_REG))]
1177   "reload_completed
1178    && operands[1] == constm1_rtx
1179    && (TARGET_PENTIUM || optimize_size)"
1180 {
1181   operands[1] = constm1_rtx;
1182   return "or{l}\t{%1, %0|%0, %1}";
1183 }
1184   [(set_attr "type" "alu1")
1185    (set_attr "mode" "SI")
1186    (set_attr "length_immediate" "1")])
1187
1188 (define_insn "*movsi_1"
1189   [(set (match_operand:SI 0 "nonimmediate_operand"
1190                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1191         (match_operand:SI 1 "general_operand"
1192                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1193   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1194 {
1195   switch (get_attr_type (insn))
1196     {
1197     case TYPE_SSELOG1:
1198       if (get_attr_mode (insn) == MODE_TI)
1199         return "pxor\t%0, %0";
1200       return "xorps\t%0, %0";
1201
1202     case TYPE_SSEMOV:
1203       switch (get_attr_mode (insn))
1204         {
1205         case MODE_TI:
1206           return "movdqa\t{%1, %0|%0, %1}";
1207         case MODE_V4SF:
1208           return "movaps\t{%1, %0|%0, %1}";
1209         case MODE_SI:
1210           return "movd\t{%1, %0|%0, %1}";
1211         case MODE_SF:
1212           return "movss\t{%1, %0|%0, %1}";
1213         default:
1214           gcc_unreachable ();
1215         }
1216
1217     case TYPE_MMXADD:
1218       return "pxor\t%0, %0";
1219
1220     case TYPE_MMXMOV:
1221       if (get_attr_mode (insn) == MODE_DI)
1222         return "movq\t{%1, %0|%0, %1}";
1223       return "movd\t{%1, %0|%0, %1}";
1224
1225     case TYPE_LEA:
1226       return "lea{l}\t{%1, %0|%0, %1}";
1227
1228     default:
1229       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1230       return "mov{l}\t{%1, %0|%0, %1}";
1231     }
1232 }
1233   [(set (attr "type")
1234      (cond [(eq_attr "alternative" "2")
1235               (const_string "mmxadd")
1236             (eq_attr "alternative" "3,4,5")
1237               (const_string "mmxmov")
1238             (eq_attr "alternative" "6")
1239               (const_string "sselog1")
1240             (eq_attr "alternative" "7,8,9,10,11")
1241               (const_string "ssemov")
1242             (match_operand:DI 1 "pic_32bit_operand" "")
1243               (const_string "lea")
1244            ]
1245            (const_string "imov")))
1246    (set (attr "mode")
1247      (cond [(eq_attr "alternative" "2,3")
1248               (const_string "DI")
1249             (eq_attr "alternative" "6,7")
1250               (if_then_else
1251                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1252                 (const_string "V4SF")
1253                 (const_string "TI"))
1254             (and (eq_attr "alternative" "8,9,10,11")
1255                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1256               (const_string "SF")
1257            ]
1258            (const_string "SI")))])
1259
1260 ;; Stores and loads of ax to arbitrary constant address.
1261 ;; We fake an second form of instruction to force reload to load address
1262 ;; into register when rax is not available
1263 (define_insn "*movabssi_1_rex64"
1264   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1265         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1266   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1267   "@
1268    movabs{l}\t{%1, %P0|%P0, %1}
1269    mov{l}\t{%1, %a0|%a0, %1}"
1270   [(set_attr "type" "imov")
1271    (set_attr "modrm" "0,*")
1272    (set_attr "length_address" "8,0")
1273    (set_attr "length_immediate" "0,*")
1274    (set_attr "memory" "store")
1275    (set_attr "mode" "SI")])
1276
1277 (define_insn "*movabssi_2_rex64"
1278   [(set (match_operand:SI 0 "register_operand" "=a,r")
1279         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1280   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1281   "@
1282    movabs{l}\t{%P1, %0|%0, %P1}
1283    mov{l}\t{%a1, %0|%0, %a1}"
1284   [(set_attr "type" "imov")
1285    (set_attr "modrm" "0,*")
1286    (set_attr "length_address" "8,0")
1287    (set_attr "length_immediate" "0")
1288    (set_attr "memory" "load")
1289    (set_attr "mode" "SI")])
1290
1291 (define_insn "*swapsi"
1292   [(set (match_operand:SI 0 "register_operand" "+r")
1293         (match_operand:SI 1 "register_operand" "+r"))
1294    (set (match_dup 1)
1295         (match_dup 0))]
1296   ""
1297   "xchg{l}\t%1, %0"
1298   [(set_attr "type" "imov")
1299    (set_attr "mode" "SI")
1300    (set_attr "pent_pair" "np")
1301    (set_attr "athlon_decode" "vector")
1302    (set_attr "amdfam10_decode" "double")])   
1303
1304 (define_expand "movhi"
1305   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1306         (match_operand:HI 1 "general_operand" ""))]
1307   ""
1308   "ix86_expand_move (HImode, operands); DONE;")
1309
1310 (define_insn "*pushhi2"
1311   [(set (match_operand:HI 0 "push_operand" "=X")
1312         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1313   "!TARGET_64BIT"
1314   "push{l}\t%k1"
1315   [(set_attr "type" "push")
1316    (set_attr "mode" "SI")])
1317
1318 ;; For 64BIT abi we always round up to 8 bytes.
1319 (define_insn "*pushhi2_rex64"
1320   [(set (match_operand:HI 0 "push_operand" "=X")
1321         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1322   "TARGET_64BIT"
1323   "push{q}\t%q1"
1324   [(set_attr "type" "push")
1325    (set_attr "mode" "DI")])
1326
1327 (define_insn "*movhi_1"
1328   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1329         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1330   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1331 {
1332   switch (get_attr_type (insn))
1333     {
1334     case TYPE_IMOVX:
1335       /* movzwl is faster than movw on p2 due to partial word stalls,
1336          though not as fast as an aligned movl.  */
1337       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1338     default:
1339       if (get_attr_mode (insn) == MODE_SI)
1340         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1341       else
1342         return "mov{w}\t{%1, %0|%0, %1}";
1343     }
1344 }
1345   [(set (attr "type")
1346      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1347               (const_string "imov")
1348             (and (eq_attr "alternative" "0")
1349                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1350                           (const_int 0))
1351                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1352                           (const_int 0))))
1353               (const_string "imov")
1354             (and (eq_attr "alternative" "1,2")
1355                  (match_operand:HI 1 "aligned_operand" ""))
1356               (const_string "imov")
1357             (and (ne (symbol_ref "TARGET_MOVX")
1358                      (const_int 0))
1359                  (eq_attr "alternative" "0,2"))
1360               (const_string "imovx")
1361            ]
1362            (const_string "imov")))
1363     (set (attr "mode")
1364       (cond [(eq_attr "type" "imovx")
1365                (const_string "SI")
1366              (and (eq_attr "alternative" "1,2")
1367                   (match_operand:HI 1 "aligned_operand" ""))
1368                (const_string "SI")
1369              (and (eq_attr "alternative" "0")
1370                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1371                            (const_int 0))
1372                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1373                            (const_int 0))))
1374                (const_string "SI")
1375             ]
1376             (const_string "HI")))])
1377
1378 ;; Stores and loads of ax to arbitrary constant address.
1379 ;; We fake an second form of instruction to force reload to load address
1380 ;; into register when rax is not available
1381 (define_insn "*movabshi_1_rex64"
1382   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1383         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1384   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1385   "@
1386    movabs{w}\t{%1, %P0|%P0, %1}
1387    mov{w}\t{%1, %a0|%a0, %1}"
1388   [(set_attr "type" "imov")
1389    (set_attr "modrm" "0,*")
1390    (set_attr "length_address" "8,0")
1391    (set_attr "length_immediate" "0,*")
1392    (set_attr "memory" "store")
1393    (set_attr "mode" "HI")])
1394
1395 (define_insn "*movabshi_2_rex64"
1396   [(set (match_operand:HI 0 "register_operand" "=a,r")
1397         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1398   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1399   "@
1400    movabs{w}\t{%P1, %0|%0, %P1}
1401    mov{w}\t{%a1, %0|%0, %a1}"
1402   [(set_attr "type" "imov")
1403    (set_attr "modrm" "0,*")
1404    (set_attr "length_address" "8,0")
1405    (set_attr "length_immediate" "0")
1406    (set_attr "memory" "load")
1407    (set_attr "mode" "HI")])
1408
1409 (define_insn "*swaphi_1"
1410   [(set (match_operand:HI 0 "register_operand" "+r")
1411         (match_operand:HI 1 "register_operand" "+r"))
1412    (set (match_dup 1)
1413         (match_dup 0))]
1414   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1415   "xchg{l}\t%k1, %k0"
1416   [(set_attr "type" "imov")
1417    (set_attr "mode" "SI")
1418    (set_attr "pent_pair" "np")
1419    (set_attr "athlon_decode" "vector")
1420    (set_attr "amdfam10_decode" "double")])   
1421
1422 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1423 (define_insn "*swaphi_2"
1424   [(set (match_operand:HI 0 "register_operand" "+r")
1425         (match_operand:HI 1 "register_operand" "+r"))
1426    (set (match_dup 1)
1427         (match_dup 0))]
1428   "TARGET_PARTIAL_REG_STALL"
1429   "xchg{w}\t%1, %0"
1430   [(set_attr "type" "imov")
1431    (set_attr "mode" "HI")
1432    (set_attr "pent_pair" "np")
1433    (set_attr "athlon_decode" "vector")])
1434
1435 (define_expand "movstricthi"
1436   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1437         (match_operand:HI 1 "general_operand" ""))]
1438   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1439 {
1440   /* Don't generate memory->memory moves, go through a register */
1441   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1442     operands[1] = force_reg (HImode, operands[1]);
1443 })
1444
1445 (define_insn "*movstricthi_1"
1446   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1447         (match_operand:HI 1 "general_operand" "rn,m"))]
1448   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1449    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1450   "mov{w}\t{%1, %0|%0, %1}"
1451   [(set_attr "type" "imov")
1452    (set_attr "mode" "HI")])
1453
1454 (define_insn "*movstricthi_xor"
1455   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1456         (match_operand:HI 1 "const0_operand" "i"))
1457    (clobber (reg:CC FLAGS_REG))]
1458   "reload_completed
1459    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1460   "xor{w}\t%0, %0"
1461   [(set_attr "type" "alu1")
1462    (set_attr "mode" "HI")
1463    (set_attr "length_immediate" "0")])
1464
1465 (define_expand "movqi"
1466   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1467         (match_operand:QI 1 "general_operand" ""))]
1468   ""
1469   "ix86_expand_move (QImode, operands); DONE;")
1470
1471 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1472 ;; "push a byte".  But actually we use pushl, which has the effect
1473 ;; of rounding the amount pushed up to a word.
1474
1475 (define_insn "*pushqi2"
1476   [(set (match_operand:QI 0 "push_operand" "=X")
1477         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1478   "!TARGET_64BIT"
1479   "push{l}\t%k1"
1480   [(set_attr "type" "push")
1481    (set_attr "mode" "SI")])
1482
1483 ;; For 64BIT abi we always round up to 8 bytes.
1484 (define_insn "*pushqi2_rex64"
1485   [(set (match_operand:QI 0 "push_operand" "=X")
1486         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1487   "TARGET_64BIT"
1488   "push{q}\t%q1"
1489   [(set_attr "type" "push")
1490    (set_attr "mode" "DI")])
1491
1492 ;; Situation is quite tricky about when to choose full sized (SImode) move
1493 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1494 ;; partial register dependency machines (such as AMD Athlon), where QImode
1495 ;; moves issue extra dependency and for partial register stalls machines
1496 ;; that don't use QImode patterns (and QImode move cause stall on the next
1497 ;; instruction).
1498 ;;
1499 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1500 ;; register stall machines with, where we use QImode instructions, since
1501 ;; partial register stall can be caused there.  Then we use movzx.
1502 (define_insn "*movqi_1"
1503   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1504         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1505   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1506 {
1507   switch (get_attr_type (insn))
1508     {
1509     case TYPE_IMOVX:
1510       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1511       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1512     default:
1513       if (get_attr_mode (insn) == MODE_SI)
1514         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1515       else
1516         return "mov{b}\t{%1, %0|%0, %1}";
1517     }
1518 }
1519   [(set (attr "type")
1520      (cond [(and (eq_attr "alternative" "5")
1521                  (not (match_operand:QI 1 "aligned_operand" "")))
1522               (const_string "imovx")
1523             (ne (symbol_ref "optimize_size") (const_int 0))
1524               (const_string "imov")
1525             (and (eq_attr "alternative" "3")
1526                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1527                           (const_int 0))
1528                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1529                           (const_int 0))))
1530               (const_string "imov")
1531             (eq_attr "alternative" "3,5")
1532               (const_string "imovx")
1533             (and (ne (symbol_ref "TARGET_MOVX")
1534                      (const_int 0))
1535                  (eq_attr "alternative" "2"))
1536               (const_string "imovx")
1537            ]
1538            (const_string "imov")))
1539    (set (attr "mode")
1540       (cond [(eq_attr "alternative" "3,4,5")
1541                (const_string "SI")
1542              (eq_attr "alternative" "6")
1543                (const_string "QI")
1544              (eq_attr "type" "imovx")
1545                (const_string "SI")
1546              (and (eq_attr "type" "imov")
1547                   (and (eq_attr "alternative" "0,1")
1548                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1549                                 (const_int 0))
1550                             (and (eq (symbol_ref "optimize_size")
1551                                      (const_int 0))
1552                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1553                                      (const_int 0))))))
1554                (const_string "SI")
1555              ;; Avoid partial register stalls when not using QImode arithmetic
1556              (and (eq_attr "type" "imov")
1557                   (and (eq_attr "alternative" "0,1")
1558                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1559                                 (const_int 0))
1560                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1561                                 (const_int 0)))))
1562                (const_string "SI")
1563            ]
1564            (const_string "QI")))])
1565
1566 (define_expand "reload_outqi"
1567   [(parallel [(match_operand:QI 0 "" "=m")
1568               (match_operand:QI 1 "register_operand" "r")
1569               (match_operand:QI 2 "register_operand" "=&q")])]
1570   ""
1571 {
1572   rtx op0, op1, op2;
1573   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1574
1575   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1576   if (! q_regs_operand (op1, QImode))
1577     {
1578       emit_insn (gen_movqi (op2, op1));
1579       op1 = op2;
1580     }
1581   emit_insn (gen_movqi (op0, op1));
1582   DONE;
1583 })
1584
1585 (define_insn "*swapqi_1"
1586   [(set (match_operand:QI 0 "register_operand" "+r")
1587         (match_operand:QI 1 "register_operand" "+r"))
1588    (set (match_dup 1)
1589         (match_dup 0))]
1590   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1591   "xchg{l}\t%k1, %k0"
1592   [(set_attr "type" "imov")
1593    (set_attr "mode" "SI")
1594    (set_attr "pent_pair" "np")
1595    (set_attr "athlon_decode" "vector")
1596    (set_attr "amdfam10_decode" "vector")])   
1597
1598 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1599 (define_insn "*swapqi_2"
1600   [(set (match_operand:QI 0 "register_operand" "+q")
1601         (match_operand:QI 1 "register_operand" "+q"))
1602    (set (match_dup 1)
1603         (match_dup 0))]
1604   "TARGET_PARTIAL_REG_STALL"
1605   "xchg{b}\t%1, %0"
1606   [(set_attr "type" "imov")
1607    (set_attr "mode" "QI")
1608    (set_attr "pent_pair" "np")
1609    (set_attr "athlon_decode" "vector")])
1610
1611 (define_expand "movstrictqi"
1612   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1613         (match_operand:QI 1 "general_operand" ""))]
1614   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1615 {
1616   /* Don't generate memory->memory moves, go through a register.  */
1617   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1618     operands[1] = force_reg (QImode, operands[1]);
1619 })
1620
1621 (define_insn "*movstrictqi_1"
1622   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1623         (match_operand:QI 1 "general_operand" "*qn,m"))]
1624   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1625    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1626   "mov{b}\t{%1, %0|%0, %1}"
1627   [(set_attr "type" "imov")
1628    (set_attr "mode" "QI")])
1629
1630 (define_insn "*movstrictqi_xor"
1631   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1632         (match_operand:QI 1 "const0_operand" "i"))
1633    (clobber (reg:CC FLAGS_REG))]
1634   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1635   "xor{b}\t%0, %0"
1636   [(set_attr "type" "alu1")
1637    (set_attr "mode" "QI")
1638    (set_attr "length_immediate" "0")])
1639
1640 (define_insn "*movsi_extv_1"
1641   [(set (match_operand:SI 0 "register_operand" "=R")
1642         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1643                          (const_int 8)
1644                          (const_int 8)))]
1645   ""
1646   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1647   [(set_attr "type" "imovx")
1648    (set_attr "mode" "SI")])
1649
1650 (define_insn "*movhi_extv_1"
1651   [(set (match_operand:HI 0 "register_operand" "=R")
1652         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1653                          (const_int 8)
1654                          (const_int 8)))]
1655   ""
1656   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1657   [(set_attr "type" "imovx")
1658    (set_attr "mode" "SI")])
1659
1660 (define_insn "*movqi_extv_1"
1661   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1662         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1663                          (const_int 8)
1664                          (const_int 8)))]
1665   "!TARGET_64BIT"
1666 {
1667   switch (get_attr_type (insn))
1668     {
1669     case TYPE_IMOVX:
1670       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1671     default:
1672       return "mov{b}\t{%h1, %0|%0, %h1}";
1673     }
1674 }
1675   [(set (attr "type")
1676      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1677                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1678                              (ne (symbol_ref "TARGET_MOVX")
1679                                  (const_int 0))))
1680         (const_string "imovx")
1681         (const_string "imov")))
1682    (set (attr "mode")
1683      (if_then_else (eq_attr "type" "imovx")
1684         (const_string "SI")
1685         (const_string "QI")))])
1686
1687 (define_insn "*movqi_extv_1_rex64"
1688   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1689         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1690                          (const_int 8)
1691                          (const_int 8)))]
1692   "TARGET_64BIT"
1693 {
1694   switch (get_attr_type (insn))
1695     {
1696     case TYPE_IMOVX:
1697       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1698     default:
1699       return "mov{b}\t{%h1, %0|%0, %h1}";
1700     }
1701 }
1702   [(set (attr "type")
1703      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1704                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1705                              (ne (symbol_ref "TARGET_MOVX")
1706                                  (const_int 0))))
1707         (const_string "imovx")
1708         (const_string "imov")))
1709    (set (attr "mode")
1710      (if_then_else (eq_attr "type" "imovx")
1711         (const_string "SI")
1712         (const_string "QI")))])
1713
1714 ;; Stores and loads of ax to arbitrary constant address.
1715 ;; We fake an second form of instruction to force reload to load address
1716 ;; into register when rax is not available
1717 (define_insn "*movabsqi_1_rex64"
1718   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1719         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1720   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1721   "@
1722    movabs{b}\t{%1, %P0|%P0, %1}
1723    mov{b}\t{%1, %a0|%a0, %1}"
1724   [(set_attr "type" "imov")
1725    (set_attr "modrm" "0,*")
1726    (set_attr "length_address" "8,0")
1727    (set_attr "length_immediate" "0,*")
1728    (set_attr "memory" "store")
1729    (set_attr "mode" "QI")])
1730
1731 (define_insn "*movabsqi_2_rex64"
1732   [(set (match_operand:QI 0 "register_operand" "=a,r")
1733         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1734   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1735   "@
1736    movabs{b}\t{%P1, %0|%0, %P1}
1737    mov{b}\t{%a1, %0|%0, %a1}"
1738   [(set_attr "type" "imov")
1739    (set_attr "modrm" "0,*")
1740    (set_attr "length_address" "8,0")
1741    (set_attr "length_immediate" "0")
1742    (set_attr "memory" "load")
1743    (set_attr "mode" "QI")])
1744
1745 (define_insn "*movdi_extzv_1"
1746   [(set (match_operand:DI 0 "register_operand" "=R")
1747         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1748                          (const_int 8)
1749                          (const_int 8)))]
1750   "TARGET_64BIT"
1751   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1752   [(set_attr "type" "imovx")
1753    (set_attr "mode" "DI")])
1754
1755 (define_insn "*movsi_extzv_1"
1756   [(set (match_operand:SI 0 "register_operand" "=R")
1757         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1758                          (const_int 8)
1759                          (const_int 8)))]
1760   ""
1761   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1762   [(set_attr "type" "imovx")
1763    (set_attr "mode" "SI")])
1764
1765 (define_insn "*movqi_extzv_2"
1766   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1767         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1768                                     (const_int 8)
1769                                     (const_int 8)) 0))]
1770   "!TARGET_64BIT"
1771 {
1772   switch (get_attr_type (insn))
1773     {
1774     case TYPE_IMOVX:
1775       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1776     default:
1777       return "mov{b}\t{%h1, %0|%0, %h1}";
1778     }
1779 }
1780   [(set (attr "type")
1781      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1782                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1783                              (ne (symbol_ref "TARGET_MOVX")
1784                                  (const_int 0))))
1785         (const_string "imovx")
1786         (const_string "imov")))
1787    (set (attr "mode")
1788      (if_then_else (eq_attr "type" "imovx")
1789         (const_string "SI")
1790         (const_string "QI")))])
1791
1792 (define_insn "*movqi_extzv_2_rex64"
1793   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1794         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1795                                     (const_int 8)
1796                                     (const_int 8)) 0))]
1797   "TARGET_64BIT"
1798 {
1799   switch (get_attr_type (insn))
1800     {
1801     case TYPE_IMOVX:
1802       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1803     default:
1804       return "mov{b}\t{%h1, %0|%0, %h1}";
1805     }
1806 }
1807   [(set (attr "type")
1808      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1809                         (ne (symbol_ref "TARGET_MOVX")
1810                             (const_int 0)))
1811         (const_string "imovx")
1812         (const_string "imov")))
1813    (set (attr "mode")
1814      (if_then_else (eq_attr "type" "imovx")
1815         (const_string "SI")
1816         (const_string "QI")))])
1817
1818 (define_insn "movsi_insv_1"
1819   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1820                          (const_int 8)
1821                          (const_int 8))
1822         (match_operand:SI 1 "general_operand" "Qmn"))]
1823   "!TARGET_64BIT"
1824   "mov{b}\t{%b1, %h0|%h0, %b1}"
1825   [(set_attr "type" "imov")
1826    (set_attr "mode" "QI")])
1827
1828 (define_insn "*movsi_insv_1_rex64"
1829   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1830                          (const_int 8)
1831                          (const_int 8))
1832         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1833   "TARGET_64BIT"
1834   "mov{b}\t{%b1, %h0|%h0, %b1}"
1835   [(set_attr "type" "imov")
1836    (set_attr "mode" "QI")])
1837
1838 (define_insn "movdi_insv_1_rex64"
1839   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1840                          (const_int 8)
1841                          (const_int 8))
1842         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1843   "TARGET_64BIT"
1844   "mov{b}\t{%b1, %h0|%h0, %b1}"
1845   [(set_attr "type" "imov")
1846    (set_attr "mode" "QI")])
1847
1848 (define_insn "*movqi_insv_2"
1849   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1850                          (const_int 8)
1851                          (const_int 8))
1852         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1853                      (const_int 8)))]
1854   ""
1855   "mov{b}\t{%h1, %h0|%h0, %h1}"
1856   [(set_attr "type" "imov")
1857    (set_attr "mode" "QI")])
1858
1859 (define_expand "movdi"
1860   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1861         (match_operand:DI 1 "general_operand" ""))]
1862   ""
1863   "ix86_expand_move (DImode, operands); DONE;")
1864
1865 (define_insn "*pushdi"
1866   [(set (match_operand:DI 0 "push_operand" "=<")
1867         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1868   "!TARGET_64BIT"
1869   "#")
1870
1871 (define_insn "*pushdi2_rex64"
1872   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1873         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1874   "TARGET_64BIT"
1875   "@
1876    push{q}\t%1
1877    #"
1878   [(set_attr "type" "push,multi")
1879    (set_attr "mode" "DI")])
1880
1881 ;; Convert impossible pushes of immediate to existing instructions.
1882 ;; First try to get scratch register and go through it.  In case this
1883 ;; fails, push sign extended lower part first and then overwrite
1884 ;; upper part by 32bit move.
1885 (define_peephole2
1886   [(match_scratch:DI 2 "r")
1887    (set (match_operand:DI 0 "push_operand" "")
1888         (match_operand:DI 1 "immediate_operand" ""))]
1889   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1890    && !x86_64_immediate_operand (operands[1], DImode)"
1891   [(set (match_dup 2) (match_dup 1))
1892    (set (match_dup 0) (match_dup 2))]
1893   "")
1894
1895 ;; We need to define this as both peepholer and splitter for case
1896 ;; peephole2 pass is not run.
1897 ;; "&& 1" is needed to keep it from matching the previous pattern.
1898 (define_peephole2
1899   [(set (match_operand:DI 0 "push_operand" "")
1900         (match_operand:DI 1 "immediate_operand" ""))]
1901   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1902    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1903   [(set (match_dup 0) (match_dup 1))
1904    (set (match_dup 2) (match_dup 3))]
1905   "split_di (operands + 1, 1, operands + 2, operands + 3);
1906    operands[1] = gen_lowpart (DImode, operands[2]);
1907    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1908                                                     GEN_INT (4)));
1909   ")
1910
1911 (define_split
1912   [(set (match_operand:DI 0 "push_operand" "")
1913         (match_operand:DI 1 "immediate_operand" ""))]
1914   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1915                     ? flow2_completed : reload_completed)
1916    && !symbolic_operand (operands[1], DImode)
1917    && !x86_64_immediate_operand (operands[1], DImode)"
1918   [(set (match_dup 0) (match_dup 1))
1919    (set (match_dup 2) (match_dup 3))]
1920   "split_di (operands + 1, 1, operands + 2, operands + 3);
1921    operands[1] = gen_lowpart (DImode, operands[2]);
1922    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1923                                                     GEN_INT (4)));
1924   ")
1925
1926 (define_insn "*pushdi2_prologue_rex64"
1927   [(set (match_operand:DI 0 "push_operand" "=<")
1928         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1929    (clobber (mem:BLK (scratch)))]
1930   "TARGET_64BIT"
1931   "push{q}\t%1"
1932   [(set_attr "type" "push")
1933    (set_attr "mode" "DI")])
1934
1935 (define_insn "*popdi1_epilogue_rex64"
1936   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1937         (mem:DI (reg:DI SP_REG)))
1938    (set (reg:DI SP_REG)
1939         (plus:DI (reg:DI SP_REG) (const_int 8)))
1940    (clobber (mem:BLK (scratch)))]
1941   "TARGET_64BIT"
1942   "pop{q}\t%0"
1943   [(set_attr "type" "pop")
1944    (set_attr "mode" "DI")])
1945
1946 (define_insn "popdi1"
1947   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1948         (mem:DI (reg:DI SP_REG)))
1949    (set (reg:DI SP_REG)
1950         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1951   "TARGET_64BIT"
1952   "pop{q}\t%0"
1953   [(set_attr "type" "pop")
1954    (set_attr "mode" "DI")])
1955
1956 (define_insn "*movdi_xor_rex64"
1957   [(set (match_operand:DI 0 "register_operand" "=r")
1958         (match_operand:DI 1 "const0_operand" "i"))
1959    (clobber (reg:CC FLAGS_REG))]
1960   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1961    && reload_completed"
1962   "xor{l}\t%k0, %k0";
1963   [(set_attr "type" "alu1")
1964    (set_attr "mode" "SI")
1965    (set_attr "length_immediate" "0")])
1966
1967 (define_insn "*movdi_or_rex64"
1968   [(set (match_operand:DI 0 "register_operand" "=r")
1969         (match_operand:DI 1 "const_int_operand" "i"))
1970    (clobber (reg:CC FLAGS_REG))]
1971   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1972    && reload_completed
1973    && operands[1] == constm1_rtx"
1974 {
1975   operands[1] = constm1_rtx;
1976   return "or{q}\t{%1, %0|%0, %1}";
1977 }
1978   [(set_attr "type" "alu1")
1979    (set_attr "mode" "DI")
1980    (set_attr "length_immediate" "1")])
1981
1982 (define_insn "*movdi_2"
1983   [(set (match_operand:DI 0 "nonimmediate_operand"
1984                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
1985         (match_operand:DI 1 "general_operand"
1986                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
1987   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1988   "@
1989    #
1990    #
1991    pxor\t%0, %0
1992    movq\t{%1, %0|%0, %1}
1993    movq\t{%1, %0|%0, %1}
1994    pxor\t%0, %0
1995    movq\t{%1, %0|%0, %1}
1996    movdqa\t{%1, %0|%0, %1}
1997    movq\t{%1, %0|%0, %1}
1998    xorps\t%0, %0
1999    movlps\t{%1, %0|%0, %1}
2000    movaps\t{%1, %0|%0, %1}
2001    movlps\t{%1, %0|%0, %1}"
2002   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2003    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2004
2005 (define_split
2006   [(set (match_operand:DI 0 "push_operand" "")
2007         (match_operand:DI 1 "general_operand" ""))]
2008   "!TARGET_64BIT && reload_completed
2009    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2010   [(const_int 0)]
2011   "ix86_split_long_move (operands); DONE;")
2012
2013 ;; %%% This multiword shite has got to go.
2014 (define_split
2015   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2016         (match_operand:DI 1 "general_operand" ""))]
2017   "!TARGET_64BIT && reload_completed
2018    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2019    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2020   [(const_int 0)]
2021   "ix86_split_long_move (operands); DONE;")
2022
2023 (define_insn "*movdi_1_rex64"
2024   [(set (match_operand:DI 0 "nonimmediate_operand"
2025           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2026         (match_operand:DI 1 "general_operand"
2027           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2028   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2029 {
2030   switch (get_attr_type (insn))
2031     {
2032     case TYPE_SSECVT:
2033       if (SSE_REG_P (operands[0]))
2034         return "movq2dq\t{%1, %0|%0, %1}";
2035       else
2036         return "movdq2q\t{%1, %0|%0, %1}";
2037
2038     case TYPE_SSEMOV:
2039       if (get_attr_mode (insn) == MODE_TI)
2040         return "movdqa\t{%1, %0|%0, %1}";
2041       /* FALLTHRU */
2042
2043     case TYPE_MMXMOV:
2044       /* Moves from and into integer register is done using movd
2045          opcode with REX prefix.  */
2046       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2047         return "movd\t{%1, %0|%0, %1}";
2048       return "movq\t{%1, %0|%0, %1}";
2049
2050     case TYPE_SSELOG1:
2051     case TYPE_MMXADD:
2052       return "pxor\t%0, %0";
2053
2054     case TYPE_MULTI:
2055       return "#";
2056
2057     case TYPE_LEA:
2058       return "lea{q}\t{%a1, %0|%0, %a1}";
2059
2060     default:
2061       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2062       if (get_attr_mode (insn) == MODE_SI)
2063         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2064       else if (which_alternative == 2)
2065         return "movabs{q}\t{%1, %0|%0, %1}";
2066       else
2067         return "mov{q}\t{%1, %0|%0, %1}";
2068     }
2069 }
2070   [(set (attr "type")
2071      (cond [(eq_attr "alternative" "5")
2072               (const_string "mmxadd")
2073             (eq_attr "alternative" "6,7,8,9,10")
2074               (const_string "mmxmov")
2075             (eq_attr "alternative" "11")
2076               (const_string "sselog1")
2077             (eq_attr "alternative" "12,13,14,15,16")
2078               (const_string "ssemov")
2079             (eq_attr "alternative" "17,18")
2080               (const_string "ssecvt")
2081             (eq_attr "alternative" "4")
2082               (const_string "multi")
2083             (match_operand:DI 1 "pic_32bit_operand" "")
2084               (const_string "lea")
2085            ]
2086            (const_string "imov")))
2087    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2088    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2089    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2090
2091 ;; Stores and loads of ax to arbitrary constant address.
2092 ;; We fake an second form of instruction to force reload to load address
2093 ;; into register when rax is not available
2094 (define_insn "*movabsdi_1_rex64"
2095   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2096         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2097   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2098   "@
2099    movabs{q}\t{%1, %P0|%P0, %1}
2100    mov{q}\t{%1, %a0|%a0, %1}"
2101   [(set_attr "type" "imov")
2102    (set_attr "modrm" "0,*")
2103    (set_attr "length_address" "8,0")
2104    (set_attr "length_immediate" "0,*")
2105    (set_attr "memory" "store")
2106    (set_attr "mode" "DI")])
2107
2108 (define_insn "*movabsdi_2_rex64"
2109   [(set (match_operand:DI 0 "register_operand" "=a,r")
2110         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2111   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2112   "@
2113    movabs{q}\t{%P1, %0|%0, %P1}
2114    mov{q}\t{%a1, %0|%0, %a1}"
2115   [(set_attr "type" "imov")
2116    (set_attr "modrm" "0,*")
2117    (set_attr "length_address" "8,0")
2118    (set_attr "length_immediate" "0")
2119    (set_attr "memory" "load")
2120    (set_attr "mode" "DI")])
2121
2122 ;; Convert impossible stores of immediate to existing instructions.
2123 ;; First try to get scratch register and go through it.  In case this
2124 ;; fails, move by 32bit parts.
2125 (define_peephole2
2126   [(match_scratch:DI 2 "r")
2127    (set (match_operand:DI 0 "memory_operand" "")
2128         (match_operand:DI 1 "immediate_operand" ""))]
2129   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2130    && !x86_64_immediate_operand (operands[1], DImode)"
2131   [(set (match_dup 2) (match_dup 1))
2132    (set (match_dup 0) (match_dup 2))]
2133   "")
2134
2135 ;; We need to define this as both peepholer and splitter for case
2136 ;; peephole2 pass is not run.
2137 ;; "&& 1" is needed to keep it from matching the previous pattern.
2138 (define_peephole2
2139   [(set (match_operand:DI 0 "memory_operand" "")
2140         (match_operand:DI 1 "immediate_operand" ""))]
2141   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2142    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2143   [(set (match_dup 2) (match_dup 3))
2144    (set (match_dup 4) (match_dup 5))]
2145   "split_di (operands, 2, operands + 2, operands + 4);")
2146
2147 (define_split
2148   [(set (match_operand:DI 0 "memory_operand" "")
2149         (match_operand:DI 1 "immediate_operand" ""))]
2150   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2151                     ? flow2_completed : reload_completed)
2152    && !symbolic_operand (operands[1], DImode)
2153    && !x86_64_immediate_operand (operands[1], DImode)"
2154   [(set (match_dup 2) (match_dup 3))
2155    (set (match_dup 4) (match_dup 5))]
2156   "split_di (operands, 2, operands + 2, operands + 4);")
2157
2158 (define_insn "*swapdi_rex64"
2159   [(set (match_operand:DI 0 "register_operand" "+r")
2160         (match_operand:DI 1 "register_operand" "+r"))
2161    (set (match_dup 1)
2162         (match_dup 0))]
2163   "TARGET_64BIT"
2164   "xchg{q}\t%1, %0"
2165   [(set_attr "type" "imov")
2166    (set_attr "mode" "DI")
2167    (set_attr "pent_pair" "np")
2168    (set_attr "athlon_decode" "vector")
2169    (set_attr "amdfam10_decode" "double")])   
2170
2171 (define_expand "movti"
2172   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2173         (match_operand:TI 1 "nonimmediate_operand" ""))]
2174   "TARGET_SSE || TARGET_64BIT"
2175 {
2176   if (TARGET_64BIT)
2177     ix86_expand_move (TImode, operands);
2178   else
2179     ix86_expand_vector_move (TImode, operands);
2180   DONE;
2181 })
2182
2183 (define_insn "*movti_internal"
2184   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2185         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2186   "TARGET_SSE && !TARGET_64BIT
2187    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2188 {
2189   switch (which_alternative)
2190     {
2191     case 0:
2192       if (get_attr_mode (insn) == MODE_V4SF)
2193         return "xorps\t%0, %0";
2194       else
2195         return "pxor\t%0, %0";
2196     case 1:
2197     case 2:
2198       if (get_attr_mode (insn) == MODE_V4SF)
2199         return "movaps\t{%1, %0|%0, %1}";
2200       else
2201         return "movdqa\t{%1, %0|%0, %1}";
2202     default:
2203       gcc_unreachable ();
2204     }
2205 }
2206   [(set_attr "type" "sselog1,ssemov,ssemov")
2207    (set (attr "mode")
2208         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2209                     (ne (symbol_ref "optimize_size") (const_int 0)))
2210                  (const_string "V4SF")
2211                (and (eq_attr "alternative" "2")
2212                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2213                         (const_int 0)))
2214                  (const_string "V4SF")]
2215               (const_string "TI")))])
2216
2217 (define_insn "*movti_rex64"
2218   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2219         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2220   "TARGET_64BIT
2221    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2222 {
2223   switch (which_alternative)
2224     {
2225     case 0:
2226     case 1:
2227       return "#";
2228     case 2:
2229       if (get_attr_mode (insn) == MODE_V4SF)
2230         return "xorps\t%0, %0";
2231       else
2232         return "pxor\t%0, %0";
2233     case 3:
2234     case 4:
2235       if (get_attr_mode (insn) == MODE_V4SF)
2236         return "movaps\t{%1, %0|%0, %1}";
2237       else
2238         return "movdqa\t{%1, %0|%0, %1}";
2239     default:
2240       gcc_unreachable ();
2241     }
2242 }
2243   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2244    (set (attr "mode")
2245         (cond [(eq_attr "alternative" "2,3")
2246                  (if_then_else
2247                    (ne (symbol_ref "optimize_size")
2248                        (const_int 0))
2249                    (const_string "V4SF")
2250                    (const_string "TI"))
2251                (eq_attr "alternative" "4")
2252                  (if_then_else
2253                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2254                             (const_int 0))
2255                         (ne (symbol_ref "optimize_size")
2256                             (const_int 0)))
2257                    (const_string "V4SF")
2258                    (const_string "TI"))]
2259                (const_string "DI")))])
2260
2261 (define_split
2262   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2263         (match_operand:TI 1 "general_operand" ""))]
2264   "reload_completed && !SSE_REG_P (operands[0])
2265    && !SSE_REG_P (operands[1])"
2266   [(const_int 0)]
2267   "ix86_split_long_move (operands); DONE;")
2268
2269 (define_expand "movsf"
2270   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2271         (match_operand:SF 1 "general_operand" ""))]
2272   ""
2273   "ix86_expand_move (SFmode, operands); DONE;")
2274
2275 (define_insn "*pushsf"
2276   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2277         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2278   "!TARGET_64BIT"
2279 {
2280   /* Anything else should be already split before reg-stack.  */
2281   gcc_assert (which_alternative == 1);
2282   return "push{l}\t%1";
2283 }
2284   [(set_attr "type" "multi,push,multi")
2285    (set_attr "unit" "i387,*,*")
2286    (set_attr "mode" "SF,SI,SF")])
2287
2288 (define_insn "*pushsf_rex64"
2289   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2290         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2291   "TARGET_64BIT"
2292 {
2293   /* Anything else should be already split before reg-stack.  */
2294   gcc_assert (which_alternative == 1);
2295   return "push{q}\t%q1";
2296 }
2297   [(set_attr "type" "multi,push,multi")
2298    (set_attr "unit" "i387,*,*")
2299    (set_attr "mode" "SF,DI,SF")])
2300
2301 (define_split
2302   [(set (match_operand:SF 0 "push_operand" "")
2303         (match_operand:SF 1 "memory_operand" ""))]
2304   "reload_completed
2305    && MEM_P (operands[1])
2306    && constant_pool_reference_p (operands[1])"
2307   [(set (match_dup 0)
2308         (match_dup 1))]
2309   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2310
2311
2312 ;; %%% Kill this when call knows how to work this out.
2313 (define_split
2314   [(set (match_operand:SF 0 "push_operand" "")
2315         (match_operand:SF 1 "any_fp_register_operand" ""))]
2316   "!TARGET_64BIT"
2317   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2318    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2319
2320 (define_split
2321   [(set (match_operand:SF 0 "push_operand" "")
2322         (match_operand:SF 1 "any_fp_register_operand" ""))]
2323   "TARGET_64BIT"
2324   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2325    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2326
2327 (define_insn "*movsf_1"
2328   [(set (match_operand:SF 0 "nonimmediate_operand"
2329           "=f,m,f,r  ,m ,x,x,x ,m,*y,m ,*y,Yi,r ,*Ym,r  ")
2330         (match_operand:SF 1 "general_operand"
2331           "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y,r ,Yi,r  ,*Ym"))]
2332   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2333    && (reload_in_progress || reload_completed
2334        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2335        || (!TARGET_SSE_MATH && optimize_size
2336            && standard_80387_constant_p (operands[1]))
2337        || GET_CODE (operands[1]) != CONST_DOUBLE
2338        || memory_operand (operands[0], SFmode))"
2339 {
2340   switch (which_alternative)
2341     {
2342     case 0:
2343       return output_387_reg_move (insn, operands);
2344
2345     case 1:
2346       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2347         return "fstp%z0\t%y0";
2348       else
2349         return "fst%z0\t%y0";
2350
2351     case 2:
2352       return standard_80387_constant_opcode (operands[1]);
2353
2354     case 3:
2355     case 4:
2356       return "mov{l}\t{%1, %0|%0, %1}";
2357     case 5:
2358       if (get_attr_mode (insn) == MODE_TI)
2359         return "pxor\t%0, %0";
2360       else
2361         return "xorps\t%0, %0";
2362     case 6:
2363       if (get_attr_mode (insn) == MODE_V4SF)
2364         return "movaps\t{%1, %0|%0, %1}";
2365       else
2366         return "movss\t{%1, %0|%0, %1}";
2367     case 7: case 8:
2368       return "movss\t{%1, %0|%0, %1}";
2369
2370     case 9: case 10:
2371     case 12: case 13: case 14: case 15:
2372       return "movd\t{%1, %0|%0, %1}";
2373
2374     case 11:
2375       return "movq\t{%1, %0|%0, %1}";
2376
2377     default:
2378       gcc_unreachable ();
2379     }
2380 }
2381   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2382    (set (attr "mode")
2383         (cond [(eq_attr "alternative" "3,4,9,10")
2384                  (const_string "SI")
2385                (eq_attr "alternative" "5")
2386                  (if_then_else
2387                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2388                                  (const_int 0))
2389                              (ne (symbol_ref "TARGET_SSE2")
2390                                  (const_int 0)))
2391                         (eq (symbol_ref "optimize_size")
2392                             (const_int 0)))
2393                    (const_string "TI")
2394                    (const_string "V4SF"))
2395                /* For architectures resolving dependencies on
2396                   whole SSE registers use APS move to break dependency
2397                   chains, otherwise use short move to avoid extra work.
2398
2399                   Do the same for architectures resolving dependencies on
2400                   the parts.  While in DF mode it is better to always handle
2401                   just register parts, the SF mode is different due to lack
2402                   of instructions to load just part of the register.  It is
2403                   better to maintain the whole registers in single format
2404                   to avoid problems on using packed logical operations.  */
2405                (eq_attr "alternative" "6")
2406                  (if_then_else
2407                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2408                             (const_int 0))
2409                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2410                             (const_int 0)))
2411                    (const_string "V4SF")
2412                    (const_string "SF"))
2413                (eq_attr "alternative" "11")
2414                  (const_string "DI")]
2415                (const_string "SF")))])
2416
2417 (define_insn "*swapsf"
2418   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2419         (match_operand:SF 1 "fp_register_operand" "+f"))
2420    (set (match_dup 1)
2421         (match_dup 0))]
2422   "reload_completed || TARGET_80387"
2423 {
2424   if (STACK_TOP_P (operands[0]))
2425     return "fxch\t%1";
2426   else
2427     return "fxch\t%0";
2428 }
2429   [(set_attr "type" "fxch")
2430    (set_attr "mode" "SF")])
2431
2432 (define_expand "movdf"
2433   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2434         (match_operand:DF 1 "general_operand" ""))]
2435   ""
2436   "ix86_expand_move (DFmode, operands); DONE;")
2437
2438 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2439 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2440 ;; On the average, pushdf using integers can be still shorter.  Allow this
2441 ;; pattern for optimize_size too.
2442
2443 (define_insn "*pushdf_nointeger"
2444   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2445         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2446   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2447 {
2448   /* This insn should be already split before reg-stack.  */
2449   gcc_unreachable ();
2450 }
2451   [(set_attr "type" "multi")
2452    (set_attr "unit" "i387,*,*,*")
2453    (set_attr "mode" "DF,SI,SI,DF")])
2454
2455 (define_insn "*pushdf_integer"
2456   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2457         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2458   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2459 {
2460   /* This insn should be already split before reg-stack.  */
2461   gcc_unreachable ();
2462 }
2463   [(set_attr "type" "multi")
2464    (set_attr "unit" "i387,*,*")
2465    (set_attr "mode" "DF,SI,DF")])
2466
2467 ;; %%% Kill this when call knows how to work this out.
2468 (define_split
2469   [(set (match_operand:DF 0 "push_operand" "")
2470         (match_operand:DF 1 "any_fp_register_operand" ""))]
2471   "!TARGET_64BIT && reload_completed"
2472   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2473    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2474   "")
2475
2476 (define_split
2477   [(set (match_operand:DF 0 "push_operand" "")
2478         (match_operand:DF 1 "any_fp_register_operand" ""))]
2479   "TARGET_64BIT && reload_completed"
2480   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2481    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2482   "")
2483
2484 (define_split
2485   [(set (match_operand:DF 0 "push_operand" "")
2486         (match_operand:DF 1 "general_operand" ""))]
2487   "reload_completed"
2488   [(const_int 0)]
2489   "ix86_split_long_move (operands); DONE;")
2490
2491 ;; Moving is usually shorter when only FP registers are used. This separate
2492 ;; movdf pattern avoids the use of integer registers for FP operations
2493 ;; when optimizing for size.
2494
2495 (define_insn "*movdf_nointeger"
2496   [(set (match_operand:DF 0 "nonimmediate_operand"
2497                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
2498         (match_operand:DF 1 "general_operand"
2499                         "fm,f,G,*roF,F*r,C   ,Y2*x,mY2*x,Y2*x"))]
2500   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2501    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2502    && (reload_in_progress || reload_completed
2503        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2504        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2505            && standard_80387_constant_p (operands[1]))
2506        || GET_CODE (operands[1]) != CONST_DOUBLE
2507        || memory_operand (operands[0], DFmode))"
2508 {
2509   switch (which_alternative)
2510     {
2511     case 0:
2512       return output_387_reg_move (insn, operands);
2513
2514     case 1:
2515       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2516         return "fstp%z0\t%y0";
2517       else
2518         return "fst%z0\t%y0";
2519
2520     case 2:
2521       return standard_80387_constant_opcode (operands[1]);
2522
2523     case 3:
2524     case 4:
2525       return "#";
2526     case 5:
2527       switch (get_attr_mode (insn))
2528         {
2529         case MODE_V4SF:
2530           return "xorps\t%0, %0";
2531         case MODE_V2DF:
2532           return "xorpd\t%0, %0";
2533         case MODE_TI:
2534           return "pxor\t%0, %0";
2535         default:
2536           gcc_unreachable ();
2537         }
2538     case 6:
2539     case 7:
2540     case 8:
2541       switch (get_attr_mode (insn))
2542         {
2543         case MODE_V4SF:
2544           return "movaps\t{%1, %0|%0, %1}";
2545         case MODE_V2DF:
2546           return "movapd\t{%1, %0|%0, %1}";
2547         case MODE_TI:
2548           return "movdqa\t{%1, %0|%0, %1}";
2549         case MODE_DI:
2550           return "movq\t{%1, %0|%0, %1}";
2551         case MODE_DF:
2552           return "movsd\t{%1, %0|%0, %1}";
2553         case MODE_V1DF:
2554           return "movlpd\t{%1, %0|%0, %1}";
2555         case MODE_V2SF:
2556           return "movlps\t{%1, %0|%0, %1}";
2557         default:
2558           gcc_unreachable ();
2559         }
2560
2561     default:
2562       gcc_unreachable ();
2563     }
2564 }
2565   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2566    (set (attr "mode")
2567         (cond [(eq_attr "alternative" "0,1,2")
2568                  (const_string "DF")
2569                (eq_attr "alternative" "3,4")
2570                  (const_string "SI")
2571
2572                /* For SSE1, we have many fewer alternatives.  */
2573                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2574                  (cond [(eq_attr "alternative" "5,6")
2575                           (const_string "V4SF")
2576                        ]
2577                    (const_string "V2SF"))
2578
2579                /* xorps is one byte shorter.  */
2580                (eq_attr "alternative" "5")
2581                  (cond [(ne (symbol_ref "optimize_size")
2582                             (const_int 0))
2583                           (const_string "V4SF")
2584                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2585                             (const_int 0))
2586                           (const_string "TI")
2587                        ]
2588                        (const_string "V2DF"))
2589
2590                /* For architectures resolving dependencies on
2591                   whole SSE registers use APD move to break dependency
2592                   chains, otherwise use short move to avoid extra work.
2593
2594                   movaps encodes one byte shorter.  */
2595                (eq_attr "alternative" "6")
2596                  (cond
2597                    [(ne (symbol_ref "optimize_size")
2598                         (const_int 0))
2599                       (const_string "V4SF")
2600                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2601                         (const_int 0))
2602                       (const_string "V2DF")
2603                    ]
2604                    (const_string "DF"))
2605                /* For architectures resolving dependencies on register
2606                   parts we may avoid extra work to zero out upper part
2607                   of register.  */
2608                (eq_attr "alternative" "7")
2609                  (if_then_else
2610                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2611                        (const_int 0))
2612                    (const_string "V1DF")
2613                    (const_string "DF"))
2614               ]
2615               (const_string "DF")))])
2616
2617 (define_insn "*movdf_integer_rex64"
2618   [(set (match_operand:DF 0 "nonimmediate_operand"
2619                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2620         (match_operand:DF 1 "general_operand"
2621                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2622   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2623    && (reload_in_progress || reload_completed
2624        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2625        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2626            && standard_80387_constant_p (operands[1]))
2627        || GET_CODE (operands[1]) != CONST_DOUBLE
2628        || memory_operand (operands[0], DFmode))"
2629 {
2630   switch (which_alternative)
2631     {
2632     case 0:
2633       return output_387_reg_move (insn, operands);
2634
2635     case 1:
2636       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2637         return "fstp%z0\t%y0";
2638       else
2639         return "fst%z0\t%y0";
2640
2641     case 2:
2642       return standard_80387_constant_opcode (operands[1]);
2643
2644     case 3:
2645     case 4:
2646       return "#";
2647
2648     case 5:
2649       switch (get_attr_mode (insn))
2650         {
2651         case MODE_V4SF:
2652           return "xorps\t%0, %0";
2653         case MODE_V2DF:
2654           return "xorpd\t%0, %0";
2655         case MODE_TI:
2656           return "pxor\t%0, %0";
2657         default:
2658           gcc_unreachable ();
2659         }
2660     case 6:
2661     case 7:
2662     case 8:
2663       switch (get_attr_mode (insn))
2664         {
2665         case MODE_V4SF:
2666           return "movaps\t{%1, %0|%0, %1}";
2667         case MODE_V2DF:
2668           return "movapd\t{%1, %0|%0, %1}";
2669         case MODE_TI:
2670           return "movdqa\t{%1, %0|%0, %1}";
2671         case MODE_DI:
2672           return "movq\t{%1, %0|%0, %1}";
2673         case MODE_DF:
2674           return "movsd\t{%1, %0|%0, %1}";
2675         case MODE_V1DF:
2676           return "movlpd\t{%1, %0|%0, %1}";
2677         case MODE_V2SF:
2678           return "movlps\t{%1, %0|%0, %1}";
2679         default:
2680           gcc_unreachable ();
2681         }
2682
2683     case 9:
2684     case 10:
2685       return "movd\t{%1, %0|%0, %1}";
2686
2687     default:
2688       gcc_unreachable();
2689     }
2690 }
2691   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2692    (set (attr "mode")
2693         (cond [(eq_attr "alternative" "0,1,2")
2694                  (const_string "DF")
2695                (eq_attr "alternative" "3,4,9,10")
2696                  (const_string "DI")
2697
2698                /* For SSE1, we have many fewer alternatives.  */
2699                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2700                  (cond [(eq_attr "alternative" "5,6")
2701                           (const_string "V4SF")
2702                        ]
2703                    (const_string "V2SF"))
2704
2705                /* xorps is one byte shorter.  */
2706                (eq_attr "alternative" "5")
2707                  (cond [(ne (symbol_ref "optimize_size")
2708                             (const_int 0))
2709                           (const_string "V4SF")
2710                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2711                             (const_int 0))
2712                           (const_string "TI")
2713                        ]
2714                        (const_string "V2DF"))
2715
2716                /* For architectures resolving dependencies on
2717                   whole SSE registers use APD move to break dependency
2718                   chains, otherwise use short move to avoid extra work.
2719
2720                   movaps encodes one byte shorter.  */
2721                (eq_attr "alternative" "6")
2722                  (cond
2723                    [(ne (symbol_ref "optimize_size")
2724                         (const_int 0))
2725                       (const_string "V4SF")
2726                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2727                         (const_int 0))
2728                       (const_string "V2DF")
2729                    ]
2730                    (const_string "DF"))
2731                /* For architectures resolving dependencies on register
2732                   parts we may avoid extra work to zero out upper part
2733                   of register.  */
2734                (eq_attr "alternative" "7")
2735                  (if_then_else
2736                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2737                        (const_int 0))
2738                    (const_string "V1DF")
2739                    (const_string "DF"))
2740               ]
2741               (const_string "DF")))])
2742
2743 (define_insn "*movdf_integer"
2744   [(set (match_operand:DF 0 "nonimmediate_operand"
2745                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
2746         (match_operand:DF 1 "general_operand"
2747                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
2748   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2749    && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2750    && (reload_in_progress || reload_completed
2751        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2752        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2753            && standard_80387_constant_p (operands[1]))
2754        || GET_CODE (operands[1]) != CONST_DOUBLE
2755        || memory_operand (operands[0], DFmode))"
2756 {
2757   switch (which_alternative)
2758     {
2759     case 0:
2760       return output_387_reg_move (insn, operands);
2761
2762     case 1:
2763       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2764         return "fstp%z0\t%y0";
2765       else
2766         return "fst%z0\t%y0";
2767
2768     case 2:
2769       return standard_80387_constant_opcode (operands[1]);
2770
2771     case 3:
2772     case 4:
2773       return "#";
2774
2775     case 5:
2776       switch (get_attr_mode (insn))
2777         {
2778         case MODE_V4SF:
2779           return "xorps\t%0, %0";
2780         case MODE_V2DF:
2781           return "xorpd\t%0, %0";
2782         case MODE_TI:
2783           return "pxor\t%0, %0";
2784         default:
2785           gcc_unreachable ();
2786         }
2787     case 6:
2788     case 7:
2789     case 8:
2790       switch (get_attr_mode (insn))
2791         {
2792         case MODE_V4SF:
2793           return "movaps\t{%1, %0|%0, %1}";
2794         case MODE_V2DF:
2795           return "movapd\t{%1, %0|%0, %1}";
2796         case MODE_TI:
2797           return "movdqa\t{%1, %0|%0, %1}";
2798         case MODE_DI:
2799           return "movq\t{%1, %0|%0, %1}";
2800         case MODE_DF:
2801           return "movsd\t{%1, %0|%0, %1}";
2802         case MODE_V1DF:
2803           return "movlpd\t{%1, %0|%0, %1}";
2804         case MODE_V2SF:
2805           return "movlps\t{%1, %0|%0, %1}";
2806         default:
2807           gcc_unreachable ();
2808         }
2809
2810     default:
2811       gcc_unreachable();
2812     }
2813 }
2814   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2815    (set (attr "mode")
2816         (cond [(eq_attr "alternative" "0,1,2")
2817                  (const_string "DF")
2818                (eq_attr "alternative" "3,4")
2819                  (const_string "SI")
2820
2821                /* For SSE1, we have many fewer alternatives.  */
2822                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2823                  (cond [(eq_attr "alternative" "5,6")
2824                           (const_string "V4SF")
2825                        ]
2826                    (const_string "V2SF"))
2827
2828                /* xorps is one byte shorter.  */
2829                (eq_attr "alternative" "5")
2830                  (cond [(ne (symbol_ref "optimize_size")
2831                             (const_int 0))
2832                           (const_string "V4SF")
2833                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2834                             (const_int 0))
2835                           (const_string "TI")
2836                        ]
2837                        (const_string "V2DF"))
2838
2839                /* For architectures resolving dependencies on
2840                   whole SSE registers use APD move to break dependency
2841                   chains, otherwise use short move to avoid extra work.
2842
2843                   movaps encodes one byte shorter.  */
2844                (eq_attr "alternative" "6")
2845                  (cond
2846                    [(ne (symbol_ref "optimize_size")
2847                         (const_int 0))
2848                       (const_string "V4SF")
2849                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2850                         (const_int 0))
2851                       (const_string "V2DF")
2852                    ]
2853                    (const_string "DF"))
2854                /* For architectures resolving dependencies on register
2855                   parts we may avoid extra work to zero out upper part
2856                   of register.  */
2857                (eq_attr "alternative" "7")
2858                  (if_then_else
2859                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2860                        (const_int 0))
2861                    (const_string "V1DF")
2862                    (const_string "DF"))
2863               ]
2864               (const_string "DF")))])
2865
2866 (define_split
2867   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2868         (match_operand:DF 1 "general_operand" ""))]
2869   "reload_completed
2870    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2871    && ! (ANY_FP_REG_P (operands[0]) ||
2872          (GET_CODE (operands[0]) == SUBREG
2873           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2874    && ! (ANY_FP_REG_P (operands[1]) ||
2875          (GET_CODE (operands[1]) == SUBREG
2876           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2877   [(const_int 0)]
2878   "ix86_split_long_move (operands); DONE;")
2879
2880 (define_insn "*swapdf"
2881   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2882         (match_operand:DF 1 "fp_register_operand" "+f"))
2883    (set (match_dup 1)
2884         (match_dup 0))]
2885   "reload_completed || TARGET_80387"
2886 {
2887   if (STACK_TOP_P (operands[0]))
2888     return "fxch\t%1";
2889   else
2890     return "fxch\t%0";
2891 }
2892   [(set_attr "type" "fxch")
2893    (set_attr "mode" "DF")])
2894
2895 (define_expand "movxf"
2896   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2897         (match_operand:XF 1 "general_operand" ""))]
2898   ""
2899   "ix86_expand_move (XFmode, operands); DONE;")
2900
2901 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2902 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2903 ;; Pushing using integer instructions is longer except for constants
2904 ;; and direct memory references.
2905 ;; (assuming that any given constant is pushed only once, but this ought to be
2906 ;;  handled elsewhere).
2907
2908 (define_insn "*pushxf_nointeger"
2909   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2910         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2911   "optimize_size"
2912 {
2913   /* This insn should be already split before reg-stack.  */
2914   gcc_unreachable ();
2915 }
2916   [(set_attr "type" "multi")
2917    (set_attr "unit" "i387,*,*")
2918    (set_attr "mode" "XF,SI,SI")])
2919
2920 (define_insn "*pushxf_integer"
2921   [(set (match_operand:XF 0 "push_operand" "=<,<")
2922         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2923   "!optimize_size"
2924 {
2925   /* This insn should be already split before reg-stack.  */
2926   gcc_unreachable ();
2927 }
2928   [(set_attr "type" "multi")
2929    (set_attr "unit" "i387,*")
2930    (set_attr "mode" "XF,SI")])
2931
2932 (define_split
2933   [(set (match_operand 0 "push_operand" "")
2934         (match_operand 1 "general_operand" ""))]
2935   "reload_completed
2936    && (GET_MODE (operands[0]) == XFmode
2937        || GET_MODE (operands[0]) == DFmode)
2938    && !ANY_FP_REG_P (operands[1])"
2939   [(const_int 0)]
2940   "ix86_split_long_move (operands); DONE;")
2941
2942 (define_split
2943   [(set (match_operand:XF 0 "push_operand" "")
2944         (match_operand:XF 1 "any_fp_register_operand" ""))]
2945   "!TARGET_64BIT"
2946   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2947    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2948   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2949
2950 (define_split
2951   [(set (match_operand:XF 0 "push_operand" "")
2952         (match_operand:XF 1 "any_fp_register_operand" ""))]
2953   "TARGET_64BIT"
2954   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2955    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2956   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2957
2958 ;; Do not use integer registers when optimizing for size
2959 (define_insn "*movxf_nointeger"
2960   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2961         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2962   "optimize_size
2963    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2964    && (reload_in_progress || reload_completed
2965        || (optimize_size && standard_80387_constant_p (operands[1]))
2966        || GET_CODE (operands[1]) != CONST_DOUBLE
2967        || memory_operand (operands[0], XFmode))"
2968 {
2969   switch (which_alternative)
2970     {
2971     case 0:
2972       return output_387_reg_move (insn, operands);
2973
2974     case 1:
2975       /* There is no non-popping store to memory for XFmode.  So if
2976          we need one, follow the store with a load.  */
2977       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2978         return "fstp%z0\t%y0\;fld%z0\t%y0";
2979       else
2980         return "fstp%z0\t%y0";
2981
2982     case 2:
2983       return standard_80387_constant_opcode (operands[1]);
2984
2985     case 3: case 4:
2986       return "#";
2987     default:
2988       gcc_unreachable ();
2989     }
2990 }
2991   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2992    (set_attr "mode" "XF,XF,XF,SI,SI")])
2993
2994 (define_insn "*movxf_integer"
2995   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2996         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2997   "!optimize_size
2998    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2999    && (reload_in_progress || reload_completed
3000        || (optimize_size && standard_80387_constant_p (operands[1]))
3001        || GET_CODE (operands[1]) != CONST_DOUBLE
3002        || memory_operand (operands[0], XFmode))"
3003 {
3004   switch (which_alternative)
3005     {
3006     case 0:
3007       return output_387_reg_move (insn, operands);
3008
3009     case 1:
3010       /* There is no non-popping store to memory for XFmode.  So if
3011          we need one, follow the store with a load.  */
3012       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3013         return "fstp%z0\t%y0\;fld%z0\t%y0";
3014       else
3015         return "fstp%z0\t%y0";
3016
3017     case 2:
3018       return standard_80387_constant_opcode (operands[1]);
3019
3020     case 3: case 4:
3021       return "#";
3022
3023     default:
3024       gcc_unreachable ();
3025     }
3026 }
3027   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3028    (set_attr "mode" "XF,XF,XF,SI,SI")])
3029
3030 (define_split
3031   [(set (match_operand 0 "nonimmediate_operand" "")
3032         (match_operand 1 "general_operand" ""))]
3033   "reload_completed
3034    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3035    && GET_MODE (operands[0]) == XFmode
3036    && ! (ANY_FP_REG_P (operands[0]) ||
3037          (GET_CODE (operands[0]) == SUBREG
3038           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3039    && ! (ANY_FP_REG_P (operands[1]) ||
3040          (GET_CODE (operands[1]) == SUBREG
3041           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3042   [(const_int 0)]
3043   "ix86_split_long_move (operands); DONE;")
3044
3045 (define_split
3046   [(set (match_operand 0 "register_operand" "")
3047         (match_operand 1 "memory_operand" ""))]
3048   "reload_completed
3049    && MEM_P (operands[1])
3050    && (GET_MODE (operands[0]) == XFmode
3051        || GET_MODE (operands[0]) == SFmode
3052        || GET_MODE (operands[0]) == DFmode)
3053    && constant_pool_reference_p (operands[1])"
3054   [(set (match_dup 0) (match_dup 1))]
3055 {
3056   rtx c = avoid_constant_pool_reference (operands[1]);
3057   rtx r = operands[0];
3058
3059   if (GET_CODE (r) == SUBREG)
3060     r = SUBREG_REG (r);
3061
3062   if (SSE_REG_P (r))
3063     {
3064       if (!standard_sse_constant_p (c))
3065         FAIL;
3066     }
3067   else if (FP_REG_P (r))
3068     {
3069       if (!standard_80387_constant_p (c))
3070         FAIL;
3071     }
3072   else if (MMX_REG_P (r))
3073     FAIL;
3074
3075   operands[1] = c;
3076 })
3077
3078 (define_split
3079   [(set (match_operand 0 "register_operand" "")
3080         (float_extend (match_operand 1 "memory_operand" "")))]
3081   "reload_completed
3082    && MEM_P (operands[1])
3083    && (GET_MODE (operands[0]) == XFmode
3084        || GET_MODE (operands[0]) == SFmode
3085        || GET_MODE (operands[0]) == DFmode)
3086    && constant_pool_reference_p (operands[1])"
3087   [(set (match_dup 0) (match_dup 1))]
3088 {
3089   rtx c = avoid_constant_pool_reference (SET_SRC (PATTERN (curr_insn)));
3090   rtx r = operands[0];
3091
3092   if (GET_CODE (r) == SUBREG)
3093     r = SUBREG_REG (r);
3094
3095   if (SSE_REG_P (r))
3096     {
3097       if (!standard_sse_constant_p (c))
3098         FAIL;
3099     }
3100   else if (FP_REG_P (r))
3101     {
3102       if (!standard_80387_constant_p (c))
3103         FAIL;
3104     }
3105   else if (MMX_REG_P (r))
3106     FAIL;
3107
3108   operands[1] = c;
3109 })
3110
3111 (define_insn "swapxf"
3112   [(set (match_operand:XF 0 "register_operand" "+f")
3113         (match_operand:XF 1 "register_operand" "+f"))
3114    (set (match_dup 1)
3115         (match_dup 0))]
3116   "TARGET_80387"
3117 {
3118   if (STACK_TOP_P (operands[0]))
3119     return "fxch\t%1";
3120   else
3121     return "fxch\t%0";
3122 }
3123   [(set_attr "type" "fxch")
3124    (set_attr "mode" "XF")])
3125
3126 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3127 (define_split
3128   [(set (match_operand:X87MODEF 0 "register_operand" "")
3129         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3130   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3131    && (standard_80387_constant_p (operands[1]) == 8
3132        || standard_80387_constant_p (operands[1]) == 9)"
3133   [(set (match_dup 0)(match_dup 1))
3134    (set (match_dup 0)
3135         (neg:X87MODEF (match_dup 0)))]
3136 {
3137   REAL_VALUE_TYPE r;
3138
3139   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3140   if (real_isnegzero (&r))
3141     operands[1] = CONST0_RTX (<MODE>mode);
3142   else
3143     operands[1] = CONST1_RTX (<MODE>mode);
3144 })
3145
3146 (define_expand "movtf"
3147   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3148         (match_operand:TF 1 "nonimmediate_operand" ""))]
3149   "TARGET_64BIT"
3150 {
3151   ix86_expand_move (TFmode, operands);
3152   DONE;
3153 })
3154
3155 (define_insn "*movtf_internal"
3156   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3157         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3158   "TARGET_64BIT
3159    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3160 {
3161   switch (which_alternative)
3162     {
3163     case 0:
3164     case 1:
3165       return "#";
3166     case 2:
3167       if (get_attr_mode (insn) == MODE_V4SF)
3168         return "xorps\t%0, %0";
3169       else
3170         return "pxor\t%0, %0";
3171     case 3:
3172     case 4:
3173       if (get_attr_mode (insn) == MODE_V4SF)
3174         return "movaps\t{%1, %0|%0, %1}";
3175       else
3176         return "movdqa\t{%1, %0|%0, %1}";
3177     default:
3178       gcc_unreachable ();
3179     }
3180 }
3181   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3182    (set (attr "mode")
3183         (cond [(eq_attr "alternative" "2,3")
3184                  (if_then_else
3185                    (ne (symbol_ref "optimize_size")
3186                        (const_int 0))
3187                    (const_string "V4SF")
3188                    (const_string "TI"))
3189                (eq_attr "alternative" "4")
3190                  (if_then_else
3191                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3192                             (const_int 0))
3193                         (ne (symbol_ref "optimize_size")
3194                             (const_int 0)))
3195                    (const_string "V4SF")
3196                    (const_string "TI"))]
3197                (const_string "DI")))])
3198
3199 (define_split
3200   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3201         (match_operand:TF 1 "general_operand" ""))]
3202   "reload_completed && !SSE_REG_P (operands[0])
3203    && !SSE_REG_P (operands[1])"
3204   [(const_int 0)]
3205   "ix86_split_long_move (operands); DONE;")
3206 \f
3207 ;; Zero extension instructions
3208
3209 (define_expand "zero_extendhisi2"
3210   [(set (match_operand:SI 0 "register_operand" "")
3211      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3212   ""
3213 {
3214   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3215     {
3216       operands[1] = force_reg (HImode, operands[1]);
3217       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3218       DONE;
3219     }
3220 })
3221
3222 (define_insn "zero_extendhisi2_and"
3223   [(set (match_operand:SI 0 "register_operand" "=r")
3224      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3225    (clobber (reg:CC FLAGS_REG))]
3226   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3227   "#"
3228   [(set_attr "type" "alu1")
3229    (set_attr "mode" "SI")])
3230
3231 (define_split
3232   [(set (match_operand:SI 0 "register_operand" "")
3233         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3234    (clobber (reg:CC FLAGS_REG))]
3235   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3236   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3237               (clobber (reg:CC FLAGS_REG))])]
3238   "")
3239
3240 (define_insn "*zero_extendhisi2_movzwl"
3241   [(set (match_operand:SI 0 "register_operand" "=r")
3242      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3243   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3244   "movz{wl|x}\t{%1, %0|%0, %1}"
3245   [(set_attr "type" "imovx")
3246    (set_attr "mode" "SI")])
3247
3248 (define_expand "zero_extendqihi2"
3249   [(parallel
3250     [(set (match_operand:HI 0 "register_operand" "")
3251        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3252      (clobber (reg:CC FLAGS_REG))])]
3253   ""
3254   "")
3255
3256 (define_insn "*zero_extendqihi2_and"
3257   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3258      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3259    (clobber (reg:CC FLAGS_REG))]
3260   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3261   "#"
3262   [(set_attr "type" "alu1")
3263    (set_attr "mode" "HI")])
3264
3265 (define_insn "*zero_extendqihi2_movzbw_and"
3266   [(set (match_operand:HI 0 "register_operand" "=r,r")
3267      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3268    (clobber (reg:CC FLAGS_REG))]
3269   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3270   "#"
3271   [(set_attr "type" "imovx,alu1")
3272    (set_attr "mode" "HI")])
3273
3274 ; zero extend to SImode here to avoid partial register stalls
3275 (define_insn "*zero_extendqihi2_movzbl"
3276   [(set (match_operand:HI 0 "register_operand" "=r")
3277      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3278   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3279   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3280   [(set_attr "type" "imovx")
3281    (set_attr "mode" "SI")])
3282
3283 ;; For the movzbw case strip only the clobber
3284 (define_split
3285   [(set (match_operand:HI 0 "register_operand" "")
3286         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3287    (clobber (reg:CC FLAGS_REG))]
3288   "reload_completed
3289    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3290    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3291   [(set (match_operand:HI 0 "register_operand" "")
3292         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3293
3294 ;; When source and destination does not overlap, clear destination
3295 ;; first and then do the movb
3296 (define_split
3297   [(set (match_operand:HI 0 "register_operand" "")
3298         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3299    (clobber (reg:CC FLAGS_REG))]
3300   "reload_completed
3301    && ANY_QI_REG_P (operands[0])
3302    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3303    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3304   [(set (match_dup 0) (const_int 0))
3305    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3306   "operands[2] = gen_lowpart (QImode, operands[0]);")
3307
3308 ;; Rest is handled by single and.
3309 (define_split
3310   [(set (match_operand:HI 0 "register_operand" "")
3311         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3312    (clobber (reg:CC FLAGS_REG))]
3313   "reload_completed
3314    && true_regnum (operands[0]) == true_regnum (operands[1])"
3315   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3316               (clobber (reg:CC FLAGS_REG))])]
3317   "")
3318
3319 (define_expand "zero_extendqisi2"
3320   [(parallel
3321     [(set (match_operand:SI 0 "register_operand" "")
3322        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3323      (clobber (reg:CC FLAGS_REG))])]
3324   ""
3325   "")
3326
3327 (define_insn "*zero_extendqisi2_and"
3328   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3329      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3330    (clobber (reg:CC FLAGS_REG))]
3331   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3332   "#"
3333   [(set_attr "type" "alu1")
3334    (set_attr "mode" "SI")])
3335
3336 (define_insn "*zero_extendqisi2_movzbw_and"
3337   [(set (match_operand:SI 0 "register_operand" "=r,r")
3338      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3339    (clobber (reg:CC FLAGS_REG))]
3340   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3341   "#"
3342   [(set_attr "type" "imovx,alu1")
3343    (set_attr "mode" "SI")])
3344
3345 (define_insn "*zero_extendqisi2_movzbw"
3346   [(set (match_operand:SI 0 "register_operand" "=r")
3347      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3348   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3349   "movz{bl|x}\t{%1, %0|%0, %1}"
3350   [(set_attr "type" "imovx")
3351    (set_attr "mode" "SI")])
3352
3353 ;; For the movzbl case strip only the clobber
3354 (define_split
3355   [(set (match_operand:SI 0 "register_operand" "")
3356         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3357    (clobber (reg:CC FLAGS_REG))]
3358   "reload_completed
3359    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3360    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3361   [(set (match_dup 0)
3362         (zero_extend:SI (match_dup 1)))])
3363
3364 ;; When source and destination does not overlap, clear destination
3365 ;; first and then do the movb
3366 (define_split
3367   [(set (match_operand:SI 0 "register_operand" "")
3368         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3369    (clobber (reg:CC FLAGS_REG))]
3370   "reload_completed
3371    && ANY_QI_REG_P (operands[0])
3372    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3373    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3374    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3375   [(set (match_dup 0) (const_int 0))
3376    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3377   "operands[2] = gen_lowpart (QImode, operands[0]);")
3378
3379 ;; Rest is handled by single and.
3380 (define_split
3381   [(set (match_operand:SI 0 "register_operand" "")
3382         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3383    (clobber (reg:CC FLAGS_REG))]
3384   "reload_completed
3385    && true_regnum (operands[0]) == true_regnum (operands[1])"
3386   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3387               (clobber (reg:CC FLAGS_REG))])]
3388   "")
3389
3390 ;; %%% Kill me once multi-word ops are sane.
3391 (define_expand "zero_extendsidi2"
3392   [(set (match_operand:DI 0 "register_operand" "=r")
3393      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3394   ""
3395 {
3396   if (!TARGET_64BIT)
3397     {
3398       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3399       DONE;
3400     }
3401 })
3402
3403 (define_insn "zero_extendsidi2_32"
3404   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,*y,?*Yi,*Y2")
3405         (zero_extend:DI
3406          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m ,r   ,m")))
3407    (clobber (reg:CC FLAGS_REG))]
3408   "!TARGET_64BIT"
3409   "@
3410    #
3411    #
3412    #
3413    movd\t{%1, %0|%0, %1}
3414    movd\t{%1, %0|%0, %1}
3415    movd\t{%1, %0|%0, %1}
3416    movd\t{%1, %0|%0, %1}"
3417   [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3418    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3419
3420 (define_insn "zero_extendsidi2_rex64"
3421   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,*y,?*Yi,*Y2")
3422      (zero_extend:DI
3423        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m ,r   ,m")))]
3424   "TARGET_64BIT"
3425   "@
3426    mov\t{%k1, %k0|%k0, %k1}
3427    #
3428    movd\t{%1, %0|%0, %1}
3429    movd\t{%1, %0|%0, %1}
3430    movd\t{%1, %0|%0, %1}
3431    movd\t{%1, %0|%0, %1}"
3432   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3433    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3434
3435 (define_split
3436   [(set (match_operand:DI 0 "memory_operand" "")
3437      (zero_extend:DI (match_dup 0)))]
3438   "TARGET_64BIT"
3439   [(set (match_dup 4) (const_int 0))]
3440   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3441
3442 (define_split
3443   [(set (match_operand:DI 0 "register_operand" "")
3444         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3445    (clobber (reg:CC FLAGS_REG))]
3446   "!TARGET_64BIT && reload_completed
3447    && true_regnum (operands[0]) == true_regnum (operands[1])"
3448   [(set (match_dup 4) (const_int 0))]
3449   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3450
3451 (define_split
3452   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3453         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3454    (clobber (reg:CC FLAGS_REG))]
3455   "!TARGET_64BIT && reload_completed
3456    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3457   [(set (match_dup 3) (match_dup 1))
3458    (set (match_dup 4) (const_int 0))]
3459   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3460
3461 (define_insn "zero_extendhidi2"
3462   [(set (match_operand:DI 0 "register_operand" "=r")
3463      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3464   "TARGET_64BIT"
3465   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3466   [(set_attr "type" "imovx")
3467    (set_attr "mode" "DI")])
3468
3469 (define_insn "zero_extendqidi2"
3470   [(set (match_operand:DI 0 "register_operand" "=r")
3471      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3472   "TARGET_64BIT"
3473   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3474   [(set_attr "type" "imovx")
3475    (set_attr "mode" "DI")])
3476 \f
3477 ;; Sign extension instructions
3478
3479 (define_expand "extendsidi2"
3480   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3481                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3482               (clobber (reg:CC FLAGS_REG))
3483               (clobber (match_scratch:SI 2 ""))])]
3484   ""
3485 {
3486   if (TARGET_64BIT)
3487     {
3488       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3489       DONE;
3490     }
3491 })
3492
3493 (define_insn "*extendsidi2_1"
3494   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3495         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3496    (clobber (reg:CC FLAGS_REG))
3497    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3498   "!TARGET_64BIT"
3499   "#")
3500
3501 (define_insn "extendsidi2_rex64"
3502   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3503         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3504   "TARGET_64BIT"
3505   "@
3506    {cltq|cdqe}
3507    movs{lq|x}\t{%1,%0|%0, %1}"
3508   [(set_attr "type" "imovx")
3509    (set_attr "mode" "DI")
3510    (set_attr "prefix_0f" "0")
3511    (set_attr "modrm" "0,1")])
3512
3513 (define_insn "extendhidi2"
3514   [(set (match_operand:DI 0 "register_operand" "=r")
3515         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3516   "TARGET_64BIT"
3517   "movs{wq|x}\t{%1,%0|%0, %1}"
3518   [(set_attr "type" "imovx")
3519    (set_attr "mode" "DI")])
3520
3521 (define_insn "extendqidi2"
3522   [(set (match_operand:DI 0 "register_operand" "=r")
3523         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3524   "TARGET_64BIT"
3525   "movs{bq|x}\t{%1,%0|%0, %1}"
3526    [(set_attr "type" "imovx")
3527     (set_attr "mode" "DI")])
3528
3529 ;; Extend to memory case when source register does die.
3530 (define_split
3531   [(set (match_operand:DI 0 "memory_operand" "")
3532         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3533    (clobber (reg:CC FLAGS_REG))
3534    (clobber (match_operand:SI 2 "register_operand" ""))]
3535   "(reload_completed
3536     && dead_or_set_p (insn, operands[1])
3537     && !reg_mentioned_p (operands[1], operands[0]))"
3538   [(set (match_dup 3) (match_dup 1))
3539    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3540               (clobber (reg:CC FLAGS_REG))])
3541    (set (match_dup 4) (match_dup 1))]
3542   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3543
3544 ;; Extend to memory case when source register does not die.
3545 (define_split
3546   [(set (match_operand:DI 0 "memory_operand" "")
3547         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3548    (clobber (reg:CC FLAGS_REG))
3549    (clobber (match_operand:SI 2 "register_operand" ""))]
3550   "reload_completed"
3551   [(const_int 0)]
3552 {
3553   split_di (&operands[0], 1, &operands[3], &operands[4]);
3554
3555   emit_move_insn (operands[3], operands[1]);
3556
3557   /* Generate a cltd if possible and doing so it profitable.  */
3558   if (true_regnum (operands[1]) == 0
3559       && true_regnum (operands[2]) == 1
3560       && (optimize_size || TARGET_USE_CLTD))
3561     {
3562       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3563     }
3564   else
3565     {
3566       emit_move_insn (operands[2], operands[1]);
3567       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3568     }
3569   emit_move_insn (operands[4], operands[2]);
3570   DONE;
3571 })
3572
3573 ;; Extend to register case.  Optimize case where source and destination
3574 ;; registers match and cases where we can use cltd.
3575 (define_split
3576   [(set (match_operand:DI 0 "register_operand" "")
3577         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3578    (clobber (reg:CC FLAGS_REG))
3579    (clobber (match_scratch:SI 2 ""))]
3580   "reload_completed"
3581   [(const_int 0)]
3582 {
3583   split_di (&operands[0], 1, &operands[3], &operands[4]);
3584
3585   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3586     emit_move_insn (operands[3], operands[1]);
3587
3588   /* Generate a cltd if possible and doing so it profitable.  */
3589   if (true_regnum (operands[3]) == 0
3590       && (optimize_size || TARGET_USE_CLTD))
3591     {
3592       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3593       DONE;
3594     }
3595
3596   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3597     emit_move_insn (operands[4], operands[1]);
3598
3599   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3600   DONE;
3601 })
3602
3603 (define_insn "extendhisi2"
3604   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3605         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3606   ""
3607 {
3608   switch (get_attr_prefix_0f (insn))
3609     {
3610     case 0:
3611       return "{cwtl|cwde}";
3612     default:
3613       return "movs{wl|x}\t{%1,%0|%0, %1}";
3614     }
3615 }
3616   [(set_attr "type" "imovx")
3617    (set_attr "mode" "SI")
3618    (set (attr "prefix_0f")
3619      ;; movsx is short decodable while cwtl is vector decoded.
3620      (if_then_else (and (eq_attr "cpu" "!k6")
3621                         (eq_attr "alternative" "0"))
3622         (const_string "0")
3623         (const_string "1")))
3624    (set (attr "modrm")
3625      (if_then_else (eq_attr "prefix_0f" "0")
3626         (const_string "0")
3627         (const_string "1")))])
3628
3629 (define_insn "*extendhisi2_zext"
3630   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3631         (zero_extend:DI
3632           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3633   "TARGET_64BIT"
3634 {
3635   switch (get_attr_prefix_0f (insn))
3636     {
3637     case 0:
3638       return "{cwtl|cwde}";
3639     default:
3640       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3641     }
3642 }
3643   [(set_attr "type" "imovx")
3644    (set_attr "mode" "SI")
3645    (set (attr "prefix_0f")
3646      ;; movsx is short decodable while cwtl is vector decoded.
3647      (if_then_else (and (eq_attr "cpu" "!k6")
3648                         (eq_attr "alternative" "0"))
3649         (const_string "0")
3650         (const_string "1")))
3651    (set (attr "modrm")
3652      (if_then_else (eq_attr "prefix_0f" "0")
3653         (const_string "0")
3654         (const_string "1")))])
3655
3656 (define_insn "extendqihi2"
3657   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3658         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3659   ""
3660 {
3661   switch (get_attr_prefix_0f (insn))
3662     {
3663     case 0:
3664       return "{cbtw|cbw}";
3665     default:
3666       return "movs{bw|x}\t{%1,%0|%0, %1}";
3667     }
3668 }
3669   [(set_attr "type" "imovx")
3670    (set_attr "mode" "HI")
3671    (set (attr "prefix_0f")
3672      ;; movsx is short decodable while cwtl is vector decoded.
3673      (if_then_else (and (eq_attr "cpu" "!k6")
3674                         (eq_attr "alternative" "0"))
3675         (const_string "0")
3676         (const_string "1")))
3677    (set (attr "modrm")
3678      (if_then_else (eq_attr "prefix_0f" "0")
3679         (const_string "0")
3680         (const_string "1")))])
3681
3682 (define_insn "extendqisi2"
3683   [(set (match_operand:SI 0 "register_operand" "=r")
3684         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3685   ""
3686   "movs{bl|x}\t{%1,%0|%0, %1}"
3687    [(set_attr "type" "imovx")
3688     (set_attr "mode" "SI")])
3689
3690 (define_insn "*extendqisi2_zext"
3691   [(set (match_operand:DI 0 "register_operand" "=r")
3692         (zero_extend:DI
3693           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3694   "TARGET_64BIT"
3695   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3696    [(set_attr "type" "imovx")
3697     (set_attr "mode" "SI")])
3698 \f
3699 ;; Conversions between float and double.
3700
3701 ;; These are all no-ops in the model used for the 80387.  So just
3702 ;; emit moves.
3703
3704 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3705 (define_insn "*dummy_extendsfdf2"
3706   [(set (match_operand:DF 0 "push_operand" "=<")
3707         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3708   "0"
3709   "#")
3710
3711 (define_split
3712   [(set (match_operand:DF 0 "push_operand" "")
3713         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3714   "!TARGET_64BIT"
3715   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3716    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3717
3718 (define_split
3719   [(set (match_operand:DF 0 "push_operand" "")
3720         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3721   "TARGET_64BIT"
3722   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3723    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3724
3725 (define_insn "*dummy_extendsfxf2"
3726   [(set (match_operand:XF 0 "push_operand" "=<")
3727         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3728   "0"
3729   "#")
3730
3731 (define_split
3732   [(set (match_operand:XF 0 "push_operand" "")
3733         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3734   ""
3735   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3736    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3737   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3738
3739 (define_split
3740   [(set (match_operand:XF 0 "push_operand" "")
3741         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3742   "TARGET_64BIT"
3743   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3744    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3745   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3746
3747 (define_split
3748   [(set (match_operand:XF 0 "push_operand" "")
3749         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3750   ""
3751   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3752    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3753   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3754
3755 (define_split
3756   [(set (match_operand:XF 0 "push_operand" "")
3757         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3758   "TARGET_64BIT"
3759   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3760    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3761   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3762
3763 (define_expand "extendsfdf2"
3764   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3765         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3766   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3767 {
3768   /* ??? Needed for compress_float_constant since all fp constants
3769      are LEGITIMATE_CONSTANT_P.  */
3770   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3771     {
3772       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3773           && standard_80387_constant_p (operands[1]) > 0)
3774         {
3775           operands[1] = simplify_const_unary_operation
3776             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3777           emit_move_insn_1 (operands[0], operands[1]);
3778           DONE;
3779         }
3780       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3781     }
3782 })
3783
3784 (define_insn "*extendsfdf2_mixed"
3785   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3786         (float_extend:DF
3787           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3788   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3789 {
3790   switch (which_alternative)
3791     {
3792     case 0:
3793       return output_387_reg_move (insn, operands);
3794
3795     case 1:
3796       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3797         return "fstp%z0\t%y0";
3798       else
3799         return "fst%z0\t%y0";
3800
3801     case 2:
3802       return "cvtss2sd\t{%1, %0|%0, %1}";
3803
3804     default:
3805       gcc_unreachable ();
3806     }
3807 }
3808   [(set_attr "type" "fmov,fmov,ssecvt")
3809    (set_attr "mode" "SF,XF,DF")])
3810
3811 (define_insn "*extendsfdf2_sse"
3812   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3813         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3814   "TARGET_SSE2 && TARGET_SSE_MATH"
3815   "cvtss2sd\t{%1, %0|%0, %1}"
3816   [(set_attr "type" "ssecvt")
3817    (set_attr "mode" "DF")])
3818
3819 (define_insn "*extendsfdf2_i387"
3820   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3821         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3822   "TARGET_80387"
3823 {
3824   switch (which_alternative)
3825     {
3826     case 0:
3827       return output_387_reg_move (insn, operands);
3828
3829     case 1:
3830       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3831         return "fstp%z0\t%y0";
3832       else
3833         return "fst%z0\t%y0";
3834
3835     default:
3836       gcc_unreachable ();
3837     }
3838 }
3839   [(set_attr "type" "fmov")
3840    (set_attr "mode" "SF,XF")])
3841
3842 (define_expand "extendsfxf2"
3843   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3844         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3845   "TARGET_80387"
3846 {
3847   /* ??? Needed for compress_float_constant since all fp constants
3848      are LEGITIMATE_CONSTANT_P.  */
3849   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3850     {
3851       if (standard_80387_constant_p (operands[1]) > 0)
3852         {
3853           operands[1] = simplify_const_unary_operation
3854             (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3855           emit_move_insn_1 (operands[0], operands[1]);
3856           DONE;
3857         }
3858       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3859     }
3860 })
3861
3862 (define_insn "*extendsfxf2_i387"
3863   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3864         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3865   "TARGET_80387"
3866 {
3867   switch (which_alternative)
3868     {
3869     case 0:
3870       return output_387_reg_move (insn, operands);
3871
3872     case 1:
3873       /* There is no non-popping store to memory for XFmode.  So if
3874          we need one, follow the store with a load.  */
3875       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3876         return "fstp%z0\t%y0";
3877       else
3878         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3879
3880     default:
3881       gcc_unreachable ();
3882     }
3883 }
3884   [(set_attr "type" "fmov")
3885    (set_attr "mode" "SF,XF")])
3886
3887 (define_expand "extenddfxf2"
3888   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3889         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3890   "TARGET_80387"
3891 {
3892   /* ??? Needed for compress_float_constant since all fp constants
3893      are LEGITIMATE_CONSTANT_P.  */
3894   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3895     {
3896       if (standard_80387_constant_p (operands[1]) > 0)
3897         {
3898           operands[1] = simplify_const_unary_operation
3899             (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3900           emit_move_insn_1 (operands[0], operands[1]);
3901           DONE;
3902         }
3903       operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3904     }
3905 })
3906
3907 (define_insn "*extenddfxf2_i387"
3908   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3909         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3910   "TARGET_80387"
3911 {
3912   switch (which_alternative)
3913     {
3914     case 0:
3915       return output_387_reg_move (insn, operands);
3916
3917     case 1:
3918       /* There is no non-popping store to memory for XFmode.  So if
3919          we need one, follow the store with a load.  */
3920       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3921         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3922       else
3923         return "fstp%z0\t%y0";
3924
3925     default:
3926       gcc_unreachable ();
3927     }
3928 }
3929   [(set_attr "type" "fmov")
3930    (set_attr "mode" "DF,XF")])
3931
3932 ;; %%% This seems bad bad news.
3933 ;; This cannot output into an f-reg because there is no way to be sure
3934 ;; of truncating in that case.  Otherwise this is just like a simple move
3935 ;; insn.  So we pretend we can output to a reg in order to get better
3936 ;; register preferencing, but we really use a stack slot.
3937
3938 ;; Conversion from DFmode to SFmode.
3939
3940 (define_expand "truncdfsf2"
3941   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3942         (float_truncate:SF
3943           (match_operand:DF 1 "nonimmediate_operand" "")))]
3944   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3945 {
3946   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3947     ;
3948   else if (flag_unsafe_math_optimizations)
3949     ;
3950   else
3951     {
3952       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3953       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3954       DONE;
3955     }
3956 })
3957
3958 (define_expand "truncdfsf2_with_temp"
3959   [(parallel [(set (match_operand:SF 0 "" "")
3960                    (float_truncate:SF (match_operand:DF 1 "" "")))
3961               (clobber (match_operand:SF 2 "" ""))])]
3962   "")
3963
3964 (define_insn "*truncdfsf_fast_mixed"
3965   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,x")
3966         (float_truncate:SF
3967           (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
3968   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3969 {
3970   switch (which_alternative)
3971     {
3972     case 0:
3973       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3974         return "fstp%z0\t%y0";
3975       else
3976         return "fst%z0\t%y0";
3977     case 1:
3978       return output_387_reg_move (insn, operands);
3979     case 2:
3980       return "cvtsd2ss\t{%1, %0|%0, %1}";
3981     default:
3982       gcc_unreachable ();
3983     }
3984 }
3985   [(set_attr "type" "fmov,fmov,ssecvt")
3986    (set_attr "mode" "SF")])
3987
3988 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3989 ;; because nothing we do here is unsafe.
3990 (define_insn "*truncdfsf_fast_sse"
3991   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
3992         (float_truncate:SF
3993           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
3994   "TARGET_SSE2 && TARGET_SSE_MATH"
3995   "cvtsd2ss\t{%1, %0|%0, %1}"
3996   [(set_attr "type" "ssecvt")
3997    (set_attr "mode" "SF")])
3998
3999 (define_insn "*truncdfsf_fast_i387"
4000   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4001         (float_truncate:SF
4002           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4003   "TARGET_80387 && flag_unsafe_math_optimizations"
4004   "* return output_387_reg_move (insn, operands);"
4005   [(set_attr "type" "fmov")
4006    (set_attr "mode" "SF")])
4007
4008 (define_insn "*truncdfsf_mixed"
4009   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y2")
4010         (float_truncate:SF
4011           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Y2m")))
4012    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
4013   "TARGET_MIX_SSE_I387"
4014 {
4015   switch (which_alternative)
4016     {
4017     case 0:
4018       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4019         return "fstp%z0\t%y0";
4020       else
4021         return "fst%z0\t%y0";
4022     case 1:
4023       return "#";
4024     case 2:
4025       return "cvtsd2ss\t{%1, %0|%0, %1}";
4026     default:
4027       gcc_unreachable ();
4028     }
4029 }
4030   [(set_attr "type" "fmov,multi,ssecvt")
4031    (set_attr "unit" "*,i387,*")
4032    (set_attr "mode" "SF")])
4033
4034 (define_insn "*truncdfsf_i387"
4035   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4036         (float_truncate:SF
4037           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4038    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4039   "TARGET_80387"
4040 {
4041   switch (which_alternative)
4042     {
4043     case 0:
4044       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4045         return "fstp%z0\t%y0";
4046       else
4047         return "fst%z0\t%y0";
4048     case 1:
4049       return "#";
4050     default:
4051       gcc_unreachable ();
4052     }
4053 }
4054   [(set_attr "type" "fmov,multi")
4055    (set_attr "unit" "*,i387")
4056    (set_attr "mode" "SF")])
4057
4058 (define_insn "*truncdfsf2_i387_1"
4059   [(set (match_operand:SF 0 "memory_operand" "=m")
4060         (float_truncate:SF
4061           (match_operand:DF 1 "register_operand" "f")))]
4062   "TARGET_80387
4063    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4064    && !TARGET_MIX_SSE_I387"
4065 {
4066   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4067     return "fstp%z0\t%y0";
4068   else
4069     return "fst%z0\t%y0";
4070 }
4071   [(set_attr "type" "fmov")
4072    (set_attr "mode" "SF")])
4073
4074 (define_split
4075   [(set (match_operand:SF 0 "register_operand" "")
4076         (float_truncate:SF
4077          (match_operand:DF 1 "fp_register_operand" "")))
4078    (clobber (match_operand 2 "" ""))]
4079   "reload_completed"
4080   [(set (match_dup 2) (match_dup 1))
4081    (set (match_dup 0) (match_dup 2))]
4082 {
4083   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4084 })
4085
4086 ;; Conversion from XFmode to SFmode.
4087
4088 (define_expand "truncxfsf2"
4089   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4090                    (float_truncate:SF
4091                     (match_operand:XF 1 "register_operand" "")))
4092               (clobber (match_dup 2))])]
4093   "TARGET_80387"
4094 {
4095   if (flag_unsafe_math_optimizations)
4096     {
4097       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
4098       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
4099       if (reg != operands[0])
4100         emit_move_insn (operands[0], reg);
4101       DONE;
4102     }
4103   else
4104     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
4105 })
4106
4107 (define_insn "*truncxfsf2_mixed"
4108   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
4109         (float_truncate:SF
4110          (match_operand:XF 1 "register_operand" "f,f,f,f")))
4111    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4112   "TARGET_80387"
4113 {
4114   gcc_assert (!which_alternative);
4115   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4116     return "fstp%z0\t%y0";
4117   else
4118     return "fst%z0\t%y0";
4119 }
4120   [(set_attr "type" "fmov,multi,multi,multi")
4121    (set_attr "unit" "*,i387,i387,i387")
4122    (set_attr "mode" "SF")])
4123
4124 (define_insn "truncxfsf2_i387_noop"
4125   [(set (match_operand:SF 0 "register_operand" "=f")
4126         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
4127   "TARGET_80387 && flag_unsafe_math_optimizations"
4128   "* return output_387_reg_move (insn, operands);"
4129   [(set_attr "type" "fmov")
4130    (set_attr "mode" "SF")])
4131
4132 (define_insn "*truncxfsf2_i387"
4133   [(set (match_operand:SF 0 "memory_operand" "=m")
4134         (float_truncate:SF
4135          (match_operand:XF 1 "register_operand" "f")))]
4136   "TARGET_80387"
4137 {
4138   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4139     return "fstp%z0\t%y0";
4140   else
4141     return "fst%z0\t%y0";
4142 }
4143   [(set_attr "type" "fmov")
4144    (set_attr "mode" "SF")])
4145
4146 (define_split
4147   [(set (match_operand:SF 0 "register_operand" "")
4148         (float_truncate:SF
4149          (match_operand:XF 1 "register_operand" "")))
4150    (clobber (match_operand:SF 2 "memory_operand" ""))]
4151   "TARGET_80387 && reload_completed"
4152   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4153    (set (match_dup 0) (match_dup 2))]
4154   "")
4155
4156 (define_split
4157   [(set (match_operand:SF 0 "memory_operand" "")
4158         (float_truncate:SF
4159          (match_operand:XF 1 "register_operand" "")))
4160    (clobber (match_operand:SF 2 "memory_operand" ""))]
4161   "TARGET_80387"
4162   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4163   "")
4164
4165 ;; Conversion from XFmode to DFmode.
4166
4167 (define_expand "truncxfdf2"
4168   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4169                    (float_truncate:DF
4170                     (match_operand:XF 1 "register_operand" "")))
4171               (clobber (match_dup 2))])]
4172   "TARGET_80387"
4173 {
4174   if (flag_unsafe_math_optimizations)
4175     {
4176       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
4177       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
4178       if (reg != operands[0])
4179         emit_move_insn (operands[0], reg);
4180       DONE;
4181     }
4182   else
4183     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
4184 })
4185
4186 (define_insn "*truncxfdf2_mixed"
4187   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y2*x")
4188         (float_truncate:DF
4189          (match_operand:XF 1 "register_operand" "f,f,f,f")))
4190    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4191   "TARGET_80387"
4192 {
4193   gcc_assert (!which_alternative);
4194   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4195     return "fstp%z0\t%y0";
4196   else
4197     return "fst%z0\t%y0";
4198 }
4199   [(set_attr "type" "fmov,multi,multi,multi")
4200    (set_attr "unit" "*,i387,i387,i387")
4201    (set_attr "mode" "DF")])
4202
4203 (define_insn "truncxfdf2_i387_noop"
4204   [(set (match_operand:DF 0 "register_operand" "=f")
4205         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4206   "TARGET_80387 && flag_unsafe_math_optimizations"
4207   "* return output_387_reg_move (insn, operands);"
4208   [(set_attr "type" "fmov")
4209    (set_attr "mode" "DF")])
4210
4211 (define_insn "*truncxfdf2_i387"
4212   [(set (match_operand:DF 0 "memory_operand" "=m")
4213         (float_truncate:DF
4214           (match_operand:XF 1 "register_operand" "f")))]
4215   "TARGET_80387"
4216 {
4217   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4218     return "fstp%z0\t%y0";
4219   else
4220     return "fst%z0\t%y0";
4221 }
4222   [(set_attr "type" "fmov")
4223    (set_attr "mode" "DF")])
4224
4225 (define_split
4226   [(set (match_operand:DF 0 "register_operand" "")
4227         (float_truncate:DF
4228          (match_operand:XF 1 "register_operand" "")))
4229    (clobber (match_operand:DF 2 "memory_operand" ""))]
4230   "TARGET_80387 && reload_completed"
4231   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4232    (set (match_dup 0) (match_dup 2))]
4233   "")
4234
4235 (define_split
4236   [(set (match_operand:DF 0 "memory_operand" "")
4237         (float_truncate:DF
4238          (match_operand:XF 1 "register_operand" "")))
4239    (clobber (match_operand:DF 2 "memory_operand" ""))]
4240   "TARGET_80387"
4241   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4242   "")
4243 \f
4244 ;; Signed conversion to DImode.
4245
4246 (define_expand "fix_truncxfdi2"
4247   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4248                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4249               (clobber (reg:CC FLAGS_REG))])]
4250   "TARGET_80387"
4251 {
4252   if (TARGET_FISTTP)
4253    {
4254      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4255      DONE;
4256    }
4257 })
4258
4259 (define_expand "fix_trunc<mode>di2"
4260   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4261                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4262               (clobber (reg:CC FLAGS_REG))])]
4263   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4264 {
4265   if (TARGET_FISTTP
4266       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4267    {
4268      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4269      DONE;
4270    }
4271   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4272    {
4273      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4274      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4275      if (out != operands[0])
4276         emit_move_insn (operands[0], out);
4277      DONE;
4278    }
4279 })
4280
4281 ;; Signed conversion to SImode.
4282
4283 (define_expand "fix_truncxfsi2"
4284   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4285                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4286               (clobber (reg:CC FLAGS_REG))])]
4287   "TARGET_80387"
4288 {
4289   if (TARGET_FISTTP)
4290    {
4291      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4292      DONE;
4293    }
4294 })
4295
4296 (define_expand "fix_trunc<mode>si2"
4297   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4298                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4299               (clobber (reg:CC FLAGS_REG))])]
4300   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4301 {
4302   if (TARGET_FISTTP
4303       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4304    {
4305      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4306      DONE;
4307    }
4308   if (SSE_FLOAT_MODE_P (<MODE>mode))
4309    {
4310      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4311      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4312      if (out != operands[0])
4313         emit_move_insn (operands[0], out);
4314      DONE;
4315    }
4316 })
4317
4318 ;; Signed conversion to HImode.
4319
4320 (define_expand "fix_trunc<mode>hi2"
4321   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4322                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4323               (clobber (reg:CC FLAGS_REG))])]
4324   "TARGET_80387
4325    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4326 {
4327   if (TARGET_FISTTP)
4328    {
4329      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4330      DONE;
4331    }
4332 })
4333
4334 ;; Unsigned conversion to SImode.
4335
4336 (define_expand "fixuns_trunc<mode>si2"
4337   [(parallel
4338     [(set (match_operand:SI 0 "register_operand" "")
4339           (unsigned_fix:SI
4340             (match_operand:SSEMODEF 1 "nonimmediate_operand" "")))
4341      (use (match_dup 2))
4342      (clobber (match_scratch:<ssevecmode> 3 ""))
4343      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4344   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4345 {
4346   enum machine_mode mode = <MODE>mode;
4347   enum machine_mode vecmode = <ssevecmode>mode;
4348   REAL_VALUE_TYPE TWO31r;
4349   rtx two31;
4350
4351   real_ldexp (&TWO31r, &dconst1, 31);
4352   two31 = const_double_from_real_value (TWO31r, mode);
4353   two31 = ix86_build_const_vector (mode, true, two31);
4354   operands[2] = force_reg (vecmode, two31);
4355 })
4356
4357 (define_insn_and_split "*fixuns_trunc<mode>_1"
4358   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4359         (unsigned_fix:SI
4360           (match_operand:SSEMODEF 3 "nonimmediate_operand" "xm,xm")))
4361    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4362    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4363    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4364   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4365   "#"
4366   "&& reload_completed"
4367   [(const_int 0)]
4368 {
4369   ix86_split_convert_uns_si_sse (operands);
4370   DONE;
4371 })
4372
4373 ;; Unsigned conversion to HImode.
4374 ;; Without these patterns, we'll try the unsigned SI conversion which
4375 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4376
4377 (define_expand "fixuns_truncsfhi2"
4378   [(set (match_dup 2)
4379         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "")))
4380    (set (match_operand:HI 0 "nonimmediate_operand" "")
4381         (subreg:HI (match_dup 2) 0))]
4382   "TARGET_SSE_MATH"
4383   "operands[2] = gen_reg_rtx (SImode);")
4384
4385 (define_expand "fixuns_truncdfhi2"
4386   [(set (match_dup 2)
4387         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "")))
4388    (set (match_operand:HI 0 "nonimmediate_operand" "")
4389         (subreg:HI (match_dup 2) 0))]
4390   "TARGET_SSE_MATH && TARGET_SSE2"
4391   "operands[2] = gen_reg_rtx (SImode);")
4392
4393 ;; When SSE is available, it is always faster to use it!
4394 (define_insn "fix_truncsfdi_sse"
4395   [(set (match_operand:DI 0 "register_operand" "=r,r")
4396         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4397   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4398   "cvttss2si{q}\t{%1, %0|%0, %1}"
4399   [(set_attr "type" "sseicvt")
4400    (set_attr "mode" "SF")
4401    (set_attr "athlon_decode" "double,vector")
4402    (set_attr "amdfam10_decode" "double,double")])
4403
4404 (define_insn "fix_truncdfdi_sse"
4405   [(set (match_operand:DI 0 "register_operand" "=r,r")
4406         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "x,xm")))]
4407   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4408   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4409   [(set_attr "type" "sseicvt")
4410    (set_attr "mode" "DF")
4411    (set_attr "athlon_decode" "double,vector")
4412    (set_attr "amdfam10_decode" "double,double")])
4413
4414 (define_insn "fix_truncsfsi_sse"
4415   [(set (match_operand:SI 0 "register_operand" "=r,r")
4416         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4417   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4418   "cvttss2si\t{%1, %0|%0, %1}"
4419   [(set_attr "type" "sseicvt")
4420    (set_attr "mode" "DF")
4421    (set_attr "athlon_decode" "double,vector")
4422    (set_attr "amdfam10_decode" "double,double")])
4423
4424 (define_insn "fix_truncdfsi_sse"
4425   [(set (match_operand:SI 0 "register_operand" "=r,r")
4426         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "x,xm")))]
4427   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4428   "cvttsd2si\t{%1, %0|%0, %1}"
4429   [(set_attr "type" "sseicvt")
4430    (set_attr "mode" "DF")
4431    (set_attr "athlon_decode" "double,vector")
4432    (set_attr "amdfam10_decode" "double,double")])
4433
4434 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4435 (define_peephole2
4436   [(set (match_operand:DF 0 "register_operand" "")
4437         (match_operand:DF 1 "memory_operand" ""))
4438    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4439         (fix:SSEMODEI24 (match_dup 0)))]
4440   "!TARGET_K8
4441    && peep2_reg_dead_p (2, operands[0])"
4442   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4443   "")
4444
4445 (define_peephole2
4446   [(set (match_operand:SF 0 "register_operand" "")
4447         (match_operand:SF 1 "memory_operand" ""))
4448    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4449         (fix:SSEMODEI24 (match_dup 0)))]
4450   "!TARGET_K8
4451    && peep2_reg_dead_p (2, operands[0])"
4452   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4453   "")
4454
4455 ;; Avoid vector decoded forms of the instruction.
4456 (define_peephole2
4457   [(match_scratch:DF 2 "Y")
4458    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4459         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4460   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4461   [(set (match_dup 2) (match_dup 1))
4462    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4463   "")
4464
4465 (define_peephole2
4466   [(match_scratch:SF 2 "x")
4467    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4468         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4469   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4470   [(set (match_dup 2) (match_dup 1))
4471    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4472   "")
4473
4474 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4475   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4476         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4477   "TARGET_FISTTP
4478    && FLOAT_MODE_P (GET_MODE (operands[1]))
4479    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4480          && (TARGET_64BIT || <MODE>mode != DImode))
4481         && TARGET_SSE_MATH)
4482    && !(reload_completed || reload_in_progress)"
4483   "#"
4484   "&& 1"
4485   [(const_int 0)]
4486 {
4487   if (memory_operand (operands[0], VOIDmode))
4488     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4489   else
4490     {
4491       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4492       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4493                                                             operands[1],
4494                                                             operands[2]));
4495     }
4496   DONE;
4497 }
4498   [(set_attr "type" "fisttp")
4499    (set_attr "mode" "<MODE>")])
4500
4501 (define_insn "fix_trunc<mode>_i387_fisttp"
4502   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4503         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4504    (clobber (match_scratch:XF 2 "=&1f"))]
4505   "TARGET_FISTTP
4506    && FLOAT_MODE_P (GET_MODE (operands[1]))
4507    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4508          && (TARGET_64BIT || <MODE>mode != DImode))
4509         && TARGET_SSE_MATH)"
4510   "* return output_fix_trunc (insn, operands, 1);"
4511   [(set_attr "type" "fisttp")
4512    (set_attr "mode" "<MODE>")])
4513
4514 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4515   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4516         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4517    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4518    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4519   "TARGET_FISTTP
4520    && FLOAT_MODE_P (GET_MODE (operands[1]))
4521    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4522         && (TARGET_64BIT || <MODE>mode != DImode))
4523         && TARGET_SSE_MATH)"
4524   "#"
4525   [(set_attr "type" "fisttp")
4526    (set_attr "mode" "<MODE>")])
4527
4528 (define_split
4529   [(set (match_operand:X87MODEI 0 "register_operand" "")
4530         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4531    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4532    (clobber (match_scratch 3 ""))]
4533   "reload_completed"
4534   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4535               (clobber (match_dup 3))])
4536    (set (match_dup 0) (match_dup 2))]
4537   "")
4538
4539 (define_split
4540   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4541         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4542    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4543    (clobber (match_scratch 3 ""))]
4544   "reload_completed"
4545   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4546               (clobber (match_dup 3))])]
4547   "")
4548
4549 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4550 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4551 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4552 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4553 ;; function in i386.c.
4554 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4555   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4556         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4557    (clobber (reg:CC FLAGS_REG))]
4558   "TARGET_80387 && !TARGET_FISTTP
4559    && FLOAT_MODE_P (GET_MODE (operands[1]))
4560    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4561          && (TARGET_64BIT || <MODE>mode != DImode))
4562    && !(reload_completed || reload_in_progress)"
4563   "#"
4564   "&& 1"
4565   [(const_int 0)]
4566 {
4567   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4568
4569   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4570   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4571   if (memory_operand (operands[0], VOIDmode))
4572     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4573                                          operands[2], operands[3]));
4574   else
4575     {
4576       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4577       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4578                                                      operands[2], operands[3],
4579                                                      operands[4]));
4580     }
4581   DONE;
4582 }
4583   [(set_attr "type" "fistp")
4584    (set_attr "i387_cw" "trunc")
4585    (set_attr "mode" "<MODE>")])
4586
4587 (define_insn "fix_truncdi_i387"
4588   [(set (match_operand:DI 0 "memory_operand" "=m")
4589         (fix:DI (match_operand 1 "register_operand" "f")))
4590    (use (match_operand:HI 2 "memory_operand" "m"))
4591    (use (match_operand:HI 3 "memory_operand" "m"))
4592    (clobber (match_scratch:XF 4 "=&1f"))]
4593   "TARGET_80387 && !TARGET_FISTTP
4594    && FLOAT_MODE_P (GET_MODE (operands[1]))
4595    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4596   "* return output_fix_trunc (insn, operands, 0);"
4597   [(set_attr "type" "fistp")
4598    (set_attr "i387_cw" "trunc")
4599    (set_attr "mode" "DI")])
4600
4601 (define_insn "fix_truncdi_i387_with_temp"
4602   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4603         (fix:DI (match_operand 1 "register_operand" "f,f")))
4604    (use (match_operand:HI 2 "memory_operand" "m,m"))
4605    (use (match_operand:HI 3 "memory_operand" "m,m"))
4606    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4607    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4608   "TARGET_80387 && !TARGET_FISTTP
4609    && FLOAT_MODE_P (GET_MODE (operands[1]))
4610    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4611   "#"
4612   [(set_attr "type" "fistp")
4613    (set_attr "i387_cw" "trunc")
4614    (set_attr "mode" "DI")])
4615
4616 (define_split
4617   [(set (match_operand:DI 0 "register_operand" "")
4618         (fix:DI (match_operand 1 "register_operand" "")))
4619    (use (match_operand:HI 2 "memory_operand" ""))
4620    (use (match_operand:HI 3 "memory_operand" ""))
4621    (clobber (match_operand:DI 4 "memory_operand" ""))
4622    (clobber (match_scratch 5 ""))]
4623   "reload_completed"
4624   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4625               (use (match_dup 2))
4626               (use (match_dup 3))
4627               (clobber (match_dup 5))])
4628    (set (match_dup 0) (match_dup 4))]
4629   "")
4630
4631 (define_split
4632   [(set (match_operand:DI 0 "memory_operand" "")
4633         (fix:DI (match_operand 1 "register_operand" "")))
4634    (use (match_operand:HI 2 "memory_operand" ""))
4635    (use (match_operand:HI 3 "memory_operand" ""))
4636    (clobber (match_operand:DI 4 "memory_operand" ""))
4637    (clobber (match_scratch 5 ""))]
4638   "reload_completed"
4639   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4640               (use (match_dup 2))
4641               (use (match_dup 3))
4642               (clobber (match_dup 5))])]
4643   "")
4644
4645 (define_insn "fix_trunc<mode>_i387"
4646   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4647         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4648    (use (match_operand:HI 2 "memory_operand" "m"))
4649    (use (match_operand:HI 3 "memory_operand" "m"))]
4650   "TARGET_80387 && !TARGET_FISTTP
4651    && FLOAT_MODE_P (GET_MODE (operands[1]))
4652    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4653   "* return output_fix_trunc (insn, operands, 0);"
4654   [(set_attr "type" "fistp")
4655    (set_attr "i387_cw" "trunc")
4656    (set_attr "mode" "<MODE>")])
4657
4658 (define_insn "fix_trunc<mode>_i387_with_temp"
4659   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4660         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4661    (use (match_operand:HI 2 "memory_operand" "m,m"))
4662    (use (match_operand:HI 3 "memory_operand" "m,m"))
4663    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4664   "TARGET_80387 && !TARGET_FISTTP
4665    && FLOAT_MODE_P (GET_MODE (operands[1]))
4666    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4667   "#"
4668   [(set_attr "type" "fistp")
4669    (set_attr "i387_cw" "trunc")
4670    (set_attr "mode" "<MODE>")])
4671
4672 (define_split
4673   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4674         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4675    (use (match_operand:HI 2 "memory_operand" ""))
4676    (use (match_operand:HI 3 "memory_operand" ""))
4677    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4678   "reload_completed"
4679   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4680               (use (match_dup 2))
4681               (use (match_dup 3))])
4682    (set (match_dup 0) (match_dup 4))]
4683   "")
4684
4685 (define_split
4686   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4687         (fix:X87MODEI12 (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:X87MODEI12 4 "memory_operand" ""))]
4691   "reload_completed"
4692   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4693               (use (match_dup 2))
4694               (use (match_dup 3))])]
4695   "")
4696
4697 (define_insn "x86_fnstcw_1"
4698   [(set (match_operand:HI 0 "memory_operand" "=m")
4699         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4700   "TARGET_80387"
4701   "fnstcw\t%0"
4702   [(set_attr "length" "2")
4703    (set_attr "mode" "HI")
4704    (set_attr "unit" "i387")])
4705
4706 (define_insn "x86_fldcw_1"
4707   [(set (reg:HI FPCR_REG)
4708         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4709   "TARGET_80387"
4710   "fldcw\t%0"
4711   [(set_attr "length" "2")
4712    (set_attr "mode" "HI")
4713    (set_attr "unit" "i387")
4714    (set_attr "athlon_decode" "vector")
4715    (set_attr "amdfam10_decode" "vector")])   
4716 \f
4717 ;; Conversion between fixed point and floating point.
4718
4719 ;; Even though we only accept memory inputs, the backend _really_
4720 ;; wants to be able to do this between registers.
4721
4722 (define_expand "floathisf2"
4723   [(set (match_operand:SF 0 "register_operand" "")
4724         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4725   "TARGET_80387 || TARGET_SSE_MATH"
4726 {
4727   if (TARGET_SSE_MATH)
4728     {
4729       emit_insn (gen_floatsisf2 (operands[0],
4730                                  convert_to_mode (SImode, operands[1], 0)));
4731       DONE;
4732     }
4733 })
4734
4735 (define_insn "*floathisf2_i387"
4736   [(set (match_operand:SF 0 "register_operand" "=f,f")
4737         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4738   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4739   "@
4740    fild%z1\t%1
4741    #"
4742   [(set_attr "type" "fmov,multi")
4743    (set_attr "mode" "SF")
4744    (set_attr "unit" "*,i387")
4745    (set_attr "fp_int_src" "true")])
4746
4747 (define_expand "floatsisf2"
4748   [(set (match_operand:SF 0 "register_operand" "")
4749         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4750   "TARGET_80387 || TARGET_SSE_MATH"
4751   "")
4752
4753 (define_insn "*floatsisf2_mixed"
4754   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4755         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4756   "TARGET_MIX_SSE_I387"
4757   "@
4758    fild%z1\t%1
4759    #
4760    cvtsi2ss\t{%1, %0|%0, %1}
4761    cvtsi2ss\t{%1, %0|%0, %1}"
4762   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4763    (set_attr "mode" "SF")
4764    (set_attr "unit" "*,i387,*,*")
4765    (set_attr "athlon_decode" "*,*,vector,double")
4766    (set_attr "amdfam10_decode" "*,*,vector,double")
4767    (set_attr "fp_int_src" "true")])
4768
4769 (define_insn "*floatsisf2_sse"
4770   [(set (match_operand:SF 0 "register_operand" "=x,x")
4771         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4772   "TARGET_SSE_MATH"
4773   "cvtsi2ss\t{%1, %0|%0, %1}"
4774   [(set_attr "type" "sseicvt")
4775    (set_attr "mode" "SF")
4776    (set_attr "athlon_decode" "vector,double")
4777    (set_attr "amdfam10_decode" "vector,double")
4778    (set_attr "fp_int_src" "true")])
4779
4780 (define_insn "*floatsisf2_i387"
4781   [(set (match_operand:SF 0 "register_operand" "=f,f")
4782         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4783   "TARGET_80387"
4784   "@
4785    fild%z1\t%1
4786    #"
4787   [(set_attr "type" "fmov,multi")
4788    (set_attr "mode" "SF")
4789    (set_attr "unit" "*,i387")
4790    (set_attr "fp_int_src" "true")])
4791
4792 (define_expand "floatdisf2"
4793   [(set (match_operand:SF 0 "register_operand" "")
4794         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4795   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4796   "")
4797
4798 (define_insn "*floatdisf2_mixed"
4799   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4800         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4801   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4802   "@
4803    fild%z1\t%1
4804    #
4805    cvtsi2ss{q}\t{%1, %0|%0, %1}
4806    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4807   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4808    (set_attr "mode" "SF")
4809    (set_attr "unit" "*,i387,*,*")
4810    (set_attr "athlon_decode" "*,*,vector,double")
4811    (set_attr "amdfam10_decode" "*,*,vector,double")
4812    (set_attr "fp_int_src" "true")])
4813
4814 (define_insn "*floatdisf2_sse"
4815   [(set (match_operand:SF 0 "register_operand" "=x,x")
4816         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4817   "TARGET_64BIT && TARGET_SSE_MATH"
4818   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4819   [(set_attr "type" "sseicvt")
4820    (set_attr "mode" "SF")
4821    (set_attr "athlon_decode" "vector,double")
4822    (set_attr "amdfam10_decode" "vector,double")
4823    (set_attr "fp_int_src" "true")])
4824
4825 (define_insn "*floatdisf2_i387"
4826   [(set (match_operand:SF 0 "register_operand" "=f,f")
4827         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4828   "TARGET_80387"
4829   "@
4830    fild%z1\t%1
4831    #"
4832   [(set_attr "type" "fmov,multi")
4833    (set_attr "mode" "SF")
4834    (set_attr "unit" "*,i387")
4835    (set_attr "fp_int_src" "true")])
4836
4837 (define_expand "floathidf2"
4838   [(set (match_operand:DF 0 "register_operand" "")
4839         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4840   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4841 {
4842   if (TARGET_SSE2 && TARGET_SSE_MATH)
4843     {
4844       emit_insn (gen_floatsidf2 (operands[0],
4845                                  convert_to_mode (SImode, operands[1], 0)));
4846       DONE;
4847     }
4848 })
4849
4850 (define_insn "*floathidf2_i387"
4851   [(set (match_operand:DF 0 "register_operand" "=f,f")
4852         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4853   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4854   "@
4855    fild%z1\t%1
4856    #"
4857   [(set_attr "type" "fmov,multi")
4858    (set_attr "mode" "DF")
4859    (set_attr "unit" "*,i387")
4860    (set_attr "fp_int_src" "true")])
4861
4862 (define_expand "floatsidf2"
4863   [(set (match_operand:DF 0 "register_operand" "")
4864         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4865   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4866   "")
4867
4868 (define_insn "*floatsidf2_mixed"
4869   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4870         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4871   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4872   "@
4873    fild%z1\t%1
4874    #
4875    cvtsi2sd\t{%1, %0|%0, %1}
4876    cvtsi2sd\t{%1, %0|%0, %1}"
4877   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4878    (set_attr "mode" "DF")
4879    (set_attr "unit" "*,i387,*,*")
4880    (set_attr "athlon_decode" "*,*,double,direct")
4881    (set_attr "amdfam10_decode" "*,*,vector,double")
4882    (set_attr "fp_int_src" "true")])
4883
4884 (define_insn "*floatsidf2_sse"
4885   [(set (match_operand:DF 0 "register_operand" "=x,x")
4886         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4887   "TARGET_SSE2 && TARGET_SSE_MATH"
4888   "cvtsi2sd\t{%1, %0|%0, %1}"
4889   [(set_attr "type" "sseicvt")
4890    (set_attr "mode" "DF")
4891    (set_attr "athlon_decode" "double,direct")
4892    (set_attr "amdfam10_decode" "vector,double")
4893    (set_attr "fp_int_src" "true")])
4894
4895 (define_insn "*floatsidf2_i387"
4896   [(set (match_operand:DF 0 "register_operand" "=f,f")
4897         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4898   "TARGET_80387"
4899   "@
4900    fild%z1\t%1
4901    #"
4902   [(set_attr "type" "fmov,multi")
4903    (set_attr "mode" "DF")
4904    (set_attr "unit" "*,i387")
4905    (set_attr "fp_int_src" "true")])
4906
4907 (define_expand "floatdidf2"
4908   [(set (match_operand:DF 0 "register_operand" "")
4909         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4910   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4911 {
4912   if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
4913     {
4914       ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
4915       DONE;
4916     }
4917 })
4918
4919 (define_insn "*floatdidf2_mixed"
4920   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4921         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4922   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4923   "@
4924    fild%z1\t%1
4925    #
4926    cvtsi2sd{q}\t{%1, %0|%0, %1}
4927    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4928   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4929    (set_attr "mode" "DF")
4930    (set_attr "unit" "*,i387,*,*")
4931    (set_attr "athlon_decode" "*,*,double,direct")
4932    (set_attr "amdfam10_decode" "*,*,vector,double")
4933    (set_attr "fp_int_src" "true")])
4934
4935 (define_insn "*floatdidf2_sse"
4936   [(set (match_operand:DF 0 "register_operand" "=x,x")
4937         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4938   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4939   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4940   [(set_attr "type" "sseicvt")
4941    (set_attr "mode" "DF")
4942    (set_attr "athlon_decode" "double,direct")
4943    (set_attr "amdfam10_decode" "vector,double")
4944    (set_attr "fp_int_src" "true")])
4945
4946 (define_insn "*floatdidf2_i387"
4947   [(set (match_operand:DF 0 "register_operand" "=f,f")
4948         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4949   "TARGET_80387"
4950   "@
4951    fild%z1\t%1
4952    #"
4953   [(set_attr "type" "fmov,multi")
4954    (set_attr "mode" "DF")
4955    (set_attr "unit" "*,i387")
4956    (set_attr "fp_int_src" "true")])
4957
4958 (define_insn "floathixf2"
4959   [(set (match_operand:XF 0 "register_operand" "=f,f")
4960         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4961   "TARGET_80387"
4962   "@
4963    fild%z1\t%1
4964    #"
4965   [(set_attr "type" "fmov,multi")
4966    (set_attr "mode" "XF")
4967    (set_attr "unit" "*,i387")
4968    (set_attr "fp_int_src" "true")])
4969
4970 (define_insn "floatsixf2"
4971   [(set (match_operand:XF 0 "register_operand" "=f,f")
4972         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4973   "TARGET_80387"
4974   "@
4975    fild%z1\t%1
4976    #"
4977   [(set_attr "type" "fmov,multi")
4978    (set_attr "mode" "XF")
4979    (set_attr "unit" "*,i387")
4980    (set_attr "fp_int_src" "true")])
4981
4982 (define_insn "floatdixf2"
4983   [(set (match_operand:XF 0 "register_operand" "=f,f")
4984         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4985   "TARGET_80387"
4986   "@
4987    fild%z1\t%1
4988    #"
4989   [(set_attr "type" "fmov,multi")
4990    (set_attr "mode" "XF")
4991    (set_attr "unit" "*,i387")
4992    (set_attr "fp_int_src" "true")])
4993
4994 ;; %%% Kill these when reload knows how to do it.
4995 (define_split
4996   [(set (match_operand 0 "fp_register_operand" "")
4997         (float (match_operand 1 "register_operand" "")))]
4998   "reload_completed
4999    && TARGET_80387
5000    && FLOAT_MODE_P (GET_MODE (operands[0]))"
5001   [(const_int 0)]
5002 {
5003   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5004   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5005   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5006   ix86_free_from_memory (GET_MODE (operands[1]));
5007   DONE;
5008 })
5009
5010 (define_expand "floatunssisf2"
5011   [(use (match_operand:SF 0 "register_operand" ""))
5012    (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5013   "!TARGET_64BIT"
5014 {
5015   if (TARGET_SSE_MATH && TARGET_SSE2)
5016     ix86_expand_convert_uns_sisf_sse (operands[0], operands[1]);
5017   else
5018     x86_emit_floatuns (operands);
5019   DONE;
5020 })
5021
5022 (define_expand "floatunssidf2"
5023   [(use (match_operand:DF 0 "register_operand" ""))
5024    (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5025   "!TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE2"
5026   "ix86_expand_convert_uns_sidf_sse (operands[0], operands[1]); DONE;")
5027
5028 (define_expand "floatunsdisf2"
5029   [(use (match_operand:SF 0 "register_operand" ""))
5030    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5031   "TARGET_64BIT && TARGET_SSE_MATH"
5032   "x86_emit_floatuns (operands); DONE;")
5033
5034 (define_expand "floatunsdidf2"
5035   [(use (match_operand:DF 0 "register_operand" ""))
5036    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5037   "TARGET_SSE_MATH && TARGET_SSE2
5038    && (TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)"
5039 {
5040   if (TARGET_64BIT)
5041     x86_emit_floatuns (operands);
5042   else
5043     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5044   DONE;
5045 })
5046 \f
5047 ;; SSE extract/set expanders
5048
5049 \f
5050 ;; Add instructions
5051
5052 ;; %%% splits for addditi3
5053
5054 (define_expand "addti3"
5055   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5056         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5057                  (match_operand:TI 2 "x86_64_general_operand" "")))
5058    (clobber (reg:CC FLAGS_REG))]
5059   "TARGET_64BIT"
5060   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5061
5062 (define_insn "*addti3_1"
5063   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5064         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5065                  (match_operand:TI 2 "general_operand" "roiF,riF")))
5066    (clobber (reg:CC FLAGS_REG))]
5067   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5068   "#")
5069
5070 (define_split
5071   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5072         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5073                  (match_operand:TI 2 "general_operand" "")))
5074    (clobber (reg:CC FLAGS_REG))]
5075   "TARGET_64BIT && reload_completed"
5076   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5077                                           UNSPEC_ADD_CARRY))
5078               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5079    (parallel [(set (match_dup 3)
5080                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5081                                      (match_dup 4))
5082                             (match_dup 5)))
5083               (clobber (reg:CC FLAGS_REG))])]
5084   "split_ti (operands+0, 1, operands+0, operands+3);
5085    split_ti (operands+1, 1, operands+1, operands+4);
5086    split_ti (operands+2, 1, operands+2, operands+5);")
5087
5088 ;; %%% splits for addsidi3
5089 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5090 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5091 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5092
5093 (define_expand "adddi3"
5094   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5095         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5096                  (match_operand:DI 2 "x86_64_general_operand" "")))
5097    (clobber (reg:CC FLAGS_REG))]
5098   ""
5099   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5100
5101 (define_insn "*adddi3_1"
5102   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5103         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5104                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5105    (clobber (reg:CC FLAGS_REG))]
5106   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5107   "#")
5108
5109 (define_split
5110   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5111         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5112                  (match_operand:DI 2 "general_operand" "")))
5113    (clobber (reg:CC FLAGS_REG))]
5114   "!TARGET_64BIT && reload_completed"
5115   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5116                                           UNSPEC_ADD_CARRY))
5117               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5118    (parallel [(set (match_dup 3)
5119                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5120                                      (match_dup 4))
5121                             (match_dup 5)))
5122               (clobber (reg:CC FLAGS_REG))])]
5123   "split_di (operands+0, 1, operands+0, operands+3);
5124    split_di (operands+1, 1, operands+1, operands+4);
5125    split_di (operands+2, 1, operands+2, operands+5);")
5126
5127 (define_insn "adddi3_carry_rex64"
5128   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5129           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5130                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5131                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5132    (clobber (reg:CC FLAGS_REG))]
5133   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5134   "adc{q}\t{%2, %0|%0, %2}"
5135   [(set_attr "type" "alu")
5136    (set_attr "pent_pair" "pu")
5137    (set_attr "mode" "DI")])
5138
5139 (define_insn "*adddi3_cc_rex64"
5140   [(set (reg:CC FLAGS_REG)
5141         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5142                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5143                    UNSPEC_ADD_CARRY))
5144    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5145         (plus:DI (match_dup 1) (match_dup 2)))]
5146   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5147   "add{q}\t{%2, %0|%0, %2}"
5148   [(set_attr "type" "alu")
5149    (set_attr "mode" "DI")])
5150
5151 (define_insn "addqi3_carry"
5152   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5153           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5154                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5155                    (match_operand:QI 2 "general_operand" "qi,qm")))
5156    (clobber (reg:CC FLAGS_REG))]
5157   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5158   "adc{b}\t{%2, %0|%0, %2}"
5159   [(set_attr "type" "alu")
5160    (set_attr "pent_pair" "pu")
5161    (set_attr "mode" "QI")])
5162
5163 (define_insn "addhi3_carry"
5164   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5165           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5166                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5167                    (match_operand:HI 2 "general_operand" "ri,rm")))
5168    (clobber (reg:CC FLAGS_REG))]
5169   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5170   "adc{w}\t{%2, %0|%0, %2}"
5171   [(set_attr "type" "alu")
5172    (set_attr "pent_pair" "pu")
5173    (set_attr "mode" "HI")])
5174
5175 (define_insn "addsi3_carry"
5176   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5177           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5178                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5179                    (match_operand:SI 2 "general_operand" "ri,rm")))
5180    (clobber (reg:CC FLAGS_REG))]
5181   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5182   "adc{l}\t{%2, %0|%0, %2}"
5183   [(set_attr "type" "alu")
5184    (set_attr "pent_pair" "pu")
5185    (set_attr "mode" "SI")])
5186
5187 (define_insn "*addsi3_carry_zext"
5188   [(set (match_operand:DI 0 "register_operand" "=r")
5189           (zero_extend:DI
5190             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5191                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5192                      (match_operand:SI 2 "general_operand" "rim"))))
5193    (clobber (reg:CC FLAGS_REG))]
5194   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5195   "adc{l}\t{%2, %k0|%k0, %2}"
5196   [(set_attr "type" "alu")
5197    (set_attr "pent_pair" "pu")
5198    (set_attr "mode" "SI")])
5199
5200 (define_insn "*addsi3_cc"
5201   [(set (reg:CC FLAGS_REG)
5202         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5203                     (match_operand:SI 2 "general_operand" "ri,rm")]
5204                    UNSPEC_ADD_CARRY))
5205    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5206         (plus:SI (match_dup 1) (match_dup 2)))]
5207   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5208   "add{l}\t{%2, %0|%0, %2}"
5209   [(set_attr "type" "alu")
5210    (set_attr "mode" "SI")])
5211
5212 (define_insn "addqi3_cc"
5213   [(set (reg:CC FLAGS_REG)
5214         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5215                     (match_operand:QI 2 "general_operand" "qi,qm")]
5216                    UNSPEC_ADD_CARRY))
5217    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5218         (plus:QI (match_dup 1) (match_dup 2)))]
5219   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5220   "add{b}\t{%2, %0|%0, %2}"
5221   [(set_attr "type" "alu")
5222    (set_attr "mode" "QI")])
5223
5224 (define_expand "addsi3"
5225   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5226                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5227                             (match_operand:SI 2 "general_operand" "")))
5228               (clobber (reg:CC FLAGS_REG))])]
5229   ""
5230   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5231
5232 (define_insn "*lea_1"
5233   [(set (match_operand:SI 0 "register_operand" "=r")
5234         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5235   "!TARGET_64BIT"
5236   "lea{l}\t{%a1, %0|%0, %a1}"
5237   [(set_attr "type" "lea")
5238    (set_attr "mode" "SI")])
5239
5240 (define_insn "*lea_1_rex64"
5241   [(set (match_operand:SI 0 "register_operand" "=r")
5242         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5243   "TARGET_64BIT"
5244   "lea{l}\t{%a1, %0|%0, %a1}"
5245   [(set_attr "type" "lea")
5246    (set_attr "mode" "SI")])
5247
5248 (define_insn "*lea_1_zext"
5249   [(set (match_operand:DI 0 "register_operand" "=r")
5250         (zero_extend:DI
5251          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5252   "TARGET_64BIT"
5253   "lea{l}\t{%a1, %k0|%k0, %a1}"
5254   [(set_attr "type" "lea")
5255    (set_attr "mode" "SI")])
5256
5257 (define_insn "*lea_2_rex64"
5258   [(set (match_operand:DI 0 "register_operand" "=r")
5259         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5260   "TARGET_64BIT"
5261   "lea{q}\t{%a1, %0|%0, %a1}"
5262   [(set_attr "type" "lea")
5263    (set_attr "mode" "DI")])
5264
5265 ;; The lea patterns for non-Pmodes needs to be matched by several
5266 ;; insns converted to real lea by splitters.
5267
5268 (define_insn_and_split "*lea_general_1"
5269   [(set (match_operand 0 "register_operand" "=r")
5270         (plus (plus (match_operand 1 "index_register_operand" "l")
5271                     (match_operand 2 "register_operand" "r"))
5272               (match_operand 3 "immediate_operand" "i")))]
5273   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5274     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5275    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5276    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5277    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5278    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5279        || GET_MODE (operands[3]) == VOIDmode)"
5280   "#"
5281   "&& reload_completed"
5282   [(const_int 0)]
5283 {
5284   rtx pat;
5285   operands[0] = gen_lowpart (SImode, operands[0]);
5286   operands[1] = gen_lowpart (Pmode, operands[1]);
5287   operands[2] = gen_lowpart (Pmode, operands[2]);
5288   operands[3] = gen_lowpart (Pmode, operands[3]);
5289   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5290                       operands[3]);
5291   if (Pmode != SImode)
5292     pat = gen_rtx_SUBREG (SImode, pat, 0);
5293   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5294   DONE;
5295 }
5296   [(set_attr "type" "lea")
5297    (set_attr "mode" "SI")])
5298
5299 (define_insn_and_split "*lea_general_1_zext"
5300   [(set (match_operand:DI 0 "register_operand" "=r")
5301         (zero_extend:DI
5302           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5303                             (match_operand:SI 2 "register_operand" "r"))
5304                    (match_operand:SI 3 "immediate_operand" "i"))))]
5305   "TARGET_64BIT"
5306   "#"
5307   "&& reload_completed"
5308   [(set (match_dup 0)
5309         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5310                                                      (match_dup 2))
5311                                             (match_dup 3)) 0)))]
5312 {
5313   operands[1] = gen_lowpart (Pmode, operands[1]);
5314   operands[2] = gen_lowpart (Pmode, operands[2]);
5315   operands[3] = gen_lowpart (Pmode, operands[3]);
5316 }
5317   [(set_attr "type" "lea")
5318    (set_attr "mode" "SI")])
5319
5320 (define_insn_and_split "*lea_general_2"
5321   [(set (match_operand 0 "register_operand" "=r")
5322         (plus (mult (match_operand 1 "index_register_operand" "l")
5323                     (match_operand 2 "const248_operand" "i"))
5324               (match_operand 3 "nonmemory_operand" "ri")))]
5325   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5326     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5327    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5328    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5329    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5330        || GET_MODE (operands[3]) == VOIDmode)"
5331   "#"
5332   "&& reload_completed"
5333   [(const_int 0)]
5334 {
5335   rtx pat;
5336   operands[0] = gen_lowpart (SImode, operands[0]);
5337   operands[1] = gen_lowpart (Pmode, operands[1]);
5338   operands[3] = gen_lowpart (Pmode, operands[3]);
5339   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5340                       operands[3]);
5341   if (Pmode != SImode)
5342     pat = gen_rtx_SUBREG (SImode, pat, 0);
5343   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5344   DONE;
5345 }
5346   [(set_attr "type" "lea")
5347    (set_attr "mode" "SI")])
5348
5349 (define_insn_and_split "*lea_general_2_zext"
5350   [(set (match_operand:DI 0 "register_operand" "=r")
5351         (zero_extend:DI
5352           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5353                             (match_operand:SI 2 "const248_operand" "n"))
5354                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5355   "TARGET_64BIT"
5356   "#"
5357   "&& reload_completed"
5358   [(set (match_dup 0)
5359         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5360                                                      (match_dup 2))
5361                                             (match_dup 3)) 0)))]
5362 {
5363   operands[1] = gen_lowpart (Pmode, operands[1]);
5364   operands[3] = gen_lowpart (Pmode, operands[3]);
5365 }
5366   [(set_attr "type" "lea")
5367    (set_attr "mode" "SI")])
5368
5369 (define_insn_and_split "*lea_general_3"
5370   [(set (match_operand 0 "register_operand" "=r")
5371         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5372                           (match_operand 2 "const248_operand" "i"))
5373                     (match_operand 3 "register_operand" "r"))
5374               (match_operand 4 "immediate_operand" "i")))]
5375   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5376     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5377    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5378    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5379    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5380   "#"
5381   "&& reload_completed"
5382   [(const_int 0)]
5383 {
5384   rtx pat;
5385   operands[0] = gen_lowpart (SImode, operands[0]);
5386   operands[1] = gen_lowpart (Pmode, operands[1]);
5387   operands[3] = gen_lowpart (Pmode, operands[3]);
5388   operands[4] = gen_lowpart (Pmode, operands[4]);
5389   pat = gen_rtx_PLUS (Pmode,
5390                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5391                                                          operands[2]),
5392                                     operands[3]),
5393                       operands[4]);
5394   if (Pmode != SImode)
5395     pat = gen_rtx_SUBREG (SImode, pat, 0);
5396   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5397   DONE;
5398 }
5399   [(set_attr "type" "lea")
5400    (set_attr "mode" "SI")])
5401
5402 (define_insn_and_split "*lea_general_3_zext"
5403   [(set (match_operand:DI 0 "register_operand" "=r")
5404         (zero_extend:DI
5405           (plus:SI (plus:SI (mult:SI
5406                               (match_operand:SI 1 "index_register_operand" "l")
5407                               (match_operand:SI 2 "const248_operand" "n"))
5408                             (match_operand:SI 3 "register_operand" "r"))
5409                    (match_operand:SI 4 "immediate_operand" "i"))))]
5410   "TARGET_64BIT"
5411   "#"
5412   "&& reload_completed"
5413   [(set (match_dup 0)
5414         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5415                                                               (match_dup 2))
5416                                                      (match_dup 3))
5417                                             (match_dup 4)) 0)))]
5418 {
5419   operands[1] = gen_lowpart (Pmode, operands[1]);
5420   operands[3] = gen_lowpart (Pmode, operands[3]);
5421   operands[4] = gen_lowpart (Pmode, operands[4]);
5422 }
5423   [(set_attr "type" "lea")
5424    (set_attr "mode" "SI")])
5425
5426 (define_insn "*adddi_1_rex64"
5427   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5428         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5429                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5430    (clobber (reg:CC FLAGS_REG))]
5431   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5432 {
5433   switch (get_attr_type (insn))
5434     {
5435     case TYPE_LEA:
5436       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5437       return "lea{q}\t{%a2, %0|%0, %a2}";
5438
5439     case TYPE_INCDEC:
5440       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5441       if (operands[2] == const1_rtx)
5442         return "inc{q}\t%0";
5443       else
5444         {
5445           gcc_assert (operands[2] == constm1_rtx);
5446           return "dec{q}\t%0";
5447         }
5448
5449     default:
5450       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5451
5452       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5453          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5454       if (CONST_INT_P (operands[2])
5455           /* Avoid overflows.  */
5456           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5457           && (INTVAL (operands[2]) == 128
5458               || (INTVAL (operands[2]) < 0
5459                   && INTVAL (operands[2]) != -128)))
5460         {
5461           operands[2] = GEN_INT (-INTVAL (operands[2]));
5462           return "sub{q}\t{%2, %0|%0, %2}";
5463         }
5464       return "add{q}\t{%2, %0|%0, %2}";
5465     }
5466 }
5467   [(set (attr "type")
5468      (cond [(eq_attr "alternative" "2")
5469               (const_string "lea")
5470             ; Current assemblers are broken and do not allow @GOTOFF in
5471             ; ought but a memory context.
5472             (match_operand:DI 2 "pic_symbolic_operand" "")
5473               (const_string "lea")
5474             (match_operand:DI 2 "incdec_operand" "")
5475               (const_string "incdec")
5476            ]
5477            (const_string "alu")))
5478    (set_attr "mode" "DI")])
5479
5480 ;; Convert lea to the lea pattern to avoid flags dependency.
5481 (define_split
5482   [(set (match_operand:DI 0 "register_operand" "")
5483         (plus:DI (match_operand:DI 1 "register_operand" "")
5484                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5485    (clobber (reg:CC FLAGS_REG))]
5486   "TARGET_64BIT && reload_completed
5487    && true_regnum (operands[0]) != true_regnum (operands[1])"
5488   [(set (match_dup 0)
5489         (plus:DI (match_dup 1)
5490                  (match_dup 2)))]
5491   "")
5492
5493 (define_insn "*adddi_2_rex64"
5494   [(set (reg FLAGS_REG)
5495         (compare
5496           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5497                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5498           (const_int 0)))
5499    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5500         (plus:DI (match_dup 1) (match_dup 2)))]
5501   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5502    && ix86_binary_operator_ok (PLUS, DImode, operands)
5503    /* Current assemblers are broken and do not allow @GOTOFF in
5504       ought but a memory context.  */
5505    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5506 {
5507   switch (get_attr_type (insn))
5508     {
5509     case TYPE_INCDEC:
5510       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5511       if (operands[2] == const1_rtx)
5512         return "inc{q}\t%0";
5513       else
5514         {
5515           gcc_assert (operands[2] == constm1_rtx);
5516           return "dec{q}\t%0";
5517         }
5518
5519     default:
5520       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5521       /* ???? We ought to handle there the 32bit case too
5522          - do we need new constraint?  */
5523       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5524          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5525       if (CONST_INT_P (operands[2])
5526           /* Avoid overflows.  */
5527           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5528           && (INTVAL (operands[2]) == 128
5529               || (INTVAL (operands[2]) < 0
5530                   && INTVAL (operands[2]) != -128)))
5531         {
5532           operands[2] = GEN_INT (-INTVAL (operands[2]));
5533           return "sub{q}\t{%2, %0|%0, %2}";
5534         }
5535       return "add{q}\t{%2, %0|%0, %2}";
5536     }
5537 }
5538   [(set (attr "type")
5539      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5540         (const_string "incdec")
5541         (const_string "alu")))
5542    (set_attr "mode" "DI")])
5543
5544 (define_insn "*adddi_3_rex64"
5545   [(set (reg FLAGS_REG)
5546         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5547                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5548    (clobber (match_scratch:DI 0 "=r"))]
5549   "TARGET_64BIT
5550    && ix86_match_ccmode (insn, CCZmode)
5551    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5552    /* Current assemblers are broken and do not allow @GOTOFF in
5553       ought but a memory context.  */
5554    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5555 {
5556   switch (get_attr_type (insn))
5557     {
5558     case TYPE_INCDEC:
5559       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5560       if (operands[2] == const1_rtx)
5561         return "inc{q}\t%0";
5562       else
5563         {
5564           gcc_assert (operands[2] == constm1_rtx);
5565           return "dec{q}\t%0";
5566         }
5567
5568     default:
5569       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5570       /* ???? We ought to handle there the 32bit case too
5571          - do we need new constraint?  */
5572       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5573          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5574       if (CONST_INT_P (operands[2])
5575           /* Avoid overflows.  */
5576           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5577           && (INTVAL (operands[2]) == 128
5578               || (INTVAL (operands[2]) < 0
5579                   && INTVAL (operands[2]) != -128)))
5580         {
5581           operands[2] = GEN_INT (-INTVAL (operands[2]));
5582           return "sub{q}\t{%2, %0|%0, %2}";
5583         }
5584       return "add{q}\t{%2, %0|%0, %2}";
5585     }
5586 }
5587   [(set (attr "type")
5588      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5589         (const_string "incdec")
5590         (const_string "alu")))
5591    (set_attr "mode" "DI")])
5592
5593 ; For comparisons against 1, -1 and 128, we may generate better code
5594 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5595 ; is matched then.  We can't accept general immediate, because for
5596 ; case of overflows,  the result is messed up.
5597 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5598 ; when negated.
5599 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5600 ; only for comparisons not depending on it.
5601 (define_insn "*adddi_4_rex64"
5602   [(set (reg FLAGS_REG)
5603         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5604                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5605    (clobber (match_scratch:DI 0 "=rm"))]
5606   "TARGET_64BIT
5607    &&  ix86_match_ccmode (insn, CCGCmode)"
5608 {
5609   switch (get_attr_type (insn))
5610     {
5611     case TYPE_INCDEC:
5612       if (operands[2] == constm1_rtx)
5613         return "inc{q}\t%0";
5614       else
5615         {
5616           gcc_assert (operands[2] == const1_rtx);
5617           return "dec{q}\t%0";
5618         }
5619
5620     default:
5621       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5622       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5623          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5624       if ((INTVAL (operands[2]) == -128
5625            || (INTVAL (operands[2]) > 0
5626                && INTVAL (operands[2]) != 128))
5627           /* Avoid overflows.  */
5628           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5629         return "sub{q}\t{%2, %0|%0, %2}";
5630       operands[2] = GEN_INT (-INTVAL (operands[2]));
5631       return "add{q}\t{%2, %0|%0, %2}";
5632     }
5633 }
5634   [(set (attr "type")
5635      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5636         (const_string "incdec")
5637         (const_string "alu")))
5638    (set_attr "mode" "DI")])
5639
5640 (define_insn "*adddi_5_rex64"
5641   [(set (reg FLAGS_REG)
5642         (compare
5643           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5644                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5645           (const_int 0)))
5646    (clobber (match_scratch:DI 0 "=r"))]
5647   "TARGET_64BIT
5648    && ix86_match_ccmode (insn, CCGOCmode)
5649    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5650    /* Current assemblers are broken and do not allow @GOTOFF in
5651       ought but a memory context.  */
5652    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5653 {
5654   switch (get_attr_type (insn))
5655     {
5656     case TYPE_INCDEC:
5657       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5658       if (operands[2] == const1_rtx)
5659         return "inc{q}\t%0";
5660       else
5661         {
5662           gcc_assert (operands[2] == constm1_rtx);
5663           return "dec{q}\t%0";
5664         }
5665
5666     default:
5667       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5668       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5669          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5670       if (CONST_INT_P (operands[2])
5671           /* Avoid overflows.  */
5672           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5673           && (INTVAL (operands[2]) == 128
5674               || (INTVAL (operands[2]) < 0
5675                   && INTVAL (operands[2]) != -128)))
5676         {
5677           operands[2] = GEN_INT (-INTVAL (operands[2]));
5678           return "sub{q}\t{%2, %0|%0, %2}";
5679         }
5680       return "add{q}\t{%2, %0|%0, %2}";
5681     }
5682 }
5683   [(set (attr "type")
5684      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5685         (const_string "incdec")
5686         (const_string "alu")))
5687    (set_attr "mode" "DI")])
5688
5689
5690 (define_insn "*addsi_1"
5691   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5692         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5693                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5694    (clobber (reg:CC FLAGS_REG))]
5695   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5696 {
5697   switch (get_attr_type (insn))
5698     {
5699     case TYPE_LEA:
5700       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5701       return "lea{l}\t{%a2, %0|%0, %a2}";
5702
5703     case TYPE_INCDEC:
5704       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5705       if (operands[2] == const1_rtx)
5706         return "inc{l}\t%0";
5707       else
5708         {
5709           gcc_assert (operands[2] == constm1_rtx);
5710           return "dec{l}\t%0";
5711         }
5712
5713     default:
5714       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5715
5716       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5717          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5718       if (CONST_INT_P (operands[2])
5719           && (INTVAL (operands[2]) == 128
5720               || (INTVAL (operands[2]) < 0
5721                   && INTVAL (operands[2]) != -128)))
5722         {
5723           operands[2] = GEN_INT (-INTVAL (operands[2]));
5724           return "sub{l}\t{%2, %0|%0, %2}";
5725         }
5726       return "add{l}\t{%2, %0|%0, %2}";
5727     }
5728 }
5729   [(set (attr "type")
5730      (cond [(eq_attr "alternative" "2")
5731               (const_string "lea")
5732             ; Current assemblers are broken and do not allow @GOTOFF in
5733             ; ought but a memory context.
5734             (match_operand:SI 2 "pic_symbolic_operand" "")
5735               (const_string "lea")
5736             (match_operand:SI 2 "incdec_operand" "")
5737               (const_string "incdec")
5738            ]
5739            (const_string "alu")))
5740    (set_attr "mode" "SI")])
5741
5742 ;; Convert lea to the lea pattern to avoid flags dependency.
5743 (define_split
5744   [(set (match_operand 0 "register_operand" "")
5745         (plus (match_operand 1 "register_operand" "")
5746               (match_operand 2 "nonmemory_operand" "")))
5747    (clobber (reg:CC FLAGS_REG))]
5748   "reload_completed
5749    && true_regnum (operands[0]) != true_regnum (operands[1])"
5750   [(const_int 0)]
5751 {
5752   rtx pat;
5753   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5754      may confuse gen_lowpart.  */
5755   if (GET_MODE (operands[0]) != Pmode)
5756     {
5757       operands[1] = gen_lowpart (Pmode, operands[1]);
5758       operands[2] = gen_lowpart (Pmode, operands[2]);
5759     }
5760   operands[0] = gen_lowpart (SImode, operands[0]);
5761   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5762   if (Pmode != SImode)
5763     pat = gen_rtx_SUBREG (SImode, pat, 0);
5764   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5765   DONE;
5766 })
5767
5768 ;; It may seem that nonimmediate operand is proper one for operand 1.
5769 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5770 ;; we take care in ix86_binary_operator_ok to not allow two memory
5771 ;; operands so proper swapping will be done in reload.  This allow
5772 ;; patterns constructed from addsi_1 to match.
5773 (define_insn "addsi_1_zext"
5774   [(set (match_operand:DI 0 "register_operand" "=r,r")
5775         (zero_extend:DI
5776           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5777                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5778    (clobber (reg:CC FLAGS_REG))]
5779   "TARGET_64BIT && 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, %k0|%k0, %a2}";
5786
5787     case TYPE_INCDEC:
5788       if (operands[2] == const1_rtx)
5789         return "inc{l}\t%k0";
5790       else
5791         {
5792           gcc_assert (operands[2] == constm1_rtx);
5793           return "dec{l}\t%k0";
5794         }
5795
5796     default:
5797       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5798          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5799       if (CONST_INT_P (operands[2])
5800           && (INTVAL (operands[2]) == 128
5801               || (INTVAL (operands[2]) < 0
5802                   && INTVAL (operands[2]) != -128)))
5803         {
5804           operands[2] = GEN_INT (-INTVAL (operands[2]));
5805           return "sub{l}\t{%2, %k0|%k0, %2}";
5806         }
5807       return "add{l}\t{%2, %k0|%k0, %2}";
5808     }
5809 }
5810   [(set (attr "type")
5811      (cond [(eq_attr "alternative" "1")
5812               (const_string "lea")
5813             ; Current assemblers are broken and do not allow @GOTOFF in
5814             ; ought but a memory context.
5815             (match_operand:SI 2 "pic_symbolic_operand" "")
5816               (const_string "lea")
5817             (match_operand:SI 2 "incdec_operand" "")
5818               (const_string "incdec")
5819            ]
5820            (const_string "alu")))
5821    (set_attr "mode" "SI")])
5822
5823 ;; Convert lea to the lea pattern to avoid flags dependency.
5824 (define_split
5825   [(set (match_operand:DI 0 "register_operand" "")
5826         (zero_extend:DI
5827           (plus:SI (match_operand:SI 1 "register_operand" "")
5828                    (match_operand:SI 2 "nonmemory_operand" ""))))
5829    (clobber (reg:CC FLAGS_REG))]
5830   "TARGET_64BIT && reload_completed
5831    && true_regnum (operands[0]) != true_regnum (operands[1])"
5832   [(set (match_dup 0)
5833         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5834 {
5835   operands[1] = gen_lowpart (Pmode, operands[1]);
5836   operands[2] = gen_lowpart (Pmode, operands[2]);
5837 })
5838
5839 (define_insn "*addsi_2"
5840   [(set (reg FLAGS_REG)
5841         (compare
5842           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5843                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5844           (const_int 0)))
5845    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5846         (plus:SI (match_dup 1) (match_dup 2)))]
5847   "ix86_match_ccmode (insn, CCGOCmode)
5848    && ix86_binary_operator_ok (PLUS, SImode, operands)
5849    /* Current assemblers are broken and do not allow @GOTOFF in
5850       ought but a memory context.  */
5851    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5852 {
5853   switch (get_attr_type (insn))
5854     {
5855     case TYPE_INCDEC:
5856       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5857       if (operands[2] == const1_rtx)
5858         return "inc{l}\t%0";
5859       else
5860         {
5861           gcc_assert (operands[2] == constm1_rtx);
5862           return "dec{l}\t%0";
5863         }
5864
5865     default:
5866       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5867       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5868          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5869       if (CONST_INT_P (operands[2])
5870           && (INTVAL (operands[2]) == 128
5871               || (INTVAL (operands[2]) < 0
5872                   && INTVAL (operands[2]) != -128)))
5873         {
5874           operands[2] = GEN_INT (-INTVAL (operands[2]));
5875           return "sub{l}\t{%2, %0|%0, %2}";
5876         }
5877       return "add{l}\t{%2, %0|%0, %2}";
5878     }
5879 }
5880   [(set (attr "type")
5881      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5882         (const_string "incdec")
5883         (const_string "alu")))
5884    (set_attr "mode" "SI")])
5885
5886 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5887 (define_insn "*addsi_2_zext"
5888   [(set (reg FLAGS_REG)
5889         (compare
5890           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5891                    (match_operand:SI 2 "general_operand" "rmni"))
5892           (const_int 0)))
5893    (set (match_operand:DI 0 "register_operand" "=r")
5894         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5895   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5896    && ix86_binary_operator_ok (PLUS, SImode, operands)
5897    /* Current assemblers are broken and do not allow @GOTOFF in
5898       ought but a memory context.  */
5899    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5900 {
5901   switch (get_attr_type (insn))
5902     {
5903     case TYPE_INCDEC:
5904       if (operands[2] == const1_rtx)
5905         return "inc{l}\t%k0";
5906       else
5907         {
5908           gcc_assert (operands[2] == constm1_rtx);
5909           return "dec{l}\t%k0";
5910         }
5911
5912     default:
5913       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5914          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5915       if (CONST_INT_P (operands[2])
5916           && (INTVAL (operands[2]) == 128
5917               || (INTVAL (operands[2]) < 0
5918                   && INTVAL (operands[2]) != -128)))
5919         {
5920           operands[2] = GEN_INT (-INTVAL (operands[2]));
5921           return "sub{l}\t{%2, %k0|%k0, %2}";
5922         }
5923       return "add{l}\t{%2, %k0|%k0, %2}";
5924     }
5925 }
5926   [(set (attr "type")
5927      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5928         (const_string "incdec")
5929         (const_string "alu")))
5930    (set_attr "mode" "SI")])
5931
5932 (define_insn "*addsi_3"
5933   [(set (reg FLAGS_REG)
5934         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5935                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5936    (clobber (match_scratch:SI 0 "=r"))]
5937   "ix86_match_ccmode (insn, CCZmode)
5938    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5939    /* Current assemblers are broken and do not allow @GOTOFF in
5940       ought but a memory context.  */
5941    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5942 {
5943   switch (get_attr_type (insn))
5944     {
5945     case TYPE_INCDEC:
5946       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5947       if (operands[2] == const1_rtx)
5948         return "inc{l}\t%0";
5949       else
5950         {
5951           gcc_assert (operands[2] == constm1_rtx);
5952           return "dec{l}\t%0";
5953         }
5954
5955     default:
5956       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5957       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5958          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5959       if (CONST_INT_P (operands[2])
5960           && (INTVAL (operands[2]) == 128
5961               || (INTVAL (operands[2]) < 0
5962                   && INTVAL (operands[2]) != -128)))
5963         {
5964           operands[2] = GEN_INT (-INTVAL (operands[2]));
5965           return "sub{l}\t{%2, %0|%0, %2}";
5966         }
5967       return "add{l}\t{%2, %0|%0, %2}";
5968     }
5969 }
5970   [(set (attr "type")
5971      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5972         (const_string "incdec")
5973         (const_string "alu")))
5974    (set_attr "mode" "SI")])
5975
5976 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5977 (define_insn "*addsi_3_zext"
5978   [(set (reg FLAGS_REG)
5979         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5980                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5981    (set (match_operand:DI 0 "register_operand" "=r")
5982         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5983   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5984    && ix86_binary_operator_ok (PLUS, SImode, operands)
5985    /* Current assemblers are broken and do not allow @GOTOFF in
5986       ought but a memory context.  */
5987    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5988 {
5989   switch (get_attr_type (insn))
5990     {
5991     case TYPE_INCDEC:
5992       if (operands[2] == const1_rtx)
5993         return "inc{l}\t%k0";
5994       else
5995         {
5996           gcc_assert (operands[2] == constm1_rtx);
5997           return "dec{l}\t%k0";
5998         }
5999
6000     default:
6001       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6002          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6003       if (CONST_INT_P (operands[2])
6004           && (INTVAL (operands[2]) == 128
6005               || (INTVAL (operands[2]) < 0
6006                   && INTVAL (operands[2]) != -128)))
6007         {
6008           operands[2] = GEN_INT (-INTVAL (operands[2]));
6009           return "sub{l}\t{%2, %k0|%k0, %2}";
6010         }
6011       return "add{l}\t{%2, %k0|%k0, %2}";
6012     }
6013 }
6014   [(set (attr "type")
6015      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6016         (const_string "incdec")
6017         (const_string "alu")))
6018    (set_attr "mode" "SI")])
6019
6020 ; For comparisons against 1, -1 and 128, we may generate better code
6021 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6022 ; is matched then.  We can't accept general immediate, because for
6023 ; case of overflows,  the result is messed up.
6024 ; This pattern also don't hold of 0x80000000, since the value overflows
6025 ; when negated.
6026 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6027 ; only for comparisons not depending on it.
6028 (define_insn "*addsi_4"
6029   [(set (reg FLAGS_REG)
6030         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6031                  (match_operand:SI 2 "const_int_operand" "n")))
6032    (clobber (match_scratch:SI 0 "=rm"))]
6033   "ix86_match_ccmode (insn, CCGCmode)
6034    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6035 {
6036   switch (get_attr_type (insn))
6037     {
6038     case TYPE_INCDEC:
6039       if (operands[2] == constm1_rtx)
6040         return "inc{l}\t%0";
6041       else
6042         {
6043           gcc_assert (operands[2] == const1_rtx);
6044           return "dec{l}\t%0";
6045         }
6046
6047     default:
6048       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6049       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6050          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6051       if ((INTVAL (operands[2]) == -128
6052            || (INTVAL (operands[2]) > 0
6053                && INTVAL (operands[2]) != 128)))
6054         return "sub{l}\t{%2, %0|%0, %2}";
6055       operands[2] = GEN_INT (-INTVAL (operands[2]));
6056       return "add{l}\t{%2, %0|%0, %2}";
6057     }
6058 }
6059   [(set (attr "type")
6060      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6061         (const_string "incdec")
6062         (const_string "alu")))
6063    (set_attr "mode" "SI")])
6064
6065 (define_insn "*addsi_5"
6066   [(set (reg FLAGS_REG)
6067         (compare
6068           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6069                    (match_operand:SI 2 "general_operand" "rmni"))
6070           (const_int 0)))
6071    (clobber (match_scratch:SI 0 "=r"))]
6072   "ix86_match_ccmode (insn, CCGOCmode)
6073    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6074    /* Current assemblers are broken and do not allow @GOTOFF in
6075       ought but a memory context.  */
6076    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6077 {
6078   switch (get_attr_type (insn))
6079     {
6080     case TYPE_INCDEC:
6081       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6082       if (operands[2] == const1_rtx)
6083         return "inc{l}\t%0";
6084       else
6085         {
6086           gcc_assert (operands[2] == constm1_rtx);
6087           return "dec{l}\t%0";
6088         }
6089
6090     default:
6091       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6092       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6093          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6094       if (CONST_INT_P (operands[2])
6095           && (INTVAL (operands[2]) == 128
6096               || (INTVAL (operands[2]) < 0
6097                   && INTVAL (operands[2]) != -128)))
6098         {
6099           operands[2] = GEN_INT (-INTVAL (operands[2]));
6100           return "sub{l}\t{%2, %0|%0, %2}";
6101         }
6102       return "add{l}\t{%2, %0|%0, %2}";
6103     }
6104 }
6105   [(set (attr "type")
6106      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6107         (const_string "incdec")
6108         (const_string "alu")))
6109    (set_attr "mode" "SI")])
6110
6111 (define_expand "addhi3"
6112   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6113                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6114                             (match_operand:HI 2 "general_operand" "")))
6115               (clobber (reg:CC FLAGS_REG))])]
6116   "TARGET_HIMODE_MATH"
6117   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6118
6119 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6120 ;; type optimizations enabled by define-splits.  This is not important
6121 ;; for PII, and in fact harmful because of partial register stalls.
6122
6123 (define_insn "*addhi_1_lea"
6124   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6125         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6126                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6127    (clobber (reg:CC FLAGS_REG))]
6128   "!TARGET_PARTIAL_REG_STALL
6129    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6130 {
6131   switch (get_attr_type (insn))
6132     {
6133     case TYPE_LEA:
6134       return "#";
6135     case TYPE_INCDEC:
6136       if (operands[2] == const1_rtx)
6137         return "inc{w}\t%0";
6138       else
6139         {
6140           gcc_assert (operands[2] == constm1_rtx);
6141           return "dec{w}\t%0";
6142         }
6143
6144     default:
6145       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6146          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6147       if (CONST_INT_P (operands[2])
6148           && (INTVAL (operands[2]) == 128
6149               || (INTVAL (operands[2]) < 0
6150                   && INTVAL (operands[2]) != -128)))
6151         {
6152           operands[2] = GEN_INT (-INTVAL (operands[2]));
6153           return "sub{w}\t{%2, %0|%0, %2}";
6154         }
6155       return "add{w}\t{%2, %0|%0, %2}";
6156     }
6157 }
6158   [(set (attr "type")
6159      (if_then_else (eq_attr "alternative" "2")
6160         (const_string "lea")
6161         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6162            (const_string "incdec")
6163            (const_string "alu"))))
6164    (set_attr "mode" "HI,HI,SI")])
6165
6166 (define_insn "*addhi_1"
6167   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6168         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6169                  (match_operand:HI 2 "general_operand" "ri,rm")))
6170    (clobber (reg:CC FLAGS_REG))]
6171   "TARGET_PARTIAL_REG_STALL
6172    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6173 {
6174   switch (get_attr_type (insn))
6175     {
6176     case TYPE_INCDEC:
6177       if (operands[2] == const1_rtx)
6178         return "inc{w}\t%0";
6179       else
6180         {
6181           gcc_assert (operands[2] == constm1_rtx);
6182           return "dec{w}\t%0";
6183         }
6184
6185     default:
6186       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6187          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6188       if (CONST_INT_P (operands[2])
6189           && (INTVAL (operands[2]) == 128
6190               || (INTVAL (operands[2]) < 0
6191                   && INTVAL (operands[2]) != -128)))
6192         {
6193           operands[2] = GEN_INT (-INTVAL (operands[2]));
6194           return "sub{w}\t{%2, %0|%0, %2}";
6195         }
6196       return "add{w}\t{%2, %0|%0, %2}";
6197     }
6198 }
6199   [(set (attr "type")
6200      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6201         (const_string "incdec")
6202         (const_string "alu")))
6203    (set_attr "mode" "HI")])
6204
6205 (define_insn "*addhi_2"
6206   [(set (reg FLAGS_REG)
6207         (compare
6208           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6209                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6210           (const_int 0)))
6211    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6212         (plus:HI (match_dup 1) (match_dup 2)))]
6213   "ix86_match_ccmode (insn, CCGOCmode)
6214    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6215 {
6216   switch (get_attr_type (insn))
6217     {
6218     case TYPE_INCDEC:
6219       if (operands[2] == const1_rtx)
6220         return "inc{w}\t%0";
6221       else
6222         {
6223           gcc_assert (operands[2] == constm1_rtx);
6224           return "dec{w}\t%0";
6225         }
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 (CONST_INT_P (operands[2])
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 (match_operand:HI 2 "incdec_operand" "")
6243         (const_string "incdec")
6244         (const_string "alu")))
6245    (set_attr "mode" "HI")])
6246
6247 (define_insn "*addhi_3"
6248   [(set (reg FLAGS_REG)
6249         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6250                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6251    (clobber (match_scratch:HI 0 "=r"))]
6252   "ix86_match_ccmode (insn, CCZmode)
6253    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6254 {
6255   switch (get_attr_type (insn))
6256     {
6257     case TYPE_INCDEC:
6258       if (operands[2] == const1_rtx)
6259         return "inc{w}\t%0";
6260       else
6261         {
6262           gcc_assert (operands[2] == constm1_rtx);
6263           return "dec{w}\t%0";
6264         }
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 (CONST_INT_P (operands[2])
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 ; See comments above addsi_4 for details.
6287 (define_insn "*addhi_4"
6288   [(set (reg FLAGS_REG)
6289         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6290                  (match_operand:HI 2 "const_int_operand" "n")))
6291    (clobber (match_scratch:HI 0 "=rm"))]
6292   "ix86_match_ccmode (insn, CCGCmode)
6293    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6294 {
6295   switch (get_attr_type (insn))
6296     {
6297     case TYPE_INCDEC:
6298       if (operands[2] == constm1_rtx)
6299         return "inc{w}\t%0";
6300       else
6301         {
6302           gcc_assert (operands[2] == const1_rtx);
6303           return "dec{w}\t%0";
6304         }
6305
6306     default:
6307       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6308       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6309          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6310       if ((INTVAL (operands[2]) == -128
6311            || (INTVAL (operands[2]) > 0
6312                && INTVAL (operands[2]) != 128)))
6313         return "sub{w}\t{%2, %0|%0, %2}";
6314       operands[2] = GEN_INT (-INTVAL (operands[2]));
6315       return "add{w}\t{%2, %0|%0, %2}";
6316     }
6317 }
6318   [(set (attr "type")
6319      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6320         (const_string "incdec")
6321         (const_string "alu")))
6322    (set_attr "mode" "SI")])
6323
6324
6325 (define_insn "*addhi_5"
6326   [(set (reg FLAGS_REG)
6327         (compare
6328           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6329                    (match_operand:HI 2 "general_operand" "rmni"))
6330           (const_int 0)))
6331    (clobber (match_scratch:HI 0 "=r"))]
6332   "ix86_match_ccmode (insn, CCGOCmode)
6333    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6334 {
6335   switch (get_attr_type (insn))
6336     {
6337     case TYPE_INCDEC:
6338       if (operands[2] == const1_rtx)
6339         return "inc{w}\t%0";
6340       else
6341         {
6342           gcc_assert (operands[2] == constm1_rtx);
6343           return "dec{w}\t%0";
6344         }
6345
6346     default:
6347       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6348          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6349       if (CONST_INT_P (operands[2])
6350           && (INTVAL (operands[2]) == 128
6351               || (INTVAL (operands[2]) < 0
6352                   && INTVAL (operands[2]) != -128)))
6353         {
6354           operands[2] = GEN_INT (-INTVAL (operands[2]));
6355           return "sub{w}\t{%2, %0|%0, %2}";
6356         }
6357       return "add{w}\t{%2, %0|%0, %2}";
6358     }
6359 }
6360   [(set (attr "type")
6361      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6362         (const_string "incdec")
6363         (const_string "alu")))
6364    (set_attr "mode" "HI")])
6365
6366 (define_expand "addqi3"
6367   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6368                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6369                             (match_operand:QI 2 "general_operand" "")))
6370               (clobber (reg:CC FLAGS_REG))])]
6371   "TARGET_QIMODE_MATH"
6372   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6373
6374 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6375 (define_insn "*addqi_1_lea"
6376   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6377         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6378                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6379    (clobber (reg:CC FLAGS_REG))]
6380   "!TARGET_PARTIAL_REG_STALL
6381    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6382 {
6383   int widen = (which_alternative == 2);
6384   switch (get_attr_type (insn))
6385     {
6386     case TYPE_LEA:
6387       return "#";
6388     case TYPE_INCDEC:
6389       if (operands[2] == const1_rtx)
6390         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6391       else
6392         {
6393           gcc_assert (operands[2] == constm1_rtx);
6394           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6395         }
6396
6397     default:
6398       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6399          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6400       if (CONST_INT_P (operands[2])
6401           && (INTVAL (operands[2]) == 128
6402               || (INTVAL (operands[2]) < 0
6403                   && INTVAL (operands[2]) != -128)))
6404         {
6405           operands[2] = GEN_INT (-INTVAL (operands[2]));
6406           if (widen)
6407             return "sub{l}\t{%2, %k0|%k0, %2}";
6408           else
6409             return "sub{b}\t{%2, %0|%0, %2}";
6410         }
6411       if (widen)
6412         return "add{l}\t{%k2, %k0|%k0, %k2}";
6413       else
6414         return "add{b}\t{%2, %0|%0, %2}";
6415     }
6416 }
6417   [(set (attr "type")
6418      (if_then_else (eq_attr "alternative" "3")
6419         (const_string "lea")
6420         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6421            (const_string "incdec")
6422            (const_string "alu"))))
6423    (set_attr "mode" "QI,QI,SI,SI")])
6424
6425 (define_insn "*addqi_1"
6426   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6427         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6428                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6429    (clobber (reg:CC FLAGS_REG))]
6430   "TARGET_PARTIAL_REG_STALL
6431    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6432 {
6433   int widen = (which_alternative == 2);
6434   switch (get_attr_type (insn))
6435     {
6436     case TYPE_INCDEC:
6437       if (operands[2] == const1_rtx)
6438         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6439       else
6440         {
6441           gcc_assert (operands[2] == constm1_rtx);
6442           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6443         }
6444
6445     default:
6446       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6447          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6448       if (CONST_INT_P (operands[2])
6449           && (INTVAL (operands[2]) == 128
6450               || (INTVAL (operands[2]) < 0
6451                   && INTVAL (operands[2]) != -128)))
6452         {
6453           operands[2] = GEN_INT (-INTVAL (operands[2]));
6454           if (widen)
6455             return "sub{l}\t{%2, %k0|%k0, %2}";
6456           else
6457             return "sub{b}\t{%2, %0|%0, %2}";
6458         }
6459       if (widen)
6460         return "add{l}\t{%k2, %k0|%k0, %k2}";
6461       else
6462         return "add{b}\t{%2, %0|%0, %2}";
6463     }
6464 }
6465   [(set (attr "type")
6466      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6467         (const_string "incdec")
6468         (const_string "alu")))
6469    (set_attr "mode" "QI,QI,SI")])
6470
6471 (define_insn "*addqi_1_slp"
6472   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6473         (plus:QI (match_dup 0)
6474                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6475    (clobber (reg:CC FLAGS_REG))]
6476   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6477    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6478 {
6479   switch (get_attr_type (insn))
6480     {
6481     case TYPE_INCDEC:
6482       if (operands[1] == const1_rtx)
6483         return "inc{b}\t%0";
6484       else
6485         {
6486           gcc_assert (operands[1] == constm1_rtx);
6487           return "dec{b}\t%0";
6488         }
6489
6490     default:
6491       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6492       if (CONST_INT_P (operands[1])
6493           && INTVAL (operands[1]) < 0)
6494         {
6495           operands[1] = GEN_INT (-INTVAL (operands[1]));
6496           return "sub{b}\t{%1, %0|%0, %1}";
6497         }
6498       return "add{b}\t{%1, %0|%0, %1}";
6499     }
6500 }
6501   [(set (attr "type")
6502      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6503         (const_string "incdec")
6504         (const_string "alu1")))
6505    (set (attr "memory")
6506      (if_then_else (match_operand 1 "memory_operand" "")
6507         (const_string "load")
6508         (const_string "none")))
6509    (set_attr "mode" "QI")])
6510
6511 (define_insn "*addqi_2"
6512   [(set (reg FLAGS_REG)
6513         (compare
6514           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6515                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6516           (const_int 0)))
6517    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6518         (plus:QI (match_dup 1) (match_dup 2)))]
6519   "ix86_match_ccmode (insn, CCGOCmode)
6520    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6521 {
6522   switch (get_attr_type (insn))
6523     {
6524     case TYPE_INCDEC:
6525       if (operands[2] == const1_rtx)
6526         return "inc{b}\t%0";
6527       else
6528         {
6529           gcc_assert (operands[2] == constm1_rtx
6530                       || (CONST_INT_P (operands[2])
6531                           && INTVAL (operands[2]) == 255));
6532           return "dec{b}\t%0";
6533         }
6534
6535     default:
6536       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6537       if (CONST_INT_P (operands[2])
6538           && INTVAL (operands[2]) < 0)
6539         {
6540           operands[2] = GEN_INT (-INTVAL (operands[2]));
6541           return "sub{b}\t{%2, %0|%0, %2}";
6542         }
6543       return "add{b}\t{%2, %0|%0, %2}";
6544     }
6545 }
6546   [(set (attr "type")
6547      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6548         (const_string "incdec")
6549         (const_string "alu")))
6550    (set_attr "mode" "QI")])
6551
6552 (define_insn "*addqi_3"
6553   [(set (reg FLAGS_REG)
6554         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6555                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6556    (clobber (match_scratch:QI 0 "=q"))]
6557   "ix86_match_ccmode (insn, CCZmode)
6558    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6559 {
6560   switch (get_attr_type (insn))
6561     {
6562     case TYPE_INCDEC:
6563       if (operands[2] == const1_rtx)
6564         return "inc{b}\t%0";
6565       else
6566         {
6567           gcc_assert (operands[2] == constm1_rtx
6568                       || (CONST_INT_P (operands[2])
6569                           && INTVAL (operands[2]) == 255));
6570           return "dec{b}\t%0";
6571         }
6572
6573     default:
6574       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6575       if (CONST_INT_P (operands[2])
6576           && INTVAL (operands[2]) < 0)
6577         {
6578           operands[2] = GEN_INT (-INTVAL (operands[2]));
6579           return "sub{b}\t{%2, %0|%0, %2}";
6580         }
6581       return "add{b}\t{%2, %0|%0, %2}";
6582     }
6583 }
6584   [(set (attr "type")
6585      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6586         (const_string "incdec")
6587         (const_string "alu")))
6588    (set_attr "mode" "QI")])
6589
6590 ; See comments above addsi_4 for details.
6591 (define_insn "*addqi_4"
6592   [(set (reg FLAGS_REG)
6593         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6594                  (match_operand:QI 2 "const_int_operand" "n")))
6595    (clobber (match_scratch:QI 0 "=qm"))]
6596   "ix86_match_ccmode (insn, CCGCmode)
6597    && (INTVAL (operands[2]) & 0xff) != 0x80"
6598 {
6599   switch (get_attr_type (insn))
6600     {
6601     case TYPE_INCDEC:
6602       if (operands[2] == constm1_rtx
6603           || (CONST_INT_P (operands[2])
6604               && INTVAL (operands[2]) == 255))
6605         return "inc{b}\t%0";
6606       else
6607         {
6608           gcc_assert (operands[2] == const1_rtx);
6609           return "dec{b}\t%0";
6610         }
6611
6612     default:
6613       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6614       if (INTVAL (operands[2]) < 0)
6615         {
6616           operands[2] = GEN_INT (-INTVAL (operands[2]));
6617           return "add{b}\t{%2, %0|%0, %2}";
6618         }
6619       return "sub{b}\t{%2, %0|%0, %2}";
6620     }
6621 }
6622   [(set (attr "type")
6623      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6624         (const_string "incdec")
6625         (const_string "alu")))
6626    (set_attr "mode" "QI")])
6627
6628
6629 (define_insn "*addqi_5"
6630   [(set (reg FLAGS_REG)
6631         (compare
6632           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6633                    (match_operand:QI 2 "general_operand" "qmni"))
6634           (const_int 0)))
6635    (clobber (match_scratch:QI 0 "=q"))]
6636   "ix86_match_ccmode (insn, CCGOCmode)
6637    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6638 {
6639   switch (get_attr_type (insn))
6640     {
6641     case TYPE_INCDEC:
6642       if (operands[2] == const1_rtx)
6643         return "inc{b}\t%0";
6644       else
6645         {
6646           gcc_assert (operands[2] == constm1_rtx
6647                       || (CONST_INT_P (operands[2])
6648                           && INTVAL (operands[2]) == 255));
6649           return "dec{b}\t%0";
6650         }
6651
6652     default:
6653       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6654       if (CONST_INT_P (operands[2])
6655           && INTVAL (operands[2]) < 0)
6656         {
6657           operands[2] = GEN_INT (-INTVAL (operands[2]));
6658           return "sub{b}\t{%2, %0|%0, %2}";
6659         }
6660       return "add{b}\t{%2, %0|%0, %2}";
6661     }
6662 }
6663   [(set (attr "type")
6664      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6665         (const_string "incdec")
6666         (const_string "alu")))
6667    (set_attr "mode" "QI")])
6668
6669
6670 (define_insn "addqi_ext_1"
6671   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6672                          (const_int 8)
6673                          (const_int 8))
6674         (plus:SI
6675           (zero_extract:SI
6676             (match_operand 1 "ext_register_operand" "0")
6677             (const_int 8)
6678             (const_int 8))
6679           (match_operand:QI 2 "general_operand" "Qmn")))
6680    (clobber (reg:CC FLAGS_REG))]
6681   "!TARGET_64BIT"
6682 {
6683   switch (get_attr_type (insn))
6684     {
6685     case TYPE_INCDEC:
6686       if (operands[2] == const1_rtx)
6687         return "inc{b}\t%h0";
6688       else
6689         {
6690           gcc_assert (operands[2] == constm1_rtx
6691                       || (CONST_INT_P (operands[2])
6692                           && INTVAL (operands[2]) == 255));
6693           return "dec{b}\t%h0";
6694         }
6695
6696     default:
6697       return "add{b}\t{%2, %h0|%h0, %2}";
6698     }
6699 }
6700   [(set (attr "type")
6701      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6702         (const_string "incdec")
6703         (const_string "alu")))
6704    (set_attr "mode" "QI")])
6705
6706 (define_insn "*addqi_ext_1_rex64"
6707   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6708                          (const_int 8)
6709                          (const_int 8))
6710         (plus:SI
6711           (zero_extract:SI
6712             (match_operand 1 "ext_register_operand" "0")
6713             (const_int 8)
6714             (const_int 8))
6715           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6716    (clobber (reg:CC FLAGS_REG))]
6717   "TARGET_64BIT"
6718 {
6719   switch (get_attr_type (insn))
6720     {
6721     case TYPE_INCDEC:
6722       if (operands[2] == const1_rtx)
6723         return "inc{b}\t%h0";
6724       else
6725         {
6726           gcc_assert (operands[2] == constm1_rtx
6727                       || (CONST_INT_P (operands[2])
6728                           && INTVAL (operands[2]) == 255));
6729           return "dec{b}\t%h0";
6730         }
6731
6732     default:
6733       return "add{b}\t{%2, %h0|%h0, %2}";
6734     }
6735 }
6736   [(set (attr "type")
6737      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6738         (const_string "incdec")
6739         (const_string "alu")))
6740    (set_attr "mode" "QI")])
6741
6742 (define_insn "*addqi_ext_2"
6743   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6744                          (const_int 8)
6745                          (const_int 8))
6746         (plus:SI
6747           (zero_extract:SI
6748             (match_operand 1 "ext_register_operand" "%0")
6749             (const_int 8)
6750             (const_int 8))
6751           (zero_extract:SI
6752             (match_operand 2 "ext_register_operand" "Q")
6753             (const_int 8)
6754             (const_int 8))))
6755    (clobber (reg:CC FLAGS_REG))]
6756   ""
6757   "add{b}\t{%h2, %h0|%h0, %h2}"
6758   [(set_attr "type" "alu")
6759    (set_attr "mode" "QI")])
6760
6761 ;; The patterns that match these are at the end of this file.
6762
6763 (define_expand "addxf3"
6764   [(set (match_operand:XF 0 "register_operand" "")
6765         (plus:XF (match_operand:XF 1 "register_operand" "")
6766                  (match_operand:XF 2 "register_operand" "")))]
6767   "TARGET_80387"
6768   "")
6769
6770 (define_expand "adddf3"
6771   [(set (match_operand:DF 0 "register_operand" "")
6772         (plus:DF (match_operand:DF 1 "register_operand" "")
6773                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6774   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6775   "")
6776
6777 (define_expand "addsf3"
6778   [(set (match_operand:SF 0 "register_operand" "")
6779         (plus:SF (match_operand:SF 1 "register_operand" "")
6780                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6781   "TARGET_80387 || TARGET_SSE_MATH"
6782   "")
6783 \f
6784 ;; Subtract instructions
6785
6786 ;; %%% splits for subditi3
6787
6788 (define_expand "subti3"
6789   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6790                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6791                              (match_operand:TI 2 "x86_64_general_operand" "")))
6792               (clobber (reg:CC FLAGS_REG))])]
6793   "TARGET_64BIT"
6794   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6795
6796 (define_insn "*subti3_1"
6797   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6798         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6799                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6800    (clobber (reg:CC FLAGS_REG))]
6801   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6802   "#")
6803
6804 (define_split
6805   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6806         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6807                   (match_operand:TI 2 "general_operand" "")))
6808    (clobber (reg:CC FLAGS_REG))]
6809   "TARGET_64BIT && reload_completed"
6810   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6811               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6812    (parallel [(set (match_dup 3)
6813                    (minus:DI (match_dup 4)
6814                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6815                                       (match_dup 5))))
6816               (clobber (reg:CC FLAGS_REG))])]
6817   "split_ti (operands+0, 1, operands+0, operands+3);
6818    split_ti (operands+1, 1, operands+1, operands+4);
6819    split_ti (operands+2, 1, operands+2, operands+5);")
6820
6821 ;; %%% splits for subsidi3
6822
6823 (define_expand "subdi3"
6824   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6825                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6826                              (match_operand:DI 2 "x86_64_general_operand" "")))
6827               (clobber (reg:CC FLAGS_REG))])]
6828   ""
6829   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6830
6831 (define_insn "*subdi3_1"
6832   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6833         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6834                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6835    (clobber (reg:CC FLAGS_REG))]
6836   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6837   "#")
6838
6839 (define_split
6840   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6841         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6842                   (match_operand:DI 2 "general_operand" "")))
6843    (clobber (reg:CC FLAGS_REG))]
6844   "!TARGET_64BIT && reload_completed"
6845   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6846               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6847    (parallel [(set (match_dup 3)
6848                    (minus:SI (match_dup 4)
6849                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6850                                       (match_dup 5))))
6851               (clobber (reg:CC FLAGS_REG))])]
6852   "split_di (operands+0, 1, operands+0, operands+3);
6853    split_di (operands+1, 1, operands+1, operands+4);
6854    split_di (operands+2, 1, operands+2, operands+5);")
6855
6856 (define_insn "subdi3_carry_rex64"
6857   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6858           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6859             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6860                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6861    (clobber (reg:CC FLAGS_REG))]
6862   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6863   "sbb{q}\t{%2, %0|%0, %2}"
6864   [(set_attr "type" "alu")
6865    (set_attr "pent_pair" "pu")
6866    (set_attr "mode" "DI")])
6867
6868 (define_insn "*subdi_1_rex64"
6869   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6870         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6871                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6872    (clobber (reg:CC FLAGS_REG))]
6873   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6874   "sub{q}\t{%2, %0|%0, %2}"
6875   [(set_attr "type" "alu")
6876    (set_attr "mode" "DI")])
6877
6878 (define_insn "*subdi_2_rex64"
6879   [(set (reg FLAGS_REG)
6880         (compare
6881           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6882                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6883           (const_int 0)))
6884    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6885         (minus:DI (match_dup 1) (match_dup 2)))]
6886   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6887    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6888   "sub{q}\t{%2, %0|%0, %2}"
6889   [(set_attr "type" "alu")
6890    (set_attr "mode" "DI")])
6891
6892 (define_insn "*subdi_3_rex63"
6893   [(set (reg FLAGS_REG)
6894         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6895                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6896    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6897         (minus:DI (match_dup 1) (match_dup 2)))]
6898   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6899    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6900   "sub{q}\t{%2, %0|%0, %2}"
6901   [(set_attr "type" "alu")
6902    (set_attr "mode" "DI")])
6903
6904 (define_insn "subqi3_carry"
6905   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6906           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6907             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6908                (match_operand:QI 2 "general_operand" "qi,qm"))))
6909    (clobber (reg:CC FLAGS_REG))]
6910   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6911   "sbb{b}\t{%2, %0|%0, %2}"
6912   [(set_attr "type" "alu")
6913    (set_attr "pent_pair" "pu")
6914    (set_attr "mode" "QI")])
6915
6916 (define_insn "subhi3_carry"
6917   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6918           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6919             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6920                (match_operand:HI 2 "general_operand" "ri,rm"))))
6921    (clobber (reg:CC FLAGS_REG))]
6922   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6923   "sbb{w}\t{%2, %0|%0, %2}"
6924   [(set_attr "type" "alu")
6925    (set_attr "pent_pair" "pu")
6926    (set_attr "mode" "HI")])
6927
6928 (define_insn "subsi3_carry"
6929   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6930           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6931             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6932                (match_operand:SI 2 "general_operand" "ri,rm"))))
6933    (clobber (reg:CC FLAGS_REG))]
6934   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6935   "sbb{l}\t{%2, %0|%0, %2}"
6936   [(set_attr "type" "alu")
6937    (set_attr "pent_pair" "pu")
6938    (set_attr "mode" "SI")])
6939
6940 (define_insn "subsi3_carry_zext"
6941   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6942           (zero_extend:DI
6943             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6944               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6945                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6946    (clobber (reg:CC FLAGS_REG))]
6947   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6948   "sbb{l}\t{%2, %k0|%k0, %2}"
6949   [(set_attr "type" "alu")
6950    (set_attr "pent_pair" "pu")
6951    (set_attr "mode" "SI")])
6952
6953 (define_expand "subsi3"
6954   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6955                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6956                              (match_operand:SI 2 "general_operand" "")))
6957               (clobber (reg:CC FLAGS_REG))])]
6958   ""
6959   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6960
6961 (define_insn "*subsi_1"
6962   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6963         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6964                   (match_operand:SI 2 "general_operand" "ri,rm")))
6965    (clobber (reg:CC FLAGS_REG))]
6966   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6967   "sub{l}\t{%2, %0|%0, %2}"
6968   [(set_attr "type" "alu")
6969    (set_attr "mode" "SI")])
6970
6971 (define_insn "*subsi_1_zext"
6972   [(set (match_operand:DI 0 "register_operand" "=r")
6973         (zero_extend:DI
6974           (minus:SI (match_operand:SI 1 "register_operand" "0")
6975                     (match_operand:SI 2 "general_operand" "rim"))))
6976    (clobber (reg:CC FLAGS_REG))]
6977   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6978   "sub{l}\t{%2, %k0|%k0, %2}"
6979   [(set_attr "type" "alu")
6980    (set_attr "mode" "SI")])
6981
6982 (define_insn "*subsi_2"
6983   [(set (reg FLAGS_REG)
6984         (compare
6985           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6986                     (match_operand:SI 2 "general_operand" "ri,rm"))
6987           (const_int 0)))
6988    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6989         (minus:SI (match_dup 1) (match_dup 2)))]
6990   "ix86_match_ccmode (insn, CCGOCmode)
6991    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6992   "sub{l}\t{%2, %0|%0, %2}"
6993   [(set_attr "type" "alu")
6994    (set_attr "mode" "SI")])
6995
6996 (define_insn "*subsi_2_zext"
6997   [(set (reg FLAGS_REG)
6998         (compare
6999           (minus:SI (match_operand:SI 1 "register_operand" "0")
7000                     (match_operand:SI 2 "general_operand" "rim"))
7001           (const_int 0)))
7002    (set (match_operand:DI 0 "register_operand" "=r")
7003         (zero_extend:DI
7004           (minus:SI (match_dup 1)
7005                     (match_dup 2))))]
7006   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7007    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7008   "sub{l}\t{%2, %k0|%k0, %2}"
7009   [(set_attr "type" "alu")
7010    (set_attr "mode" "SI")])
7011
7012 (define_insn "*subsi_3"
7013   [(set (reg FLAGS_REG)
7014         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7015                  (match_operand:SI 2 "general_operand" "ri,rm")))
7016    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7017         (minus:SI (match_dup 1) (match_dup 2)))]
7018   "ix86_match_ccmode (insn, CCmode)
7019    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7020   "sub{l}\t{%2, %0|%0, %2}"
7021   [(set_attr "type" "alu")
7022    (set_attr "mode" "SI")])
7023
7024 (define_insn "*subsi_3_zext"
7025   [(set (reg FLAGS_REG)
7026         (compare (match_operand:SI 1 "register_operand" "0")
7027                  (match_operand:SI 2 "general_operand" "rim")))
7028    (set (match_operand:DI 0 "register_operand" "=r")
7029         (zero_extend:DI
7030           (minus:SI (match_dup 1)
7031                     (match_dup 2))))]
7032   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7033    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7034   "sub{l}\t{%2, %1|%1, %2}"
7035   [(set_attr "type" "alu")
7036    (set_attr "mode" "DI")])
7037
7038 (define_expand "subhi3"
7039   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7040                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7041                              (match_operand:HI 2 "general_operand" "")))
7042               (clobber (reg:CC FLAGS_REG))])]
7043   "TARGET_HIMODE_MATH"
7044   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7045
7046 (define_insn "*subhi_1"
7047   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7048         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7049                   (match_operand:HI 2 "general_operand" "ri,rm")))
7050    (clobber (reg:CC FLAGS_REG))]
7051   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7052   "sub{w}\t{%2, %0|%0, %2}"
7053   [(set_attr "type" "alu")
7054    (set_attr "mode" "HI")])
7055
7056 (define_insn "*subhi_2"
7057   [(set (reg FLAGS_REG)
7058         (compare
7059           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7060                     (match_operand:HI 2 "general_operand" "ri,rm"))
7061           (const_int 0)))
7062    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7063         (minus:HI (match_dup 1) (match_dup 2)))]
7064   "ix86_match_ccmode (insn, CCGOCmode)
7065    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7066   "sub{w}\t{%2, %0|%0, %2}"
7067   [(set_attr "type" "alu")
7068    (set_attr "mode" "HI")])
7069
7070 (define_insn "*subhi_3"
7071   [(set (reg FLAGS_REG)
7072         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7073                  (match_operand:HI 2 "general_operand" "ri,rm")))
7074    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7075         (minus:HI (match_dup 1) (match_dup 2)))]
7076   "ix86_match_ccmode (insn, CCmode)
7077    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7078   "sub{w}\t{%2, %0|%0, %2}"
7079   [(set_attr "type" "alu")
7080    (set_attr "mode" "HI")])
7081
7082 (define_expand "subqi3"
7083   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7084                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7085                              (match_operand:QI 2 "general_operand" "")))
7086               (clobber (reg:CC FLAGS_REG))])]
7087   "TARGET_QIMODE_MATH"
7088   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7089
7090 (define_insn "*subqi_1"
7091   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7092         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7093                   (match_operand:QI 2 "general_operand" "qn,qmn")))
7094    (clobber (reg:CC FLAGS_REG))]
7095   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7096   "sub{b}\t{%2, %0|%0, %2}"
7097   [(set_attr "type" "alu")
7098    (set_attr "mode" "QI")])
7099
7100 (define_insn "*subqi_1_slp"
7101   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7102         (minus:QI (match_dup 0)
7103                   (match_operand:QI 1 "general_operand" "qn,qmn")))
7104    (clobber (reg:CC FLAGS_REG))]
7105   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7106    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7107   "sub{b}\t{%1, %0|%0, %1}"
7108   [(set_attr "type" "alu1")
7109    (set_attr "mode" "QI")])
7110
7111 (define_insn "*subqi_2"
7112   [(set (reg FLAGS_REG)
7113         (compare
7114           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7115                     (match_operand:QI 2 "general_operand" "qi,qm"))
7116           (const_int 0)))
7117    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7118         (minus:HI (match_dup 1) (match_dup 2)))]
7119   "ix86_match_ccmode (insn, CCGOCmode)
7120    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7121   "sub{b}\t{%2, %0|%0, %2}"
7122   [(set_attr "type" "alu")
7123    (set_attr "mode" "QI")])
7124
7125 (define_insn "*subqi_3"
7126   [(set (reg FLAGS_REG)
7127         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7128                  (match_operand:QI 2 "general_operand" "qi,qm")))
7129    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7130         (minus:HI (match_dup 1) (match_dup 2)))]
7131   "ix86_match_ccmode (insn, CCmode)
7132    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7133   "sub{b}\t{%2, %0|%0, %2}"
7134   [(set_attr "type" "alu")
7135    (set_attr "mode" "QI")])
7136
7137 ;; The patterns that match these are at the end of this file.
7138
7139 (define_expand "subxf3"
7140   [(set (match_operand:XF 0 "register_operand" "")
7141         (minus:XF (match_operand:XF 1 "register_operand" "")
7142                   (match_operand:XF 2 "register_operand" "")))]
7143   "TARGET_80387"
7144   "")
7145
7146 (define_expand "subdf3"
7147   [(set (match_operand:DF 0 "register_operand" "")
7148         (minus:DF (match_operand:DF 1 "register_operand" "")
7149                   (match_operand:DF 2 "nonimmediate_operand" "")))]
7150   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7151   "")
7152
7153 (define_expand "subsf3"
7154   [(set (match_operand:SF 0 "register_operand" "")
7155         (minus:SF (match_operand:SF 1 "register_operand" "")
7156                   (match_operand:SF 2 "nonimmediate_operand" "")))]
7157   "TARGET_80387 || TARGET_SSE_MATH"
7158   "")
7159 \f
7160 ;; Multiply instructions
7161
7162 (define_expand "muldi3"
7163   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7164                    (mult:DI (match_operand:DI 1 "register_operand" "")
7165                             (match_operand:DI 2 "x86_64_general_operand" "")))
7166               (clobber (reg:CC FLAGS_REG))])]
7167   "TARGET_64BIT"
7168   "")
7169
7170 ;; On AMDFAM10 
7171 ;; IMUL reg64, reg64, imm8      Direct
7172 ;; IMUL reg64, mem64, imm8      VectorPath
7173 ;; IMUL reg64, reg64, imm32     Direct
7174 ;; IMUL reg64, mem64, imm32     VectorPath 
7175 ;; IMUL reg64, reg64            Direct
7176 ;; IMUL reg64, mem64            Direct
7177
7178 (define_insn "*muldi3_1_rex64"
7179   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7180         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7181                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7182    (clobber (reg:CC FLAGS_REG))]
7183   "TARGET_64BIT
7184    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7185   "@
7186    imul{q}\t{%2, %1, %0|%0, %1, %2}
7187    imul{q}\t{%2, %1, %0|%0, %1, %2}
7188    imul{q}\t{%2, %0|%0, %2}"
7189   [(set_attr "type" "imul")
7190    (set_attr "prefix_0f" "0,0,1")
7191    (set (attr "athlon_decode")
7192         (cond [(eq_attr "cpu" "athlon")
7193                   (const_string "vector")
7194                (eq_attr "alternative" "1")
7195                   (const_string "vector")
7196                (and (eq_attr "alternative" "2")
7197                     (match_operand 1 "memory_operand" ""))
7198                   (const_string "vector")]
7199               (const_string "direct")))
7200    (set (attr "amdfam10_decode")
7201         (cond [(and (eq_attr "alternative" "0,1")
7202                     (match_operand 1 "memory_operand" ""))
7203                   (const_string "vector")]
7204               (const_string "direct")))       
7205    (set_attr "mode" "DI")])
7206
7207 (define_expand "mulsi3"
7208   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7209                    (mult:SI (match_operand:SI 1 "register_operand" "")
7210                             (match_operand:SI 2 "general_operand" "")))
7211               (clobber (reg:CC FLAGS_REG))])]
7212   ""
7213   "")
7214
7215 ;; On AMDFAM10 
7216 ;; IMUL reg32, reg32, imm8      Direct
7217 ;; IMUL reg32, mem32, imm8      VectorPath
7218 ;; IMUL reg32, reg32, imm32     Direct
7219 ;; IMUL reg32, mem32, imm32     VectorPath
7220 ;; IMUL reg32, reg32            Direct
7221 ;; IMUL reg32, mem32            Direct
7222
7223 (define_insn "*mulsi3_1"
7224   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7225         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7226                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7227    (clobber (reg:CC FLAGS_REG))]
7228   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7229   "@
7230    imul{l}\t{%2, %1, %0|%0, %1, %2}
7231    imul{l}\t{%2, %1, %0|%0, %1, %2}
7232    imul{l}\t{%2, %0|%0, %2}"
7233   [(set_attr "type" "imul")
7234    (set_attr "prefix_0f" "0,0,1")
7235    (set (attr "athlon_decode")
7236         (cond [(eq_attr "cpu" "athlon")
7237                   (const_string "vector")
7238                (eq_attr "alternative" "1")
7239                   (const_string "vector")
7240                (and (eq_attr "alternative" "2")
7241                     (match_operand 1 "memory_operand" ""))
7242                   (const_string "vector")]
7243               (const_string "direct")))
7244    (set (attr "amdfam10_decode")
7245         (cond [(and (eq_attr "alternative" "0,1")
7246                     (match_operand 1 "memory_operand" ""))
7247                   (const_string "vector")]
7248               (const_string "direct")))       
7249    (set_attr "mode" "SI")])
7250
7251 (define_insn "*mulsi3_1_zext"
7252   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7253         (zero_extend:DI
7254           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7255                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7256    (clobber (reg:CC FLAGS_REG))]
7257   "TARGET_64BIT
7258    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7259   "@
7260    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7261    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7262    imul{l}\t{%2, %k0|%k0, %2}"
7263   [(set_attr "type" "imul")
7264    (set_attr "prefix_0f" "0,0,1")
7265    (set (attr "athlon_decode")
7266         (cond [(eq_attr "cpu" "athlon")
7267                   (const_string "vector")
7268                (eq_attr "alternative" "1")
7269                   (const_string "vector")
7270                (and (eq_attr "alternative" "2")
7271                     (match_operand 1 "memory_operand" ""))
7272                   (const_string "vector")]
7273               (const_string "direct")))
7274    (set (attr "amdfam10_decode")
7275         (cond [(and (eq_attr "alternative" "0,1")
7276                     (match_operand 1 "memory_operand" ""))
7277                   (const_string "vector")]
7278               (const_string "direct")))       
7279    (set_attr "mode" "SI")])
7280
7281 (define_expand "mulhi3"
7282   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7283                    (mult:HI (match_operand:HI 1 "register_operand" "")
7284                             (match_operand:HI 2 "general_operand" "")))
7285               (clobber (reg:CC FLAGS_REG))])]
7286   "TARGET_HIMODE_MATH"
7287   "")
7288
7289 ;; On AMDFAM10
7290 ;; IMUL reg16, reg16, imm8      VectorPath
7291 ;; IMUL reg16, mem16, imm8      VectorPath
7292 ;; IMUL reg16, reg16, imm16     VectorPath
7293 ;; IMUL reg16, mem16, imm16     VectorPath
7294 ;; IMUL reg16, reg16            Direct
7295 ;; IMUL reg16, mem16            Direct
7296 (define_insn "*mulhi3_1"
7297   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7298         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7299                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7300    (clobber (reg:CC FLAGS_REG))]
7301   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7302   "@
7303    imul{w}\t{%2, %1, %0|%0, %1, %2}
7304    imul{w}\t{%2, %1, %0|%0, %1, %2}
7305    imul{w}\t{%2, %0|%0, %2}"
7306   [(set_attr "type" "imul")
7307    (set_attr "prefix_0f" "0,0,1")
7308    (set (attr "athlon_decode")
7309         (cond [(eq_attr "cpu" "athlon")
7310                   (const_string "vector")
7311                (eq_attr "alternative" "1,2")
7312                   (const_string "vector")]
7313               (const_string "direct")))
7314    (set (attr "amdfam10_decode")
7315         (cond [(eq_attr "alternative" "0,1")
7316                   (const_string "vector")]
7317               (const_string "direct")))
7318    (set_attr "mode" "HI")])
7319
7320 (define_expand "mulqi3"
7321   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7322                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7323                             (match_operand:QI 2 "register_operand" "")))
7324               (clobber (reg:CC FLAGS_REG))])]
7325   "TARGET_QIMODE_MATH"
7326   "")
7327
7328 ;;On AMDFAM10
7329 ;; MUL reg8     Direct
7330 ;; MUL mem8     Direct
7331
7332 (define_insn "*mulqi3_1"
7333   [(set (match_operand:QI 0 "register_operand" "=a")
7334         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7335                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7336    (clobber (reg:CC FLAGS_REG))]
7337   "TARGET_QIMODE_MATH
7338    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7339   "mul{b}\t%2"
7340   [(set_attr "type" "imul")
7341    (set_attr "length_immediate" "0")
7342    (set (attr "athlon_decode")
7343      (if_then_else (eq_attr "cpu" "athlon")
7344         (const_string "vector")
7345         (const_string "direct")))
7346    (set_attr "amdfam10_decode" "direct")        
7347    (set_attr "mode" "QI")])
7348
7349 (define_expand "umulqihi3"
7350   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7351                    (mult:HI (zero_extend:HI
7352                               (match_operand:QI 1 "nonimmediate_operand" ""))
7353                             (zero_extend:HI
7354                               (match_operand:QI 2 "register_operand" ""))))
7355               (clobber (reg:CC FLAGS_REG))])]
7356   "TARGET_QIMODE_MATH"
7357   "")
7358
7359 (define_insn "*umulqihi3_1"
7360   [(set (match_operand:HI 0 "register_operand" "=a")
7361         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7362                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7363    (clobber (reg:CC FLAGS_REG))]
7364   "TARGET_QIMODE_MATH
7365    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7366   "mul{b}\t%2"
7367   [(set_attr "type" "imul")
7368    (set_attr "length_immediate" "0")
7369    (set (attr "athlon_decode")
7370      (if_then_else (eq_attr "cpu" "athlon")
7371         (const_string "vector")
7372         (const_string "direct")))
7373    (set_attr "amdfam10_decode" "direct")        
7374    (set_attr "mode" "QI")])
7375
7376 (define_expand "mulqihi3"
7377   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7378                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7379                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7380               (clobber (reg:CC FLAGS_REG))])]
7381   "TARGET_QIMODE_MATH"
7382   "")
7383
7384 (define_insn "*mulqihi3_insn"
7385   [(set (match_operand:HI 0 "register_operand" "=a")
7386         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7387                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7388    (clobber (reg:CC FLAGS_REG))]
7389   "TARGET_QIMODE_MATH
7390    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7391   "imul{b}\t%2"
7392   [(set_attr "type" "imul")
7393    (set_attr "length_immediate" "0")
7394    (set (attr "athlon_decode")
7395      (if_then_else (eq_attr "cpu" "athlon")
7396         (const_string "vector")
7397         (const_string "direct")))
7398    (set_attr "amdfam10_decode" "direct")        
7399    (set_attr "mode" "QI")])
7400
7401 (define_expand "umulditi3"
7402   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7403                    (mult:TI (zero_extend:TI
7404                               (match_operand:DI 1 "nonimmediate_operand" ""))
7405                             (zero_extend:TI
7406                               (match_operand:DI 2 "register_operand" ""))))
7407               (clobber (reg:CC FLAGS_REG))])]
7408   "TARGET_64BIT"
7409   "")
7410
7411 (define_insn "*umulditi3_insn"
7412   [(set (match_operand:TI 0 "register_operand" "=A")
7413         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7414                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7415    (clobber (reg:CC FLAGS_REG))]
7416   "TARGET_64BIT
7417    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7418   "mul{q}\t%2"
7419   [(set_attr "type" "imul")
7420    (set_attr "length_immediate" "0")
7421    (set (attr "athlon_decode")
7422      (if_then_else (eq_attr "cpu" "athlon")
7423         (const_string "vector")
7424         (const_string "double")))
7425    (set_attr "amdfam10_decode" "double")        
7426    (set_attr "mode" "DI")])
7427
7428 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7429 (define_expand "umulsidi3"
7430   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7431                    (mult:DI (zero_extend:DI
7432                               (match_operand:SI 1 "nonimmediate_operand" ""))
7433                             (zero_extend:DI
7434                               (match_operand:SI 2 "register_operand" ""))))
7435               (clobber (reg:CC FLAGS_REG))])]
7436   "!TARGET_64BIT"
7437   "")
7438
7439 (define_insn "*umulsidi3_insn"
7440   [(set (match_operand:DI 0 "register_operand" "=A")
7441         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7442                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7443    (clobber (reg:CC FLAGS_REG))]
7444   "!TARGET_64BIT
7445    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7446   "mul{l}\t%2"
7447   [(set_attr "type" "imul")
7448    (set_attr "length_immediate" "0")
7449    (set (attr "athlon_decode")
7450      (if_then_else (eq_attr "cpu" "athlon")
7451         (const_string "vector")
7452         (const_string "double")))
7453    (set_attr "amdfam10_decode" "double")        
7454    (set_attr "mode" "SI")])
7455
7456 (define_expand "mulditi3"
7457   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7458                    (mult:TI (sign_extend:TI
7459                               (match_operand:DI 1 "nonimmediate_operand" ""))
7460                             (sign_extend:TI
7461                               (match_operand:DI 2 "register_operand" ""))))
7462               (clobber (reg:CC FLAGS_REG))])]
7463   "TARGET_64BIT"
7464   "")
7465
7466 (define_insn "*mulditi3_insn"
7467   [(set (match_operand:TI 0 "register_operand" "=A")
7468         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7469                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7470    (clobber (reg:CC FLAGS_REG))]
7471   "TARGET_64BIT
7472    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7473   "imul{q}\t%2"
7474   [(set_attr "type" "imul")
7475    (set_attr "length_immediate" "0")
7476    (set (attr "athlon_decode")
7477      (if_then_else (eq_attr "cpu" "athlon")
7478         (const_string "vector")
7479         (const_string "double")))
7480    (set_attr "amdfam10_decode" "double")
7481    (set_attr "mode" "DI")])
7482
7483 (define_expand "mulsidi3"
7484   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7485                    (mult:DI (sign_extend:DI
7486                               (match_operand:SI 1 "nonimmediate_operand" ""))
7487                             (sign_extend:DI
7488                               (match_operand:SI 2 "register_operand" ""))))
7489               (clobber (reg:CC FLAGS_REG))])]
7490   "!TARGET_64BIT"
7491   "")
7492
7493 (define_insn "*mulsidi3_insn"
7494   [(set (match_operand:DI 0 "register_operand" "=A")
7495         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7496                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7497    (clobber (reg:CC FLAGS_REG))]
7498   "!TARGET_64BIT
7499    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7500   "imul{l}\t%2"
7501   [(set_attr "type" "imul")
7502    (set_attr "length_immediate" "0")
7503    (set (attr "athlon_decode")
7504      (if_then_else (eq_attr "cpu" "athlon")
7505         (const_string "vector")
7506         (const_string "double")))
7507    (set_attr "amdfam10_decode" "double")        
7508    (set_attr "mode" "SI")])
7509
7510 (define_expand "umuldi3_highpart"
7511   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7512                    (truncate:DI
7513                      (lshiftrt:TI
7514                        (mult:TI (zero_extend:TI
7515                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7516                                 (zero_extend:TI
7517                                   (match_operand:DI 2 "register_operand" "")))
7518                        (const_int 64))))
7519               (clobber (match_scratch:DI 3 ""))
7520               (clobber (reg:CC FLAGS_REG))])]
7521   "TARGET_64BIT"
7522   "")
7523
7524 (define_insn "*umuldi3_highpart_rex64"
7525   [(set (match_operand:DI 0 "register_operand" "=d")
7526         (truncate:DI
7527           (lshiftrt:TI
7528             (mult:TI (zero_extend:TI
7529                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7530                      (zero_extend:TI
7531                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7532             (const_int 64))))
7533    (clobber (match_scratch:DI 3 "=1"))
7534    (clobber (reg:CC FLAGS_REG))]
7535   "TARGET_64BIT
7536    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7537   "mul{q}\t%2"
7538   [(set_attr "type" "imul")
7539    (set_attr "length_immediate" "0")
7540    (set (attr "athlon_decode")
7541      (if_then_else (eq_attr "cpu" "athlon")
7542         (const_string "vector")
7543         (const_string "double")))
7544    (set_attr "amdfam10_decode" "double")        
7545    (set_attr "mode" "DI")])
7546
7547 (define_expand "umulsi3_highpart"
7548   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7549                    (truncate:SI
7550                      (lshiftrt:DI
7551                        (mult:DI (zero_extend:DI
7552                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7553                                 (zero_extend:DI
7554                                   (match_operand:SI 2 "register_operand" "")))
7555                        (const_int 32))))
7556               (clobber (match_scratch:SI 3 ""))
7557               (clobber (reg:CC FLAGS_REG))])]
7558   ""
7559   "")
7560
7561 (define_insn "*umulsi3_highpart_insn"
7562   [(set (match_operand:SI 0 "register_operand" "=d")
7563         (truncate:SI
7564           (lshiftrt:DI
7565             (mult:DI (zero_extend:DI
7566                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7567                      (zero_extend:DI
7568                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7569             (const_int 32))))
7570    (clobber (match_scratch:SI 3 "=1"))
7571    (clobber (reg:CC FLAGS_REG))]
7572   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7573   "mul{l}\t%2"
7574   [(set_attr "type" "imul")
7575    (set_attr "length_immediate" "0")
7576    (set (attr "athlon_decode")
7577      (if_then_else (eq_attr "cpu" "athlon")
7578         (const_string "vector")
7579         (const_string "double")))
7580    (set_attr "amdfam10_decode" "double")
7581    (set_attr "mode" "SI")])
7582
7583 (define_insn "*umulsi3_highpart_zext"
7584   [(set (match_operand:DI 0 "register_operand" "=d")
7585         (zero_extend:DI (truncate:SI
7586           (lshiftrt:DI
7587             (mult:DI (zero_extend:DI
7588                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7589                      (zero_extend:DI
7590                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7591             (const_int 32)))))
7592    (clobber (match_scratch:SI 3 "=1"))
7593    (clobber (reg:CC FLAGS_REG))]
7594   "TARGET_64BIT
7595    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7596   "mul{l}\t%2"
7597   [(set_attr "type" "imul")
7598    (set_attr "length_immediate" "0")
7599    (set (attr "athlon_decode")
7600      (if_then_else (eq_attr "cpu" "athlon")
7601         (const_string "vector")
7602         (const_string "double")))
7603    (set_attr "amdfam10_decode" "double")
7604    (set_attr "mode" "SI")])
7605
7606 (define_expand "smuldi3_highpart"
7607   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7608                    (truncate:DI
7609                      (lshiftrt:TI
7610                        (mult:TI (sign_extend:TI
7611                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7612                                 (sign_extend:TI
7613                                   (match_operand:DI 2 "register_operand" "")))
7614                        (const_int 64))))
7615               (clobber (match_scratch:DI 3 ""))
7616               (clobber (reg:CC FLAGS_REG))])]
7617   "TARGET_64BIT"
7618   "")
7619
7620 (define_insn "*smuldi3_highpart_rex64"
7621   [(set (match_operand:DI 0 "register_operand" "=d")
7622         (truncate:DI
7623           (lshiftrt:TI
7624             (mult:TI (sign_extend:TI
7625                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7626                      (sign_extend:TI
7627                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7628             (const_int 64))))
7629    (clobber (match_scratch:DI 3 "=1"))
7630    (clobber (reg:CC FLAGS_REG))]
7631   "TARGET_64BIT
7632    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7633   "imul{q}\t%2"
7634   [(set_attr "type" "imul")
7635    (set (attr "athlon_decode")
7636      (if_then_else (eq_attr "cpu" "athlon")
7637         (const_string "vector")
7638         (const_string "double")))
7639    (set_attr "amdfam10_decode" "double")
7640    (set_attr "mode" "DI")])
7641
7642 (define_expand "smulsi3_highpart"
7643   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7644                    (truncate:SI
7645                      (lshiftrt:DI
7646                        (mult:DI (sign_extend:DI
7647                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7648                                 (sign_extend:DI
7649                                   (match_operand:SI 2 "register_operand" "")))
7650                        (const_int 32))))
7651               (clobber (match_scratch:SI 3 ""))
7652               (clobber (reg:CC FLAGS_REG))])]
7653   ""
7654   "")
7655
7656 (define_insn "*smulsi3_highpart_insn"
7657   [(set (match_operand:SI 0 "register_operand" "=d")
7658         (truncate:SI
7659           (lshiftrt:DI
7660             (mult:DI (sign_extend:DI
7661                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7662                      (sign_extend:DI
7663                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7664             (const_int 32))))
7665    (clobber (match_scratch:SI 3 "=1"))
7666    (clobber (reg:CC FLAGS_REG))]
7667   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7668   "imul{l}\t%2"
7669   [(set_attr "type" "imul")
7670    (set (attr "athlon_decode")
7671      (if_then_else (eq_attr "cpu" "athlon")
7672         (const_string "vector")
7673         (const_string "double")))
7674    (set_attr "amdfam10_decode" "double")
7675    (set_attr "mode" "SI")])
7676
7677 (define_insn "*smulsi3_highpart_zext"
7678   [(set (match_operand:DI 0 "register_operand" "=d")
7679         (zero_extend:DI (truncate:SI
7680           (lshiftrt:DI
7681             (mult:DI (sign_extend:DI
7682                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7683                      (sign_extend:DI
7684                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7685             (const_int 32)))))
7686    (clobber (match_scratch:SI 3 "=1"))
7687    (clobber (reg:CC FLAGS_REG))]
7688   "TARGET_64BIT
7689    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7690   "imul{l}\t%2"
7691   [(set_attr "type" "imul")
7692    (set (attr "athlon_decode")
7693      (if_then_else (eq_attr "cpu" "athlon")
7694         (const_string "vector")
7695         (const_string "double")))
7696    (set_attr "amdfam10_decode" "double")
7697    (set_attr "mode" "SI")])
7698
7699 ;; The patterns that match these are at the end of this file.
7700
7701 (define_expand "mulxf3"
7702   [(set (match_operand:XF 0 "register_operand" "")
7703         (mult:XF (match_operand:XF 1 "register_operand" "")
7704                  (match_operand:XF 2 "register_operand" "")))]
7705   "TARGET_80387"
7706   "")
7707
7708 (define_expand "muldf3"
7709   [(set (match_operand:DF 0 "register_operand" "")
7710         (mult:DF (match_operand:DF 1 "register_operand" "")
7711                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7712   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7713   "")
7714
7715 (define_expand "mulsf3"
7716   [(set (match_operand:SF 0 "register_operand" "")
7717         (mult:SF (match_operand:SF 1 "register_operand" "")
7718                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7719   "TARGET_80387 || TARGET_SSE_MATH"
7720   "")
7721 \f
7722 ;; Divide instructions
7723
7724 (define_insn "divqi3"
7725   [(set (match_operand:QI 0 "register_operand" "=a")
7726         (div:QI (match_operand:HI 1 "register_operand" "0")
7727                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7728    (clobber (reg:CC FLAGS_REG))]
7729   "TARGET_QIMODE_MATH"
7730   "idiv{b}\t%2"
7731   [(set_attr "type" "idiv")
7732    (set_attr "mode" "QI")])
7733
7734 (define_insn "udivqi3"
7735   [(set (match_operand:QI 0 "register_operand" "=a")
7736         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7737                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7738    (clobber (reg:CC FLAGS_REG))]
7739   "TARGET_QIMODE_MATH"
7740   "div{b}\t%2"
7741   [(set_attr "type" "idiv")
7742    (set_attr "mode" "QI")])
7743
7744 ;; The patterns that match these are at the end of this file.
7745
7746 (define_expand "divxf3"
7747   [(set (match_operand:XF 0 "register_operand" "")
7748         (div:XF (match_operand:XF 1 "register_operand" "")
7749                 (match_operand:XF 2 "register_operand" "")))]
7750   "TARGET_80387"
7751   "")
7752
7753 (define_expand "divdf3"
7754   [(set (match_operand:DF 0 "register_operand" "")
7755         (div:DF (match_operand:DF 1 "register_operand" "")
7756                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7757    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7758    "")
7759
7760 (define_expand "divsf3"
7761   [(set (match_operand:SF 0 "register_operand" "")
7762         (div:SF (match_operand:SF 1 "register_operand" "")
7763                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7764   "TARGET_80387 || TARGET_SSE_MATH"
7765   "")
7766 \f
7767 ;; Remainder instructions.
7768
7769 (define_expand "divmoddi4"
7770   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7771                    (div:DI (match_operand:DI 1 "register_operand" "")
7772                            (match_operand:DI 2 "nonimmediate_operand" "")))
7773               (set (match_operand:DI 3 "register_operand" "")
7774                    (mod:DI (match_dup 1) (match_dup 2)))
7775               (clobber (reg:CC FLAGS_REG))])]
7776   "TARGET_64BIT"
7777   "")
7778
7779 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7780 ;; Penalize eax case slightly because it results in worse scheduling
7781 ;; of code.
7782 (define_insn "*divmoddi4_nocltd_rex64"
7783   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7784         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7785                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7786    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7787         (mod:DI (match_dup 2) (match_dup 3)))
7788    (clobber (reg:CC FLAGS_REG))]
7789   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7790   "#"
7791   [(set_attr "type" "multi")])
7792
7793 (define_insn "*divmoddi4_cltd_rex64"
7794   [(set (match_operand:DI 0 "register_operand" "=a")
7795         (div:DI (match_operand:DI 2 "register_operand" "a")
7796                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7797    (set (match_operand:DI 1 "register_operand" "=&d")
7798         (mod:DI (match_dup 2) (match_dup 3)))
7799    (clobber (reg:CC FLAGS_REG))]
7800   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7801   "#"
7802   [(set_attr "type" "multi")])
7803
7804 (define_insn "*divmoddi_noext_rex64"
7805   [(set (match_operand:DI 0 "register_operand" "=a")
7806         (div:DI (match_operand:DI 1 "register_operand" "0")
7807                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7808    (set (match_operand:DI 3 "register_operand" "=d")
7809         (mod:DI (match_dup 1) (match_dup 2)))
7810    (use (match_operand:DI 4 "register_operand" "3"))
7811    (clobber (reg:CC FLAGS_REG))]
7812   "TARGET_64BIT"
7813   "idiv{q}\t%2"
7814   [(set_attr "type" "idiv")
7815    (set_attr "mode" "DI")])
7816
7817 (define_split
7818   [(set (match_operand:DI 0 "register_operand" "")
7819         (div:DI (match_operand:DI 1 "register_operand" "")
7820                 (match_operand:DI 2 "nonimmediate_operand" "")))
7821    (set (match_operand:DI 3 "register_operand" "")
7822         (mod:DI (match_dup 1) (match_dup 2)))
7823    (clobber (reg:CC FLAGS_REG))]
7824   "TARGET_64BIT && reload_completed"
7825   [(parallel [(set (match_dup 3)
7826                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7827               (clobber (reg:CC FLAGS_REG))])
7828    (parallel [(set (match_dup 0)
7829                    (div:DI (reg:DI 0) (match_dup 2)))
7830               (set (match_dup 3)
7831                    (mod:DI (reg:DI 0) (match_dup 2)))
7832               (use (match_dup 3))
7833               (clobber (reg:CC FLAGS_REG))])]
7834 {
7835   /* Avoid use of cltd in favor of a mov+shift.  */
7836   if (!TARGET_USE_CLTD && !optimize_size)
7837     {
7838       if (true_regnum (operands[1]))
7839         emit_move_insn (operands[0], operands[1]);
7840       else
7841         emit_move_insn (operands[3], operands[1]);
7842       operands[4] = operands[3];
7843     }
7844   else
7845     {
7846       gcc_assert (!true_regnum (operands[1]));
7847       operands[4] = operands[1];
7848     }
7849 })
7850
7851
7852 (define_expand "divmodsi4"
7853   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7854                    (div:SI (match_operand:SI 1 "register_operand" "")
7855                            (match_operand:SI 2 "nonimmediate_operand" "")))
7856               (set (match_operand:SI 3 "register_operand" "")
7857                    (mod:SI (match_dup 1) (match_dup 2)))
7858               (clobber (reg:CC FLAGS_REG))])]
7859   ""
7860   "")
7861
7862 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7863 ;; Penalize eax case slightly because it results in worse scheduling
7864 ;; of code.
7865 (define_insn "*divmodsi4_nocltd"
7866   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7867         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7868                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7869    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7870         (mod:SI (match_dup 2) (match_dup 3)))
7871    (clobber (reg:CC FLAGS_REG))]
7872   "!optimize_size && !TARGET_USE_CLTD"
7873   "#"
7874   [(set_attr "type" "multi")])
7875
7876 (define_insn "*divmodsi4_cltd"
7877   [(set (match_operand:SI 0 "register_operand" "=a")
7878         (div:SI (match_operand:SI 2 "register_operand" "a")
7879                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7880    (set (match_operand:SI 1 "register_operand" "=&d")
7881         (mod:SI (match_dup 2) (match_dup 3)))
7882    (clobber (reg:CC FLAGS_REG))]
7883   "optimize_size || TARGET_USE_CLTD"
7884   "#"
7885   [(set_attr "type" "multi")])
7886
7887 (define_insn "*divmodsi_noext"
7888   [(set (match_operand:SI 0 "register_operand" "=a")
7889         (div:SI (match_operand:SI 1 "register_operand" "0")
7890                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7891    (set (match_operand:SI 3 "register_operand" "=d")
7892         (mod:SI (match_dup 1) (match_dup 2)))
7893    (use (match_operand:SI 4 "register_operand" "3"))
7894    (clobber (reg:CC FLAGS_REG))]
7895   ""
7896   "idiv{l}\t%2"
7897   [(set_attr "type" "idiv")
7898    (set_attr "mode" "SI")])
7899
7900 (define_split
7901   [(set (match_operand:SI 0 "register_operand" "")
7902         (div:SI (match_operand:SI 1 "register_operand" "")
7903                 (match_operand:SI 2 "nonimmediate_operand" "")))
7904    (set (match_operand:SI 3 "register_operand" "")
7905         (mod:SI (match_dup 1) (match_dup 2)))
7906    (clobber (reg:CC FLAGS_REG))]
7907   "reload_completed"
7908   [(parallel [(set (match_dup 3)
7909                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7910               (clobber (reg:CC FLAGS_REG))])
7911    (parallel [(set (match_dup 0)
7912                    (div:SI (reg:SI 0) (match_dup 2)))
7913               (set (match_dup 3)
7914                    (mod:SI (reg:SI 0) (match_dup 2)))
7915               (use (match_dup 3))
7916               (clobber (reg:CC FLAGS_REG))])]
7917 {
7918   /* Avoid use of cltd in favor of a mov+shift.  */
7919   if (!TARGET_USE_CLTD && !optimize_size)
7920     {
7921       if (true_regnum (operands[1]))
7922         emit_move_insn (operands[0], operands[1]);
7923       else
7924         emit_move_insn (operands[3], operands[1]);
7925       operands[4] = operands[3];
7926     }
7927   else
7928     {
7929       gcc_assert (!true_regnum (operands[1]));
7930       operands[4] = operands[1];
7931     }
7932 })
7933 ;; %%% Split me.
7934 (define_insn "divmodhi4"
7935   [(set (match_operand:HI 0 "register_operand" "=a")
7936         (div:HI (match_operand:HI 1 "register_operand" "0")
7937                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7938    (set (match_operand:HI 3 "register_operand" "=&d")
7939         (mod:HI (match_dup 1) (match_dup 2)))
7940    (clobber (reg:CC FLAGS_REG))]
7941   "TARGET_HIMODE_MATH"
7942   "cwtd\;idiv{w}\t%2"
7943   [(set_attr "type" "multi")
7944    (set_attr "length_immediate" "0")
7945    (set_attr "mode" "SI")])
7946
7947 (define_insn "udivmoddi4"
7948   [(set (match_operand:DI 0 "register_operand" "=a")
7949         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7950                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7951    (set (match_operand:DI 3 "register_operand" "=&d")
7952         (umod:DI (match_dup 1) (match_dup 2)))
7953    (clobber (reg:CC FLAGS_REG))]
7954   "TARGET_64BIT"
7955   "xor{q}\t%3, %3\;div{q}\t%2"
7956   [(set_attr "type" "multi")
7957    (set_attr "length_immediate" "0")
7958    (set_attr "mode" "DI")])
7959
7960 (define_insn "*udivmoddi4_noext"
7961   [(set (match_operand:DI 0 "register_operand" "=a")
7962         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7963                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7964    (set (match_operand:DI 3 "register_operand" "=d")
7965         (umod:DI (match_dup 1) (match_dup 2)))
7966    (use (match_dup 3))
7967    (clobber (reg:CC FLAGS_REG))]
7968   "TARGET_64BIT"
7969   "div{q}\t%2"
7970   [(set_attr "type" "idiv")
7971    (set_attr "mode" "DI")])
7972
7973 (define_split
7974   [(set (match_operand:DI 0 "register_operand" "")
7975         (udiv:DI (match_operand:DI 1 "register_operand" "")
7976                  (match_operand:DI 2 "nonimmediate_operand" "")))
7977    (set (match_operand:DI 3 "register_operand" "")
7978         (umod:DI (match_dup 1) (match_dup 2)))
7979    (clobber (reg:CC FLAGS_REG))]
7980   "TARGET_64BIT && reload_completed"
7981   [(set (match_dup 3) (const_int 0))
7982    (parallel [(set (match_dup 0)
7983                    (udiv:DI (match_dup 1) (match_dup 2)))
7984               (set (match_dup 3)
7985                    (umod:DI (match_dup 1) (match_dup 2)))
7986               (use (match_dup 3))
7987               (clobber (reg:CC FLAGS_REG))])]
7988   "")
7989
7990 (define_insn "udivmodsi4"
7991   [(set (match_operand:SI 0 "register_operand" "=a")
7992         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7993                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7994    (set (match_operand:SI 3 "register_operand" "=&d")
7995         (umod:SI (match_dup 1) (match_dup 2)))
7996    (clobber (reg:CC FLAGS_REG))]
7997   ""
7998   "xor{l}\t%3, %3\;div{l}\t%2"
7999   [(set_attr "type" "multi")
8000    (set_attr "length_immediate" "0")
8001    (set_attr "mode" "SI")])
8002
8003 (define_insn "*udivmodsi4_noext"
8004   [(set (match_operand:SI 0 "register_operand" "=a")
8005         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8006                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8007    (set (match_operand:SI 3 "register_operand" "=d")
8008         (umod:SI (match_dup 1) (match_dup 2)))
8009    (use (match_dup 3))
8010    (clobber (reg:CC FLAGS_REG))]
8011   ""
8012   "div{l}\t%2"
8013   [(set_attr "type" "idiv")
8014    (set_attr "mode" "SI")])
8015
8016 (define_split
8017   [(set (match_operand:SI 0 "register_operand" "")
8018         (udiv:SI (match_operand:SI 1 "register_operand" "")
8019                  (match_operand:SI 2 "nonimmediate_operand" "")))
8020    (set (match_operand:SI 3 "register_operand" "")
8021         (umod:SI (match_dup 1) (match_dup 2)))
8022    (clobber (reg:CC FLAGS_REG))]
8023   "reload_completed"
8024   [(set (match_dup 3) (const_int 0))
8025    (parallel [(set (match_dup 0)
8026                    (udiv:SI (match_dup 1) (match_dup 2)))
8027               (set (match_dup 3)
8028                    (umod:SI (match_dup 1) (match_dup 2)))
8029               (use (match_dup 3))
8030               (clobber (reg:CC FLAGS_REG))])]
8031   "")
8032
8033 (define_expand "udivmodhi4"
8034   [(set (match_dup 4) (const_int 0))
8035    (parallel [(set (match_operand:HI 0 "register_operand" "")
8036                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8037                             (match_operand:HI 2 "nonimmediate_operand" "")))
8038               (set (match_operand:HI 3 "register_operand" "")
8039                    (umod:HI (match_dup 1) (match_dup 2)))
8040               (use (match_dup 4))
8041               (clobber (reg:CC FLAGS_REG))])]
8042   "TARGET_HIMODE_MATH"
8043   "operands[4] = gen_reg_rtx (HImode);")
8044
8045 (define_insn "*udivmodhi_noext"
8046   [(set (match_operand:HI 0 "register_operand" "=a")
8047         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8048                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8049    (set (match_operand:HI 3 "register_operand" "=d")
8050         (umod:HI (match_dup 1) (match_dup 2)))
8051    (use (match_operand:HI 4 "register_operand" "3"))
8052    (clobber (reg:CC FLAGS_REG))]
8053   ""
8054   "div{w}\t%2"
8055   [(set_attr "type" "idiv")
8056    (set_attr "mode" "HI")])
8057
8058 ;; We cannot use div/idiv for double division, because it causes
8059 ;; "division by zero" on the overflow and that's not what we expect
8060 ;; from truncate.  Because true (non truncating) double division is
8061 ;; never generated, we can't create this insn anyway.
8062 ;
8063 ;(define_insn ""
8064 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8065 ;       (truncate:SI
8066 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8067 ;                  (zero_extend:DI
8068 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8069 ;   (set (match_operand:SI 3 "register_operand" "=d")
8070 ;       (truncate:SI
8071 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8072 ;   (clobber (reg:CC FLAGS_REG))]
8073 ;  ""
8074 ;  "div{l}\t{%2, %0|%0, %2}"
8075 ;  [(set_attr "type" "idiv")])
8076 \f
8077 ;;- Logical AND instructions
8078
8079 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8080 ;; Note that this excludes ah.
8081
8082 (define_insn "*testdi_1_rex64"
8083   [(set (reg FLAGS_REG)
8084         (compare
8085           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8086                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8087           (const_int 0)))]
8088   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8089    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8090   "@
8091    test{l}\t{%k1, %k0|%k0, %k1}
8092    test{l}\t{%k1, %k0|%k0, %k1}
8093    test{q}\t{%1, %0|%0, %1}
8094    test{q}\t{%1, %0|%0, %1}
8095    test{q}\t{%1, %0|%0, %1}"
8096   [(set_attr "type" "test")
8097    (set_attr "modrm" "0,1,0,1,1")
8098    (set_attr "mode" "SI,SI,DI,DI,DI")
8099    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8100
8101 (define_insn "testsi_1"
8102   [(set (reg FLAGS_REG)
8103         (compare
8104           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8105                   (match_operand:SI 1 "general_operand" "in,in,rin"))
8106           (const_int 0)))]
8107   "ix86_match_ccmode (insn, CCNOmode)
8108    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8109   "test{l}\t{%1, %0|%0, %1}"
8110   [(set_attr "type" "test")
8111    (set_attr "modrm" "0,1,1")
8112    (set_attr "mode" "SI")
8113    (set_attr "pent_pair" "uv,np,uv")])
8114
8115 (define_expand "testsi_ccno_1"
8116   [(set (reg:CCNO FLAGS_REG)
8117         (compare:CCNO
8118           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8119                   (match_operand:SI 1 "nonmemory_operand" ""))
8120           (const_int 0)))]
8121   ""
8122   "")
8123
8124 (define_insn "*testhi_1"
8125   [(set (reg FLAGS_REG)
8126         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8127                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8128                  (const_int 0)))]
8129   "ix86_match_ccmode (insn, CCNOmode)
8130    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8131   "test{w}\t{%1, %0|%0, %1}"
8132   [(set_attr "type" "test")
8133    (set_attr "modrm" "0,1,1")
8134    (set_attr "mode" "HI")
8135    (set_attr "pent_pair" "uv,np,uv")])
8136
8137 (define_expand "testqi_ccz_1"
8138   [(set (reg:CCZ FLAGS_REG)
8139         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8140                              (match_operand:QI 1 "nonmemory_operand" ""))
8141                  (const_int 0)))]
8142   ""
8143   "")
8144
8145 (define_insn "*testqi_1_maybe_si"
8146   [(set (reg FLAGS_REG)
8147         (compare
8148           (and:QI
8149             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8150             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8151           (const_int 0)))]
8152    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8153     && ix86_match_ccmode (insn,
8154                          CONST_INT_P (operands[1])
8155                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8156 {
8157   if (which_alternative == 3)
8158     {
8159       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8160         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8161       return "test{l}\t{%1, %k0|%k0, %1}";
8162     }
8163   return "test{b}\t{%1, %0|%0, %1}";
8164 }
8165   [(set_attr "type" "test")
8166    (set_attr "modrm" "0,1,1,1")
8167    (set_attr "mode" "QI,QI,QI,SI")
8168    (set_attr "pent_pair" "uv,np,uv,np")])
8169
8170 (define_insn "*testqi_1"
8171   [(set (reg FLAGS_REG)
8172         (compare
8173           (and:QI
8174             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8175             (match_operand:QI 1 "general_operand" "n,n,qn"))
8176           (const_int 0)))]
8177   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8178    && ix86_match_ccmode (insn, CCNOmode)"
8179   "test{b}\t{%1, %0|%0, %1}"
8180   [(set_attr "type" "test")
8181    (set_attr "modrm" "0,1,1")
8182    (set_attr "mode" "QI")
8183    (set_attr "pent_pair" "uv,np,uv")])
8184
8185 (define_expand "testqi_ext_ccno_0"
8186   [(set (reg:CCNO FLAGS_REG)
8187         (compare:CCNO
8188           (and:SI
8189             (zero_extract:SI
8190               (match_operand 0 "ext_register_operand" "")
8191               (const_int 8)
8192               (const_int 8))
8193             (match_operand 1 "const_int_operand" ""))
8194           (const_int 0)))]
8195   ""
8196   "")
8197
8198 (define_insn "*testqi_ext_0"
8199   [(set (reg FLAGS_REG)
8200         (compare
8201           (and:SI
8202             (zero_extract:SI
8203               (match_operand 0 "ext_register_operand" "Q")
8204               (const_int 8)
8205               (const_int 8))
8206             (match_operand 1 "const_int_operand" "n"))
8207           (const_int 0)))]
8208   "ix86_match_ccmode (insn, CCNOmode)"
8209   "test{b}\t{%1, %h0|%h0, %1}"
8210   [(set_attr "type" "test")
8211    (set_attr "mode" "QI")
8212    (set_attr "length_immediate" "1")
8213    (set_attr "pent_pair" "np")])
8214
8215 (define_insn "*testqi_ext_1"
8216   [(set (reg FLAGS_REG)
8217         (compare
8218           (and:SI
8219             (zero_extract:SI
8220               (match_operand 0 "ext_register_operand" "Q")
8221               (const_int 8)
8222               (const_int 8))
8223             (zero_extend:SI
8224               (match_operand:QI 1 "general_operand" "Qm")))
8225           (const_int 0)))]
8226   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8227    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8228   "test{b}\t{%1, %h0|%h0, %1}"
8229   [(set_attr "type" "test")
8230    (set_attr "mode" "QI")])
8231
8232 (define_insn "*testqi_ext_1_rex64"
8233   [(set (reg FLAGS_REG)
8234         (compare
8235           (and:SI
8236             (zero_extract:SI
8237               (match_operand 0 "ext_register_operand" "Q")
8238               (const_int 8)
8239               (const_int 8))
8240             (zero_extend:SI
8241               (match_operand:QI 1 "register_operand" "Q")))
8242           (const_int 0)))]
8243   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8244   "test{b}\t{%1, %h0|%h0, %1}"
8245   [(set_attr "type" "test")
8246    (set_attr "mode" "QI")])
8247
8248 (define_insn "*testqi_ext_2"
8249   [(set (reg FLAGS_REG)
8250         (compare
8251           (and:SI
8252             (zero_extract:SI
8253               (match_operand 0 "ext_register_operand" "Q")
8254               (const_int 8)
8255               (const_int 8))
8256             (zero_extract:SI
8257               (match_operand 1 "ext_register_operand" "Q")
8258               (const_int 8)
8259               (const_int 8)))
8260           (const_int 0)))]
8261   "ix86_match_ccmode (insn, CCNOmode)"
8262   "test{b}\t{%h1, %h0|%h0, %h1}"
8263   [(set_attr "type" "test")
8264    (set_attr "mode" "QI")])
8265
8266 ;; Combine likes to form bit extractions for some tests.  Humor it.
8267 (define_insn "*testqi_ext_3"
8268   [(set (reg FLAGS_REG)
8269         (compare (zero_extract:SI
8270                    (match_operand 0 "nonimmediate_operand" "rm")
8271                    (match_operand:SI 1 "const_int_operand" "")
8272                    (match_operand:SI 2 "const_int_operand" ""))
8273                  (const_int 0)))]
8274   "ix86_match_ccmode (insn, CCNOmode)
8275    && INTVAL (operands[1]) > 0
8276    && INTVAL (operands[2]) >= 0
8277    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8278    && (GET_MODE (operands[0]) == SImode
8279        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8280        || GET_MODE (operands[0]) == HImode
8281        || GET_MODE (operands[0]) == QImode)"
8282   "#")
8283
8284 (define_insn "*testqi_ext_3_rex64"
8285   [(set (reg FLAGS_REG)
8286         (compare (zero_extract:DI
8287                    (match_operand 0 "nonimmediate_operand" "rm")
8288                    (match_operand:DI 1 "const_int_operand" "")
8289                    (match_operand:DI 2 "const_int_operand" ""))
8290                  (const_int 0)))]
8291   "TARGET_64BIT
8292    && ix86_match_ccmode (insn, CCNOmode)
8293    && INTVAL (operands[1]) > 0
8294    && INTVAL (operands[2]) >= 0
8295    /* Ensure that resulting mask is zero or sign extended operand.  */
8296    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8297        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8298            && INTVAL (operands[1]) > 32))
8299    && (GET_MODE (operands[0]) == SImode
8300        || GET_MODE (operands[0]) == DImode
8301        || GET_MODE (operands[0]) == HImode
8302        || GET_MODE (operands[0]) == QImode)"
8303   "#")
8304
8305 (define_split
8306   [(set (match_operand 0 "flags_reg_operand" "")
8307         (match_operator 1 "compare_operator"
8308           [(zero_extract
8309              (match_operand 2 "nonimmediate_operand" "")
8310              (match_operand 3 "const_int_operand" "")
8311              (match_operand 4 "const_int_operand" ""))
8312            (const_int 0)]))]
8313   "ix86_match_ccmode (insn, CCNOmode)"
8314   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8315 {
8316   rtx val = operands[2];
8317   HOST_WIDE_INT len = INTVAL (operands[3]);
8318   HOST_WIDE_INT pos = INTVAL (operands[4]);
8319   HOST_WIDE_INT mask;
8320   enum machine_mode mode, submode;
8321
8322   mode = GET_MODE (val);
8323   if (MEM_P (val))
8324     {
8325       /* ??? Combine likes to put non-volatile mem extractions in QImode
8326          no matter the size of the test.  So find a mode that works.  */
8327       if (! MEM_VOLATILE_P (val))
8328         {
8329           mode = smallest_mode_for_size (pos + len, MODE_INT);
8330           val = adjust_address (val, mode, 0);
8331         }
8332     }
8333   else if (GET_CODE (val) == SUBREG
8334            && (submode = GET_MODE (SUBREG_REG (val)),
8335                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8336            && pos + len <= GET_MODE_BITSIZE (submode))
8337     {
8338       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8339       mode = submode;
8340       val = SUBREG_REG (val);
8341     }
8342   else if (mode == HImode && pos + len <= 8)
8343     {
8344       /* Small HImode tests can be converted to QImode.  */
8345       mode = QImode;
8346       val = gen_lowpart (QImode, val);
8347     }
8348
8349   if (len == HOST_BITS_PER_WIDE_INT)
8350     mask = -1;
8351   else
8352     mask = ((HOST_WIDE_INT)1 << len) - 1;
8353   mask <<= pos;
8354
8355   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8356 })
8357
8358 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8359 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8360 ;; this is relatively important trick.
8361 ;; Do the conversion only post-reload to avoid limiting of the register class
8362 ;; to QI regs.
8363 (define_split
8364   [(set (match_operand 0 "flags_reg_operand" "")
8365         (match_operator 1 "compare_operator"
8366           [(and (match_operand 2 "register_operand" "")
8367                 (match_operand 3 "const_int_operand" ""))
8368            (const_int 0)]))]
8369    "reload_completed
8370     && QI_REG_P (operands[2])
8371     && GET_MODE (operands[2]) != QImode
8372     && ((ix86_match_ccmode (insn, CCZmode)
8373          && !(INTVAL (operands[3]) & ~(255 << 8)))
8374         || (ix86_match_ccmode (insn, CCNOmode)
8375             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8376   [(set (match_dup 0)
8377         (match_op_dup 1
8378           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8379                    (match_dup 3))
8380            (const_int 0)]))]
8381   "operands[2] = gen_lowpart (SImode, operands[2]);
8382    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8383
8384 (define_split
8385   [(set (match_operand 0 "flags_reg_operand" "")
8386         (match_operator 1 "compare_operator"
8387           [(and (match_operand 2 "nonimmediate_operand" "")
8388                 (match_operand 3 "const_int_operand" ""))
8389            (const_int 0)]))]
8390    "reload_completed
8391     && GET_MODE (operands[2]) != QImode
8392     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8393     && ((ix86_match_ccmode (insn, CCZmode)
8394          && !(INTVAL (operands[3]) & ~255))
8395         || (ix86_match_ccmode (insn, CCNOmode)
8396             && !(INTVAL (operands[3]) & ~127)))"
8397   [(set (match_dup 0)
8398         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8399                          (const_int 0)]))]
8400   "operands[2] = gen_lowpart (QImode, operands[2]);
8401    operands[3] = gen_lowpart (QImode, operands[3]);")
8402
8403
8404 ;; %%% This used to optimize known byte-wide and operations to memory,
8405 ;; and sometimes to QImode registers.  If this is considered useful,
8406 ;; it should be done with splitters.
8407
8408 (define_expand "anddi3"
8409   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8410         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8411                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8412    (clobber (reg:CC FLAGS_REG))]
8413   "TARGET_64BIT"
8414   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8415
8416 (define_insn "*anddi_1_rex64"
8417   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8418         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8419                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8420    (clobber (reg:CC FLAGS_REG))]
8421   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8422 {
8423   switch (get_attr_type (insn))
8424     {
8425     case TYPE_IMOVX:
8426       {
8427         enum machine_mode mode;
8428
8429         gcc_assert (CONST_INT_P (operands[2]));
8430         if (INTVAL (operands[2]) == 0xff)
8431           mode = QImode;
8432         else
8433           {
8434             gcc_assert (INTVAL (operands[2]) == 0xffff);
8435             mode = HImode;
8436           }
8437
8438         operands[1] = gen_lowpart (mode, operands[1]);
8439         if (mode == QImode)
8440           return "movz{bq|x}\t{%1,%0|%0, %1}";
8441         else
8442           return "movz{wq|x}\t{%1,%0|%0, %1}";
8443       }
8444
8445     default:
8446       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8447       if (get_attr_mode (insn) == MODE_SI)
8448         return "and{l}\t{%k2, %k0|%k0, %k2}";
8449       else
8450         return "and{q}\t{%2, %0|%0, %2}";
8451     }
8452 }
8453   [(set_attr "type" "alu,alu,alu,imovx")
8454    (set_attr "length_immediate" "*,*,*,0")
8455    (set_attr "mode" "SI,DI,DI,DI")])
8456
8457 (define_insn "*anddi_2"
8458   [(set (reg FLAGS_REG)
8459         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8460                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8461                  (const_int 0)))
8462    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8463         (and:DI (match_dup 1) (match_dup 2)))]
8464   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8465    && ix86_binary_operator_ok (AND, DImode, operands)"
8466   "@
8467    and{l}\t{%k2, %k0|%k0, %k2}
8468    and{q}\t{%2, %0|%0, %2}
8469    and{q}\t{%2, %0|%0, %2}"
8470   [(set_attr "type" "alu")
8471    (set_attr "mode" "SI,DI,DI")])
8472
8473 (define_expand "andsi3"
8474   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8475         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8476                 (match_operand:SI 2 "general_operand" "")))
8477    (clobber (reg:CC FLAGS_REG))]
8478   ""
8479   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8480
8481 (define_insn "*andsi_1"
8482   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8483         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8484                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8485    (clobber (reg:CC FLAGS_REG))]
8486   "ix86_binary_operator_ok (AND, SImode, operands)"
8487 {
8488   switch (get_attr_type (insn))
8489     {
8490     case TYPE_IMOVX:
8491       {
8492         enum machine_mode mode;
8493
8494         gcc_assert (CONST_INT_P (operands[2]));
8495         if (INTVAL (operands[2]) == 0xff)
8496           mode = QImode;
8497         else
8498           {
8499             gcc_assert (INTVAL (operands[2]) == 0xffff);
8500             mode = HImode;
8501           }
8502
8503         operands[1] = gen_lowpart (mode, operands[1]);
8504         if (mode == QImode)
8505           return "movz{bl|x}\t{%1,%0|%0, %1}";
8506         else
8507           return "movz{wl|x}\t{%1,%0|%0, %1}";
8508       }
8509
8510     default:
8511       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8512       return "and{l}\t{%2, %0|%0, %2}";
8513     }
8514 }
8515   [(set_attr "type" "alu,alu,imovx")
8516    (set_attr "length_immediate" "*,*,0")
8517    (set_attr "mode" "SI")])
8518
8519 (define_split
8520   [(set (match_operand 0 "register_operand" "")
8521         (and (match_dup 0)
8522              (const_int -65536)))
8523    (clobber (reg:CC FLAGS_REG))]
8524   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8525   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8526   "operands[1] = gen_lowpart (HImode, operands[0]);")
8527
8528 (define_split
8529   [(set (match_operand 0 "ext_register_operand" "")
8530         (and (match_dup 0)
8531              (const_int -256)))
8532    (clobber (reg:CC FLAGS_REG))]
8533   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8534   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8535   "operands[1] = gen_lowpart (QImode, operands[0]);")
8536
8537 (define_split
8538   [(set (match_operand 0 "ext_register_operand" "")
8539         (and (match_dup 0)
8540              (const_int -65281)))
8541    (clobber (reg:CC FLAGS_REG))]
8542   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8543   [(parallel [(set (zero_extract:SI (match_dup 0)
8544                                     (const_int 8)
8545                                     (const_int 8))
8546                    (xor:SI
8547                      (zero_extract:SI (match_dup 0)
8548                                       (const_int 8)
8549                                       (const_int 8))
8550                      (zero_extract:SI (match_dup 0)
8551                                       (const_int 8)
8552                                       (const_int 8))))
8553               (clobber (reg:CC FLAGS_REG))])]
8554   "operands[0] = gen_lowpart (SImode, operands[0]);")
8555
8556 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8557 (define_insn "*andsi_1_zext"
8558   [(set (match_operand:DI 0 "register_operand" "=r")
8559         (zero_extend:DI
8560           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8561                   (match_operand:SI 2 "general_operand" "rim"))))
8562    (clobber (reg:CC FLAGS_REG))]
8563   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8564   "and{l}\t{%2, %k0|%k0, %2}"
8565   [(set_attr "type" "alu")
8566    (set_attr "mode" "SI")])
8567
8568 (define_insn "*andsi_2"
8569   [(set (reg FLAGS_REG)
8570         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8571                          (match_operand:SI 2 "general_operand" "rim,ri"))
8572                  (const_int 0)))
8573    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8574         (and:SI (match_dup 1) (match_dup 2)))]
8575   "ix86_match_ccmode (insn, CCNOmode)
8576    && ix86_binary_operator_ok (AND, SImode, operands)"
8577   "and{l}\t{%2, %0|%0, %2}"
8578   [(set_attr "type" "alu")
8579    (set_attr "mode" "SI")])
8580
8581 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8582 (define_insn "*andsi_2_zext"
8583   [(set (reg FLAGS_REG)
8584         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8585                          (match_operand:SI 2 "general_operand" "rim"))
8586                  (const_int 0)))
8587    (set (match_operand:DI 0 "register_operand" "=r")
8588         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8589   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8590    && ix86_binary_operator_ok (AND, SImode, operands)"
8591   "and{l}\t{%2, %k0|%k0, %2}"
8592   [(set_attr "type" "alu")
8593    (set_attr "mode" "SI")])
8594
8595 (define_expand "andhi3"
8596   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8597         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8598                 (match_operand:HI 2 "general_operand" "")))
8599    (clobber (reg:CC FLAGS_REG))]
8600   "TARGET_HIMODE_MATH"
8601   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8602
8603 (define_insn "*andhi_1"
8604   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8605         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8606                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8607    (clobber (reg:CC FLAGS_REG))]
8608   "ix86_binary_operator_ok (AND, HImode, operands)"
8609 {
8610   switch (get_attr_type (insn))
8611     {
8612     case TYPE_IMOVX:
8613       gcc_assert (CONST_INT_P (operands[2]));
8614       gcc_assert (INTVAL (operands[2]) == 0xff);
8615       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8616
8617     default:
8618       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8619
8620       return "and{w}\t{%2, %0|%0, %2}";
8621     }
8622 }
8623   [(set_attr "type" "alu,alu,imovx")
8624    (set_attr "length_immediate" "*,*,0")
8625    (set_attr "mode" "HI,HI,SI")])
8626
8627 (define_insn "*andhi_2"
8628   [(set (reg FLAGS_REG)
8629         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8630                          (match_operand:HI 2 "general_operand" "rim,ri"))
8631                  (const_int 0)))
8632    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8633         (and:HI (match_dup 1) (match_dup 2)))]
8634   "ix86_match_ccmode (insn, CCNOmode)
8635    && ix86_binary_operator_ok (AND, HImode, operands)"
8636   "and{w}\t{%2, %0|%0, %2}"
8637   [(set_attr "type" "alu")
8638    (set_attr "mode" "HI")])
8639
8640 (define_expand "andqi3"
8641   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8642         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8643                 (match_operand:QI 2 "general_operand" "")))
8644    (clobber (reg:CC FLAGS_REG))]
8645   "TARGET_QIMODE_MATH"
8646   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8647
8648 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8649 (define_insn "*andqi_1"
8650   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8651         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8652                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8653    (clobber (reg:CC FLAGS_REG))]
8654   "ix86_binary_operator_ok (AND, QImode, operands)"
8655   "@
8656    and{b}\t{%2, %0|%0, %2}
8657    and{b}\t{%2, %0|%0, %2}
8658    and{l}\t{%k2, %k0|%k0, %k2}"
8659   [(set_attr "type" "alu")
8660    (set_attr "mode" "QI,QI,SI")])
8661
8662 (define_insn "*andqi_1_slp"
8663   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8664         (and:QI (match_dup 0)
8665                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8666    (clobber (reg:CC FLAGS_REG))]
8667   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8668    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8669   "and{b}\t{%1, %0|%0, %1}"
8670   [(set_attr "type" "alu1")
8671    (set_attr "mode" "QI")])
8672
8673 (define_insn "*andqi_2_maybe_si"
8674   [(set (reg FLAGS_REG)
8675         (compare (and:QI
8676                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8677                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8678                  (const_int 0)))
8679    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8680         (and:QI (match_dup 1) (match_dup 2)))]
8681   "ix86_binary_operator_ok (AND, QImode, operands)
8682    && ix86_match_ccmode (insn,
8683                          CONST_INT_P (operands[2])
8684                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8685 {
8686   if (which_alternative == 2)
8687     {
8688       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8689         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8690       return "and{l}\t{%2, %k0|%k0, %2}";
8691     }
8692   return "and{b}\t{%2, %0|%0, %2}";
8693 }
8694   [(set_attr "type" "alu")
8695    (set_attr "mode" "QI,QI,SI")])
8696
8697 (define_insn "*andqi_2"
8698   [(set (reg FLAGS_REG)
8699         (compare (and:QI
8700                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8701                    (match_operand:QI 2 "general_operand" "qim,qi"))
8702                  (const_int 0)))
8703    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8704         (and:QI (match_dup 1) (match_dup 2)))]
8705   "ix86_match_ccmode (insn, CCNOmode)
8706    && ix86_binary_operator_ok (AND, QImode, operands)"
8707   "and{b}\t{%2, %0|%0, %2}"
8708   [(set_attr "type" "alu")
8709    (set_attr "mode" "QI")])
8710
8711 (define_insn "*andqi_2_slp"
8712   [(set (reg FLAGS_REG)
8713         (compare (and:QI
8714                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8715                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8716                  (const_int 0)))
8717    (set (strict_low_part (match_dup 0))
8718         (and:QI (match_dup 0) (match_dup 1)))]
8719   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8720    && ix86_match_ccmode (insn, CCNOmode)
8721    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8722   "and{b}\t{%1, %0|%0, %1}"
8723   [(set_attr "type" "alu1")
8724    (set_attr "mode" "QI")])
8725
8726 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8727 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8728 ;; for a QImode operand, which of course failed.
8729
8730 (define_insn "andqi_ext_0"
8731   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8732                          (const_int 8)
8733                          (const_int 8))
8734         (and:SI
8735           (zero_extract:SI
8736             (match_operand 1 "ext_register_operand" "0")
8737             (const_int 8)
8738             (const_int 8))
8739           (match_operand 2 "const_int_operand" "n")))
8740    (clobber (reg:CC FLAGS_REG))]
8741   ""
8742   "and{b}\t{%2, %h0|%h0, %2}"
8743   [(set_attr "type" "alu")
8744    (set_attr "length_immediate" "1")
8745    (set_attr "mode" "QI")])
8746
8747 ;; Generated by peephole translating test to and.  This shows up
8748 ;; often in fp comparisons.
8749
8750 (define_insn "*andqi_ext_0_cc"
8751   [(set (reg FLAGS_REG)
8752         (compare
8753           (and:SI
8754             (zero_extract:SI
8755               (match_operand 1 "ext_register_operand" "0")
8756               (const_int 8)
8757               (const_int 8))
8758             (match_operand 2 "const_int_operand" "n"))
8759           (const_int 0)))
8760    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8761                          (const_int 8)
8762                          (const_int 8))
8763         (and:SI
8764           (zero_extract:SI
8765             (match_dup 1)
8766             (const_int 8)
8767             (const_int 8))
8768           (match_dup 2)))]
8769   "ix86_match_ccmode (insn, CCNOmode)"
8770   "and{b}\t{%2, %h0|%h0, %2}"
8771   [(set_attr "type" "alu")
8772    (set_attr "length_immediate" "1")
8773    (set_attr "mode" "QI")])
8774
8775 (define_insn "*andqi_ext_1"
8776   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8777                          (const_int 8)
8778                          (const_int 8))
8779         (and:SI
8780           (zero_extract:SI
8781             (match_operand 1 "ext_register_operand" "0")
8782             (const_int 8)
8783             (const_int 8))
8784           (zero_extend:SI
8785             (match_operand:QI 2 "general_operand" "Qm"))))
8786    (clobber (reg:CC FLAGS_REG))]
8787   "!TARGET_64BIT"
8788   "and{b}\t{%2, %h0|%h0, %2}"
8789   [(set_attr "type" "alu")
8790    (set_attr "length_immediate" "0")
8791    (set_attr "mode" "QI")])
8792
8793 (define_insn "*andqi_ext_1_rex64"
8794   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8795                          (const_int 8)
8796                          (const_int 8))
8797         (and:SI
8798           (zero_extract:SI
8799             (match_operand 1 "ext_register_operand" "0")
8800             (const_int 8)
8801             (const_int 8))
8802           (zero_extend:SI
8803             (match_operand 2 "ext_register_operand" "Q"))))
8804    (clobber (reg:CC FLAGS_REG))]
8805   "TARGET_64BIT"
8806   "and{b}\t{%2, %h0|%h0, %2}"
8807   [(set_attr "type" "alu")
8808    (set_attr "length_immediate" "0")
8809    (set_attr "mode" "QI")])
8810
8811 (define_insn "*andqi_ext_2"
8812   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8813                          (const_int 8)
8814                          (const_int 8))
8815         (and:SI
8816           (zero_extract:SI
8817             (match_operand 1 "ext_register_operand" "%0")
8818             (const_int 8)
8819             (const_int 8))
8820           (zero_extract:SI
8821             (match_operand 2 "ext_register_operand" "Q")
8822             (const_int 8)
8823             (const_int 8))))
8824    (clobber (reg:CC FLAGS_REG))]
8825   ""
8826   "and{b}\t{%h2, %h0|%h0, %h2}"
8827   [(set_attr "type" "alu")
8828    (set_attr "length_immediate" "0")
8829    (set_attr "mode" "QI")])
8830
8831 ;; Convert wide AND instructions with immediate operand to shorter QImode
8832 ;; equivalents when possible.
8833 ;; Don't do the splitting with memory operands, since it introduces risk
8834 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8835 ;; for size, but that can (should?) be handled by generic code instead.
8836 (define_split
8837   [(set (match_operand 0 "register_operand" "")
8838         (and (match_operand 1 "register_operand" "")
8839              (match_operand 2 "const_int_operand" "")))
8840    (clobber (reg:CC FLAGS_REG))]
8841    "reload_completed
8842     && QI_REG_P (operands[0])
8843     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8844     && !(~INTVAL (operands[2]) & ~(255 << 8))
8845     && GET_MODE (operands[0]) != QImode"
8846   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8847                    (and:SI (zero_extract:SI (match_dup 1)
8848                                             (const_int 8) (const_int 8))
8849                            (match_dup 2)))
8850               (clobber (reg:CC FLAGS_REG))])]
8851   "operands[0] = gen_lowpart (SImode, operands[0]);
8852    operands[1] = gen_lowpart (SImode, operands[1]);
8853    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8854
8855 ;; Since AND can be encoded with sign extended immediate, this is only
8856 ;; profitable when 7th bit is not set.
8857 (define_split
8858   [(set (match_operand 0 "register_operand" "")
8859         (and (match_operand 1 "general_operand" "")
8860              (match_operand 2 "const_int_operand" "")))
8861    (clobber (reg:CC FLAGS_REG))]
8862    "reload_completed
8863     && ANY_QI_REG_P (operands[0])
8864     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8865     && !(~INTVAL (operands[2]) & ~255)
8866     && !(INTVAL (operands[2]) & 128)
8867     && GET_MODE (operands[0]) != QImode"
8868   [(parallel [(set (strict_low_part (match_dup 0))
8869                    (and:QI (match_dup 1)
8870                            (match_dup 2)))
8871               (clobber (reg:CC FLAGS_REG))])]
8872   "operands[0] = gen_lowpart (QImode, operands[0]);
8873    operands[1] = gen_lowpart (QImode, operands[1]);
8874    operands[2] = gen_lowpart (QImode, operands[2]);")
8875 \f
8876 ;; Logical inclusive OR instructions
8877
8878 ;; %%% This used to optimize known byte-wide and operations to memory.
8879 ;; If this is considered useful, it should be done with splitters.
8880
8881 (define_expand "iordi3"
8882   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8883         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8884                 (match_operand:DI 2 "x86_64_general_operand" "")))
8885    (clobber (reg:CC FLAGS_REG))]
8886   "TARGET_64BIT"
8887   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8888
8889 (define_insn "*iordi_1_rex64"
8890   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8891         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8892                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8893    (clobber (reg:CC FLAGS_REG))]
8894   "TARGET_64BIT
8895    && ix86_binary_operator_ok (IOR, DImode, operands)"
8896   "or{q}\t{%2, %0|%0, %2}"
8897   [(set_attr "type" "alu")
8898    (set_attr "mode" "DI")])
8899
8900 (define_insn "*iordi_2_rex64"
8901   [(set (reg FLAGS_REG)
8902         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8903                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8904                  (const_int 0)))
8905    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8906         (ior:DI (match_dup 1) (match_dup 2)))]
8907   "TARGET_64BIT
8908    && ix86_match_ccmode (insn, CCNOmode)
8909    && ix86_binary_operator_ok (IOR, DImode, operands)"
8910   "or{q}\t{%2, %0|%0, %2}"
8911   [(set_attr "type" "alu")
8912    (set_attr "mode" "DI")])
8913
8914 (define_insn "*iordi_3_rex64"
8915   [(set (reg FLAGS_REG)
8916         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8917                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8918                  (const_int 0)))
8919    (clobber (match_scratch:DI 0 "=r"))]
8920   "TARGET_64BIT
8921    && ix86_match_ccmode (insn, CCNOmode)
8922    && ix86_binary_operator_ok (IOR, DImode, operands)"
8923   "or{q}\t{%2, %0|%0, %2}"
8924   [(set_attr "type" "alu")
8925    (set_attr "mode" "DI")])
8926
8927
8928 (define_expand "iorsi3"
8929   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8930         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8931                 (match_operand:SI 2 "general_operand" "")))
8932    (clobber (reg:CC FLAGS_REG))]
8933   ""
8934   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8935
8936 (define_insn "*iorsi_1"
8937   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8938         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8939                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8940    (clobber (reg:CC FLAGS_REG))]
8941   "ix86_binary_operator_ok (IOR, SImode, operands)"
8942   "or{l}\t{%2, %0|%0, %2}"
8943   [(set_attr "type" "alu")
8944    (set_attr "mode" "SI")])
8945
8946 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8947 (define_insn "*iorsi_1_zext"
8948   [(set (match_operand:DI 0 "register_operand" "=rm")
8949         (zero_extend:DI
8950           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8951                   (match_operand:SI 2 "general_operand" "rim"))))
8952    (clobber (reg:CC FLAGS_REG))]
8953   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8954   "or{l}\t{%2, %k0|%k0, %2}"
8955   [(set_attr "type" "alu")
8956    (set_attr "mode" "SI")])
8957
8958 (define_insn "*iorsi_1_zext_imm"
8959   [(set (match_operand:DI 0 "register_operand" "=rm")
8960         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8961                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8962    (clobber (reg:CC FLAGS_REG))]
8963   "TARGET_64BIT"
8964   "or{l}\t{%2, %k0|%k0, %2}"
8965   [(set_attr "type" "alu")
8966    (set_attr "mode" "SI")])
8967
8968 (define_insn "*iorsi_2"
8969   [(set (reg FLAGS_REG)
8970         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8971                          (match_operand:SI 2 "general_operand" "rim,ri"))
8972                  (const_int 0)))
8973    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8974         (ior:SI (match_dup 1) (match_dup 2)))]
8975   "ix86_match_ccmode (insn, CCNOmode)
8976    && ix86_binary_operator_ok (IOR, SImode, operands)"
8977   "or{l}\t{%2, %0|%0, %2}"
8978   [(set_attr "type" "alu")
8979    (set_attr "mode" "SI")])
8980
8981 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8982 ;; ??? Special case for immediate operand is missing - it is tricky.
8983 (define_insn "*iorsi_2_zext"
8984   [(set (reg FLAGS_REG)
8985         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8986                          (match_operand:SI 2 "general_operand" "rim"))
8987                  (const_int 0)))
8988    (set (match_operand:DI 0 "register_operand" "=r")
8989         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8990   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8991    && ix86_binary_operator_ok (IOR, SImode, operands)"
8992   "or{l}\t{%2, %k0|%k0, %2}"
8993   [(set_attr "type" "alu")
8994    (set_attr "mode" "SI")])
8995
8996 (define_insn "*iorsi_2_zext_imm"
8997   [(set (reg FLAGS_REG)
8998         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8999                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9000                  (const_int 0)))
9001    (set (match_operand:DI 0 "register_operand" "=r")
9002         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9003   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9004    && ix86_binary_operator_ok (IOR, SImode, operands)"
9005   "or{l}\t{%2, %k0|%k0, %2}"
9006   [(set_attr "type" "alu")
9007    (set_attr "mode" "SI")])
9008
9009 (define_insn "*iorsi_3"
9010   [(set (reg FLAGS_REG)
9011         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9012                          (match_operand:SI 2 "general_operand" "rim"))
9013                  (const_int 0)))
9014    (clobber (match_scratch:SI 0 "=r"))]
9015   "ix86_match_ccmode (insn, CCNOmode)
9016    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9017   "or{l}\t{%2, %0|%0, %2}"
9018   [(set_attr "type" "alu")
9019    (set_attr "mode" "SI")])
9020
9021 (define_expand "iorhi3"
9022   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9023         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9024                 (match_operand:HI 2 "general_operand" "")))
9025    (clobber (reg:CC FLAGS_REG))]
9026   "TARGET_HIMODE_MATH"
9027   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9028
9029 (define_insn "*iorhi_1"
9030   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9031         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9032                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9033    (clobber (reg:CC FLAGS_REG))]
9034   "ix86_binary_operator_ok (IOR, HImode, operands)"
9035   "or{w}\t{%2, %0|%0, %2}"
9036   [(set_attr "type" "alu")
9037    (set_attr "mode" "HI")])
9038
9039 (define_insn "*iorhi_2"
9040   [(set (reg FLAGS_REG)
9041         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9042                          (match_operand:HI 2 "general_operand" "rim,ri"))
9043                  (const_int 0)))
9044    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9045         (ior:HI (match_dup 1) (match_dup 2)))]
9046   "ix86_match_ccmode (insn, CCNOmode)
9047    && ix86_binary_operator_ok (IOR, HImode, operands)"
9048   "or{w}\t{%2, %0|%0, %2}"
9049   [(set_attr "type" "alu")
9050    (set_attr "mode" "HI")])
9051
9052 (define_insn "*iorhi_3"
9053   [(set (reg FLAGS_REG)
9054         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9055                          (match_operand:HI 2 "general_operand" "rim"))
9056                  (const_int 0)))
9057    (clobber (match_scratch:HI 0 "=r"))]
9058   "ix86_match_ccmode (insn, CCNOmode)
9059    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9060   "or{w}\t{%2, %0|%0, %2}"
9061   [(set_attr "type" "alu")
9062    (set_attr "mode" "HI")])
9063
9064 (define_expand "iorqi3"
9065   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9066         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9067                 (match_operand:QI 2 "general_operand" "")))
9068    (clobber (reg:CC FLAGS_REG))]
9069   "TARGET_QIMODE_MATH"
9070   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9071
9072 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9073 (define_insn "*iorqi_1"
9074   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9075         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9076                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9077    (clobber (reg:CC FLAGS_REG))]
9078   "ix86_binary_operator_ok (IOR, QImode, operands)"
9079   "@
9080    or{b}\t{%2, %0|%0, %2}
9081    or{b}\t{%2, %0|%0, %2}
9082    or{l}\t{%k2, %k0|%k0, %k2}"
9083   [(set_attr "type" "alu")
9084    (set_attr "mode" "QI,QI,SI")])
9085
9086 (define_insn "*iorqi_1_slp"
9087   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9088         (ior:QI (match_dup 0)
9089                 (match_operand:QI 1 "general_operand" "qmi,qi")))
9090    (clobber (reg:CC FLAGS_REG))]
9091   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9092    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9093   "or{b}\t{%1, %0|%0, %1}"
9094   [(set_attr "type" "alu1")
9095    (set_attr "mode" "QI")])
9096
9097 (define_insn "*iorqi_2"
9098   [(set (reg FLAGS_REG)
9099         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9100                          (match_operand:QI 2 "general_operand" "qim,qi"))
9101                  (const_int 0)))
9102    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9103         (ior:QI (match_dup 1) (match_dup 2)))]
9104   "ix86_match_ccmode (insn, CCNOmode)
9105    && ix86_binary_operator_ok (IOR, QImode, operands)"
9106   "or{b}\t{%2, %0|%0, %2}"
9107   [(set_attr "type" "alu")
9108    (set_attr "mode" "QI")])
9109
9110 (define_insn "*iorqi_2_slp"
9111   [(set (reg FLAGS_REG)
9112         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9113                          (match_operand:QI 1 "general_operand" "qim,qi"))
9114                  (const_int 0)))
9115    (set (strict_low_part (match_dup 0))
9116         (ior:QI (match_dup 0) (match_dup 1)))]
9117   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9118    && ix86_match_ccmode (insn, CCNOmode)
9119    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9120   "or{b}\t{%1, %0|%0, %1}"
9121   [(set_attr "type" "alu1")
9122    (set_attr "mode" "QI")])
9123
9124 (define_insn "*iorqi_3"
9125   [(set (reg FLAGS_REG)
9126         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9127                          (match_operand:QI 2 "general_operand" "qim"))
9128                  (const_int 0)))
9129    (clobber (match_scratch:QI 0 "=q"))]
9130   "ix86_match_ccmode (insn, CCNOmode)
9131    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9132   "or{b}\t{%2, %0|%0, %2}"
9133   [(set_attr "type" "alu")
9134    (set_attr "mode" "QI")])
9135
9136 (define_insn "iorqi_ext_0"
9137   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9138                          (const_int 8)
9139                          (const_int 8))
9140         (ior:SI
9141           (zero_extract:SI
9142             (match_operand 1 "ext_register_operand" "0")
9143             (const_int 8)
9144             (const_int 8))
9145           (match_operand 2 "const_int_operand" "n")))
9146    (clobber (reg:CC FLAGS_REG))]
9147   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9148   "or{b}\t{%2, %h0|%h0, %2}"
9149   [(set_attr "type" "alu")
9150    (set_attr "length_immediate" "1")
9151    (set_attr "mode" "QI")])
9152
9153 (define_insn "*iorqi_ext_1"
9154   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9155                          (const_int 8)
9156                          (const_int 8))
9157         (ior:SI
9158           (zero_extract:SI
9159             (match_operand 1 "ext_register_operand" "0")
9160             (const_int 8)
9161             (const_int 8))
9162           (zero_extend:SI
9163             (match_operand:QI 2 "general_operand" "Qm"))))
9164    (clobber (reg:CC FLAGS_REG))]
9165   "!TARGET_64BIT
9166    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9167   "or{b}\t{%2, %h0|%h0, %2}"
9168   [(set_attr "type" "alu")
9169    (set_attr "length_immediate" "0")
9170    (set_attr "mode" "QI")])
9171
9172 (define_insn "*iorqi_ext_1_rex64"
9173   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9174                          (const_int 8)
9175                          (const_int 8))
9176         (ior:SI
9177           (zero_extract:SI
9178             (match_operand 1 "ext_register_operand" "0")
9179             (const_int 8)
9180             (const_int 8))
9181           (zero_extend:SI
9182             (match_operand 2 "ext_register_operand" "Q"))))
9183    (clobber (reg:CC FLAGS_REG))]
9184   "TARGET_64BIT
9185    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9186   "or{b}\t{%2, %h0|%h0, %2}"
9187   [(set_attr "type" "alu")
9188    (set_attr "length_immediate" "0")
9189    (set_attr "mode" "QI")])
9190
9191 (define_insn "*iorqi_ext_2"
9192   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9193                          (const_int 8)
9194                          (const_int 8))
9195         (ior:SI
9196           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9197                            (const_int 8)
9198                            (const_int 8))
9199           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9200                            (const_int 8)
9201                            (const_int 8))))
9202    (clobber (reg:CC FLAGS_REG))]
9203   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9204   "ior{b}\t{%h2, %h0|%h0, %h2}"
9205   [(set_attr "type" "alu")
9206    (set_attr "length_immediate" "0")
9207    (set_attr "mode" "QI")])
9208
9209 (define_split
9210   [(set (match_operand 0 "register_operand" "")
9211         (ior (match_operand 1 "register_operand" "")
9212              (match_operand 2 "const_int_operand" "")))
9213    (clobber (reg:CC FLAGS_REG))]
9214    "reload_completed
9215     && QI_REG_P (operands[0])
9216     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9217     && !(INTVAL (operands[2]) & ~(255 << 8))
9218     && GET_MODE (operands[0]) != QImode"
9219   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9220                    (ior:SI (zero_extract:SI (match_dup 1)
9221                                             (const_int 8) (const_int 8))
9222                            (match_dup 2)))
9223               (clobber (reg:CC FLAGS_REG))])]
9224   "operands[0] = gen_lowpart (SImode, operands[0]);
9225    operands[1] = gen_lowpart (SImode, operands[1]);
9226    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9227
9228 ;; Since OR can be encoded with sign extended immediate, this is only
9229 ;; profitable when 7th bit is set.
9230 (define_split
9231   [(set (match_operand 0 "register_operand" "")
9232         (ior (match_operand 1 "general_operand" "")
9233              (match_operand 2 "const_int_operand" "")))
9234    (clobber (reg:CC FLAGS_REG))]
9235    "reload_completed
9236     && ANY_QI_REG_P (operands[0])
9237     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9238     && !(INTVAL (operands[2]) & ~255)
9239     && (INTVAL (operands[2]) & 128)
9240     && GET_MODE (operands[0]) != QImode"
9241   [(parallel [(set (strict_low_part (match_dup 0))
9242                    (ior:QI (match_dup 1)
9243                            (match_dup 2)))
9244               (clobber (reg:CC FLAGS_REG))])]
9245   "operands[0] = gen_lowpart (QImode, operands[0]);
9246    operands[1] = gen_lowpart (QImode, operands[1]);
9247    operands[2] = gen_lowpart (QImode, operands[2]);")
9248 \f
9249 ;; Logical XOR instructions
9250
9251 ;; %%% This used to optimize known byte-wide and operations to memory.
9252 ;; If this is considered useful, it should be done with splitters.
9253
9254 (define_expand "xordi3"
9255   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9256         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9257                 (match_operand:DI 2 "x86_64_general_operand" "")))
9258    (clobber (reg:CC FLAGS_REG))]
9259   "TARGET_64BIT"
9260   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9261
9262 (define_insn "*xordi_1_rex64"
9263   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9264         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9265                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9266    (clobber (reg:CC FLAGS_REG))]
9267   "TARGET_64BIT
9268    && ix86_binary_operator_ok (XOR, DImode, operands)"
9269   "@
9270    xor{q}\t{%2, %0|%0, %2}
9271    xor{q}\t{%2, %0|%0, %2}"
9272   [(set_attr "type" "alu")
9273    (set_attr "mode" "DI,DI")])
9274
9275 (define_insn "*xordi_2_rex64"
9276   [(set (reg FLAGS_REG)
9277         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9278                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9279                  (const_int 0)))
9280    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9281         (xor:DI (match_dup 1) (match_dup 2)))]
9282   "TARGET_64BIT
9283    && ix86_match_ccmode (insn, CCNOmode)
9284    && ix86_binary_operator_ok (XOR, DImode, operands)"
9285   "@
9286    xor{q}\t{%2, %0|%0, %2}
9287    xor{q}\t{%2, %0|%0, %2}"
9288   [(set_attr "type" "alu")
9289    (set_attr "mode" "DI,DI")])
9290
9291 (define_insn "*xordi_3_rex64"
9292   [(set (reg FLAGS_REG)
9293         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9294                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9295                  (const_int 0)))
9296    (clobber (match_scratch:DI 0 "=r"))]
9297   "TARGET_64BIT
9298    && ix86_match_ccmode (insn, CCNOmode)
9299    && ix86_binary_operator_ok (XOR, DImode, operands)"
9300   "xor{q}\t{%2, %0|%0, %2}"
9301   [(set_attr "type" "alu")
9302    (set_attr "mode" "DI")])
9303
9304 (define_expand "xorsi3"
9305   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9306         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9307                 (match_operand:SI 2 "general_operand" "")))
9308    (clobber (reg:CC FLAGS_REG))]
9309   ""
9310   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9311
9312 (define_insn "*xorsi_1"
9313   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9314         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9315                 (match_operand:SI 2 "general_operand" "ri,rm")))
9316    (clobber (reg:CC FLAGS_REG))]
9317   "ix86_binary_operator_ok (XOR, SImode, operands)"
9318   "xor{l}\t{%2, %0|%0, %2}"
9319   [(set_attr "type" "alu")
9320    (set_attr "mode" "SI")])
9321
9322 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9323 ;; Add speccase for immediates
9324 (define_insn "*xorsi_1_zext"
9325   [(set (match_operand:DI 0 "register_operand" "=r")
9326         (zero_extend:DI
9327           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9328                   (match_operand:SI 2 "general_operand" "rim"))))
9329    (clobber (reg:CC FLAGS_REG))]
9330   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9331   "xor{l}\t{%2, %k0|%k0, %2}"
9332   [(set_attr "type" "alu")
9333    (set_attr "mode" "SI")])
9334
9335 (define_insn "*xorsi_1_zext_imm"
9336   [(set (match_operand:DI 0 "register_operand" "=r")
9337         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9338                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9339    (clobber (reg:CC FLAGS_REG))]
9340   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9341   "xor{l}\t{%2, %k0|%k0, %2}"
9342   [(set_attr "type" "alu")
9343    (set_attr "mode" "SI")])
9344
9345 (define_insn "*xorsi_2"
9346   [(set (reg FLAGS_REG)
9347         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9348                          (match_operand:SI 2 "general_operand" "rim,ri"))
9349                  (const_int 0)))
9350    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9351         (xor:SI (match_dup 1) (match_dup 2)))]
9352   "ix86_match_ccmode (insn, CCNOmode)
9353    && ix86_binary_operator_ok (XOR, SImode, operands)"
9354   "xor{l}\t{%2, %0|%0, %2}"
9355   [(set_attr "type" "alu")
9356    (set_attr "mode" "SI")])
9357
9358 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9359 ;; ??? Special case for immediate operand is missing - it is tricky.
9360 (define_insn "*xorsi_2_zext"
9361   [(set (reg FLAGS_REG)
9362         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9363                          (match_operand:SI 2 "general_operand" "rim"))
9364                  (const_int 0)))
9365    (set (match_operand:DI 0 "register_operand" "=r")
9366         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9367   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9368    && ix86_binary_operator_ok (XOR, SImode, operands)"
9369   "xor{l}\t{%2, %k0|%k0, %2}"
9370   [(set_attr "type" "alu")
9371    (set_attr "mode" "SI")])
9372
9373 (define_insn "*xorsi_2_zext_imm"
9374   [(set (reg FLAGS_REG)
9375         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9376                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9377                  (const_int 0)))
9378    (set (match_operand:DI 0 "register_operand" "=r")
9379         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9380   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9381    && ix86_binary_operator_ok (XOR, SImode, operands)"
9382   "xor{l}\t{%2, %k0|%k0, %2}"
9383   [(set_attr "type" "alu")
9384    (set_attr "mode" "SI")])
9385
9386 (define_insn "*xorsi_3"
9387   [(set (reg FLAGS_REG)
9388         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9389                          (match_operand:SI 2 "general_operand" "rim"))
9390                  (const_int 0)))
9391    (clobber (match_scratch:SI 0 "=r"))]
9392   "ix86_match_ccmode (insn, CCNOmode)
9393    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9394   "xor{l}\t{%2, %0|%0, %2}"
9395   [(set_attr "type" "alu")
9396    (set_attr "mode" "SI")])
9397
9398 (define_expand "xorhi3"
9399   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9400         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9401                 (match_operand:HI 2 "general_operand" "")))
9402    (clobber (reg:CC FLAGS_REG))]
9403   "TARGET_HIMODE_MATH"
9404   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9405
9406 (define_insn "*xorhi_1"
9407   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9408         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9409                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9410    (clobber (reg:CC FLAGS_REG))]
9411   "ix86_binary_operator_ok (XOR, HImode, operands)"
9412   "xor{w}\t{%2, %0|%0, %2}"
9413   [(set_attr "type" "alu")
9414    (set_attr "mode" "HI")])
9415
9416 (define_insn "*xorhi_2"
9417   [(set (reg FLAGS_REG)
9418         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9419                          (match_operand:HI 2 "general_operand" "rim,ri"))
9420                  (const_int 0)))
9421    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9422         (xor:HI (match_dup 1) (match_dup 2)))]
9423   "ix86_match_ccmode (insn, CCNOmode)
9424    && ix86_binary_operator_ok (XOR, HImode, operands)"
9425   "xor{w}\t{%2, %0|%0, %2}"
9426   [(set_attr "type" "alu")
9427    (set_attr "mode" "HI")])
9428
9429 (define_insn "*xorhi_3"
9430   [(set (reg FLAGS_REG)
9431         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9432                          (match_operand:HI 2 "general_operand" "rim"))
9433                  (const_int 0)))
9434    (clobber (match_scratch:HI 0 "=r"))]
9435   "ix86_match_ccmode (insn, CCNOmode)
9436    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9437   "xor{w}\t{%2, %0|%0, %2}"
9438   [(set_attr "type" "alu")
9439    (set_attr "mode" "HI")])
9440
9441 (define_expand "xorqi3"
9442   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9443         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9444                 (match_operand:QI 2 "general_operand" "")))
9445    (clobber (reg:CC FLAGS_REG))]
9446   "TARGET_QIMODE_MATH"
9447   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9448
9449 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9450 (define_insn "*xorqi_1"
9451   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9452         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9453                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9454    (clobber (reg:CC FLAGS_REG))]
9455   "ix86_binary_operator_ok (XOR, QImode, operands)"
9456   "@
9457    xor{b}\t{%2, %0|%0, %2}
9458    xor{b}\t{%2, %0|%0, %2}
9459    xor{l}\t{%k2, %k0|%k0, %k2}"
9460   [(set_attr "type" "alu")
9461    (set_attr "mode" "QI,QI,SI")])
9462
9463 (define_insn "*xorqi_1_slp"
9464   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9465         (xor:QI (match_dup 0)
9466                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9467    (clobber (reg:CC FLAGS_REG))]
9468   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9469    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9470   "xor{b}\t{%1, %0|%0, %1}"
9471   [(set_attr "type" "alu1")
9472    (set_attr "mode" "QI")])
9473
9474 (define_insn "xorqi_ext_0"
9475   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9476                          (const_int 8)
9477                          (const_int 8))
9478         (xor:SI
9479           (zero_extract:SI
9480             (match_operand 1 "ext_register_operand" "0")
9481             (const_int 8)
9482             (const_int 8))
9483           (match_operand 2 "const_int_operand" "n")))
9484    (clobber (reg:CC FLAGS_REG))]
9485   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9486   "xor{b}\t{%2, %h0|%h0, %2}"
9487   [(set_attr "type" "alu")
9488    (set_attr "length_immediate" "1")
9489    (set_attr "mode" "QI")])
9490
9491 (define_insn "*xorqi_ext_1"
9492   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9493                          (const_int 8)
9494                          (const_int 8))
9495         (xor:SI
9496           (zero_extract:SI
9497             (match_operand 1 "ext_register_operand" "0")
9498             (const_int 8)
9499             (const_int 8))
9500           (zero_extend:SI
9501             (match_operand:QI 2 "general_operand" "Qm"))))
9502    (clobber (reg:CC FLAGS_REG))]
9503   "!TARGET_64BIT
9504    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9505   "xor{b}\t{%2, %h0|%h0, %2}"
9506   [(set_attr "type" "alu")
9507    (set_attr "length_immediate" "0")
9508    (set_attr "mode" "QI")])
9509
9510 (define_insn "*xorqi_ext_1_rex64"
9511   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9512                          (const_int 8)
9513                          (const_int 8))
9514         (xor:SI
9515           (zero_extract:SI
9516             (match_operand 1 "ext_register_operand" "0")
9517             (const_int 8)
9518             (const_int 8))
9519           (zero_extend:SI
9520             (match_operand 2 "ext_register_operand" "Q"))))
9521    (clobber (reg:CC FLAGS_REG))]
9522   "TARGET_64BIT
9523    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9524   "xor{b}\t{%2, %h0|%h0, %2}"
9525   [(set_attr "type" "alu")
9526    (set_attr "length_immediate" "0")
9527    (set_attr "mode" "QI")])
9528
9529 (define_insn "*xorqi_ext_2"
9530   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9531                          (const_int 8)
9532                          (const_int 8))
9533         (xor:SI
9534           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9535                            (const_int 8)
9536                            (const_int 8))
9537           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9538                            (const_int 8)
9539                            (const_int 8))))
9540    (clobber (reg:CC FLAGS_REG))]
9541   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9542   "xor{b}\t{%h2, %h0|%h0, %h2}"
9543   [(set_attr "type" "alu")
9544    (set_attr "length_immediate" "0")
9545    (set_attr "mode" "QI")])
9546
9547 (define_insn "*xorqi_cc_1"
9548   [(set (reg FLAGS_REG)
9549         (compare
9550           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9551                   (match_operand:QI 2 "general_operand" "qim,qi"))
9552           (const_int 0)))
9553    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9554         (xor:QI (match_dup 1) (match_dup 2)))]
9555   "ix86_match_ccmode (insn, CCNOmode)
9556    && ix86_binary_operator_ok (XOR, QImode, operands)"
9557   "xor{b}\t{%2, %0|%0, %2}"
9558   [(set_attr "type" "alu")
9559    (set_attr "mode" "QI")])
9560
9561 (define_insn "*xorqi_2_slp"
9562   [(set (reg FLAGS_REG)
9563         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9564                          (match_operand:QI 1 "general_operand" "qim,qi"))
9565                  (const_int 0)))
9566    (set (strict_low_part (match_dup 0))
9567         (xor:QI (match_dup 0) (match_dup 1)))]
9568   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9569    && ix86_match_ccmode (insn, CCNOmode)
9570    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9571   "xor{b}\t{%1, %0|%0, %1}"
9572   [(set_attr "type" "alu1")
9573    (set_attr "mode" "QI")])
9574
9575 (define_insn "*xorqi_cc_2"
9576   [(set (reg FLAGS_REG)
9577         (compare
9578           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9579                   (match_operand:QI 2 "general_operand" "qim"))
9580           (const_int 0)))
9581    (clobber (match_scratch:QI 0 "=q"))]
9582   "ix86_match_ccmode (insn, CCNOmode)
9583    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9584   "xor{b}\t{%2, %0|%0, %2}"
9585   [(set_attr "type" "alu")
9586    (set_attr "mode" "QI")])
9587
9588 (define_insn "*xorqi_cc_ext_1"
9589   [(set (reg FLAGS_REG)
9590         (compare
9591           (xor:SI
9592             (zero_extract:SI
9593               (match_operand 1 "ext_register_operand" "0")
9594               (const_int 8)
9595               (const_int 8))
9596             (match_operand:QI 2 "general_operand" "qmn"))
9597           (const_int 0)))
9598    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9599                          (const_int 8)
9600                          (const_int 8))
9601         (xor:SI
9602           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9603           (match_dup 2)))]
9604   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9605   "xor{b}\t{%2, %h0|%h0, %2}"
9606   [(set_attr "type" "alu")
9607    (set_attr "mode" "QI")])
9608
9609 (define_insn "*xorqi_cc_ext_1_rex64"
9610   [(set (reg FLAGS_REG)
9611         (compare
9612           (xor:SI
9613             (zero_extract:SI
9614               (match_operand 1 "ext_register_operand" "0")
9615               (const_int 8)
9616               (const_int 8))
9617             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9618           (const_int 0)))
9619    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
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   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9626   "xor{b}\t{%2, %h0|%h0, %2}"
9627   [(set_attr "type" "alu")
9628    (set_attr "mode" "QI")])
9629
9630 (define_expand "xorqi_cc_ext_1"
9631   [(parallel [
9632      (set (reg:CCNO FLAGS_REG)
9633           (compare:CCNO
9634             (xor:SI
9635               (zero_extract:SI
9636                 (match_operand 1 "ext_register_operand" "")
9637                 (const_int 8)
9638                 (const_int 8))
9639               (match_operand:QI 2 "general_operand" ""))
9640             (const_int 0)))
9641      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9642                            (const_int 8)
9643                            (const_int 8))
9644           (xor:SI
9645             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9646             (match_dup 2)))])]
9647   ""
9648   "")
9649
9650 (define_split
9651   [(set (match_operand 0 "register_operand" "")
9652         (xor (match_operand 1 "register_operand" "")
9653              (match_operand 2 "const_int_operand" "")))
9654    (clobber (reg:CC FLAGS_REG))]
9655    "reload_completed
9656     && QI_REG_P (operands[0])
9657     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9658     && !(INTVAL (operands[2]) & ~(255 << 8))
9659     && GET_MODE (operands[0]) != QImode"
9660   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9661                    (xor:SI (zero_extract:SI (match_dup 1)
9662                                             (const_int 8) (const_int 8))
9663                            (match_dup 2)))
9664               (clobber (reg:CC FLAGS_REG))])]
9665   "operands[0] = gen_lowpart (SImode, operands[0]);
9666    operands[1] = gen_lowpart (SImode, operands[1]);
9667    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9668
9669 ;; Since XOR can be encoded with sign extended immediate, this is only
9670 ;; profitable when 7th bit is set.
9671 (define_split
9672   [(set (match_operand 0 "register_operand" "")
9673         (xor (match_operand 1 "general_operand" "")
9674              (match_operand 2 "const_int_operand" "")))
9675    (clobber (reg:CC FLAGS_REG))]
9676    "reload_completed
9677     && ANY_QI_REG_P (operands[0])
9678     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9679     && !(INTVAL (operands[2]) & ~255)
9680     && (INTVAL (operands[2]) & 128)
9681     && GET_MODE (operands[0]) != QImode"
9682   [(parallel [(set (strict_low_part (match_dup 0))
9683                    (xor:QI (match_dup 1)
9684                            (match_dup 2)))
9685               (clobber (reg:CC FLAGS_REG))])]
9686   "operands[0] = gen_lowpart (QImode, operands[0]);
9687    operands[1] = gen_lowpart (QImode, operands[1]);
9688    operands[2] = gen_lowpart (QImode, operands[2]);")
9689 \f
9690 ;; Negation instructions
9691
9692 (define_expand "negti2"
9693   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9694                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9695               (clobber (reg:CC FLAGS_REG))])]
9696   "TARGET_64BIT"
9697   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9698
9699 (define_insn "*negti2_1"
9700   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9701         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9702    (clobber (reg:CC FLAGS_REG))]
9703   "TARGET_64BIT
9704    && ix86_unary_operator_ok (NEG, TImode, operands)"
9705   "#")
9706
9707 (define_split
9708   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9709         (neg:TI (match_operand:TI 1 "general_operand" "")))
9710    (clobber (reg:CC FLAGS_REG))]
9711   "TARGET_64BIT && reload_completed"
9712   [(parallel
9713     [(set (reg:CCZ FLAGS_REG)
9714           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9715      (set (match_dup 0) (neg:DI (match_dup 2)))])
9716    (parallel
9717     [(set (match_dup 1)
9718           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9719                             (match_dup 3))
9720                    (const_int 0)))
9721      (clobber (reg:CC FLAGS_REG))])
9722    (parallel
9723     [(set (match_dup 1)
9724           (neg:DI (match_dup 1)))
9725      (clobber (reg:CC FLAGS_REG))])]
9726   "split_ti (operands+1, 1, operands+2, operands+3);
9727    split_ti (operands+0, 1, operands+0, operands+1);")
9728
9729 (define_expand "negdi2"
9730   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9731                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9732               (clobber (reg:CC FLAGS_REG))])]
9733   ""
9734   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9735
9736 (define_insn "*negdi2_1"
9737   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9738         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9739    (clobber (reg:CC FLAGS_REG))]
9740   "!TARGET_64BIT
9741    && ix86_unary_operator_ok (NEG, DImode, operands)"
9742   "#")
9743
9744 (define_split
9745   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9746         (neg:DI (match_operand:DI 1 "general_operand" "")))
9747    (clobber (reg:CC FLAGS_REG))]
9748   "!TARGET_64BIT && reload_completed"
9749   [(parallel
9750     [(set (reg:CCZ FLAGS_REG)
9751           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9752      (set (match_dup 0) (neg:SI (match_dup 2)))])
9753    (parallel
9754     [(set (match_dup 1)
9755           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9756                             (match_dup 3))
9757                    (const_int 0)))
9758      (clobber (reg:CC FLAGS_REG))])
9759    (parallel
9760     [(set (match_dup 1)
9761           (neg:SI (match_dup 1)))
9762      (clobber (reg:CC FLAGS_REG))])]
9763   "split_di (operands+1, 1, operands+2, operands+3);
9764    split_di (operands+0, 1, operands+0, operands+1);")
9765
9766 (define_insn "*negdi2_1_rex64"
9767   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9768         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9769    (clobber (reg:CC FLAGS_REG))]
9770   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9771   "neg{q}\t%0"
9772   [(set_attr "type" "negnot")
9773    (set_attr "mode" "DI")])
9774
9775 ;; The problem with neg is that it does not perform (compare x 0),
9776 ;; it really performs (compare 0 x), which leaves us with the zero
9777 ;; flag being the only useful item.
9778
9779 (define_insn "*negdi2_cmpz_rex64"
9780   [(set (reg:CCZ FLAGS_REG)
9781         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9782                      (const_int 0)))
9783    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9784         (neg:DI (match_dup 1)))]
9785   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9786   "neg{q}\t%0"
9787   [(set_attr "type" "negnot")
9788    (set_attr "mode" "DI")])
9789
9790
9791 (define_expand "negsi2"
9792   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9793                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9794               (clobber (reg:CC FLAGS_REG))])]
9795   ""
9796   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9797
9798 (define_insn "*negsi2_1"
9799   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9800         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9801    (clobber (reg:CC FLAGS_REG))]
9802   "ix86_unary_operator_ok (NEG, SImode, operands)"
9803   "neg{l}\t%0"
9804   [(set_attr "type" "negnot")
9805    (set_attr "mode" "SI")])
9806
9807 ;; Combine is quite creative about this pattern.
9808 (define_insn "*negsi2_1_zext"
9809   [(set (match_operand:DI 0 "register_operand" "=r")
9810         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9811                                         (const_int 32)))
9812                      (const_int 32)))
9813    (clobber (reg:CC FLAGS_REG))]
9814   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9815   "neg{l}\t%k0"
9816   [(set_attr "type" "negnot")
9817    (set_attr "mode" "SI")])
9818
9819 ;; The problem with neg is that it does not perform (compare x 0),
9820 ;; it really performs (compare 0 x), which leaves us with the zero
9821 ;; flag being the only useful item.
9822
9823 (define_insn "*negsi2_cmpz"
9824   [(set (reg:CCZ FLAGS_REG)
9825         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9826                      (const_int 0)))
9827    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9828         (neg:SI (match_dup 1)))]
9829   "ix86_unary_operator_ok (NEG, SImode, operands)"
9830   "neg{l}\t%0"
9831   [(set_attr "type" "negnot")
9832    (set_attr "mode" "SI")])
9833
9834 (define_insn "*negsi2_cmpz_zext"
9835   [(set (reg:CCZ FLAGS_REG)
9836         (compare:CCZ (lshiftrt:DI
9837                        (neg:DI (ashift:DI
9838                                  (match_operand:DI 1 "register_operand" "0")
9839                                  (const_int 32)))
9840                        (const_int 32))
9841                      (const_int 0)))
9842    (set (match_operand:DI 0 "register_operand" "=r")
9843         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9844                                         (const_int 32)))
9845                      (const_int 32)))]
9846   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9847   "neg{l}\t%k0"
9848   [(set_attr "type" "negnot")
9849    (set_attr "mode" "SI")])
9850
9851 (define_expand "neghi2"
9852   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9853                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9854               (clobber (reg:CC FLAGS_REG))])]
9855   "TARGET_HIMODE_MATH"
9856   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9857
9858 (define_insn "*neghi2_1"
9859   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9860         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9861    (clobber (reg:CC FLAGS_REG))]
9862   "ix86_unary_operator_ok (NEG, HImode, operands)"
9863   "neg{w}\t%0"
9864   [(set_attr "type" "negnot")
9865    (set_attr "mode" "HI")])
9866
9867 (define_insn "*neghi2_cmpz"
9868   [(set (reg:CCZ FLAGS_REG)
9869         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9870                      (const_int 0)))
9871    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9872         (neg:HI (match_dup 1)))]
9873   "ix86_unary_operator_ok (NEG, HImode, operands)"
9874   "neg{w}\t%0"
9875   [(set_attr "type" "negnot")
9876    (set_attr "mode" "HI")])
9877
9878 (define_expand "negqi2"
9879   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9880                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9881               (clobber (reg:CC FLAGS_REG))])]
9882   "TARGET_QIMODE_MATH"
9883   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9884
9885 (define_insn "*negqi2_1"
9886   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9887         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9888    (clobber (reg:CC FLAGS_REG))]
9889   "ix86_unary_operator_ok (NEG, QImode, operands)"
9890   "neg{b}\t%0"
9891   [(set_attr "type" "negnot")
9892    (set_attr "mode" "QI")])
9893
9894 (define_insn "*negqi2_cmpz"
9895   [(set (reg:CCZ FLAGS_REG)
9896         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9897                      (const_int 0)))
9898    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9899         (neg:QI (match_dup 1)))]
9900   "ix86_unary_operator_ok (NEG, QImode, operands)"
9901   "neg{b}\t%0"
9902   [(set_attr "type" "negnot")
9903    (set_attr "mode" "QI")])
9904
9905 ;; Changing of sign for FP values is doable using integer unit too.
9906
9907 (define_expand "negsf2"
9908   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9909         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9910   "TARGET_80387 || TARGET_SSE_MATH"
9911   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9912
9913 (define_expand "abssf2"
9914   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9915         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9916   "TARGET_80387 || TARGET_SSE_MATH"
9917   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9918
9919 (define_insn "*absnegsf2_mixed"
9920   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9921         (match_operator:SF 3 "absneg_operator"
9922           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9923    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9924    (clobber (reg:CC FLAGS_REG))]
9925   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9926    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9927   "#")
9928
9929 (define_insn "*absnegsf2_sse"
9930   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9931         (match_operator:SF 3 "absneg_operator"
9932           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9933    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9934    (clobber (reg:CC FLAGS_REG))]
9935   "TARGET_SSE_MATH
9936    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9937   "#")
9938
9939 (define_insn "*absnegsf2_i387"
9940   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9941         (match_operator:SF 3 "absneg_operator"
9942           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9943    (use (match_operand 2 "" ""))
9944    (clobber (reg:CC FLAGS_REG))]
9945   "TARGET_80387 && !TARGET_SSE_MATH
9946    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9947   "#")
9948
9949 (define_expand "copysignsf3"
9950   [(match_operand:SF 0 "register_operand" "")
9951    (match_operand:SF 1 "nonmemory_operand" "")
9952    (match_operand:SF 2 "register_operand" "")]
9953   "TARGET_SSE_MATH"
9954 {
9955   ix86_expand_copysign (operands);
9956   DONE;
9957 })
9958
9959 (define_insn_and_split "copysignsf3_const"
9960   [(set (match_operand:SF 0 "register_operand"          "=x")
9961         (unspec:SF
9962           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9963            (match_operand:SF 2 "register_operand"       "0")
9964            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9965           UNSPEC_COPYSIGN))]
9966   "TARGET_SSE_MATH"
9967   "#"
9968   "&& reload_completed"
9969   [(const_int 0)]
9970 {
9971   ix86_split_copysign_const (operands);
9972   DONE;
9973 })
9974
9975 (define_insn "copysignsf3_var"
9976   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9977         (unspec:SF
9978           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9979            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9980            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9981            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9982           UNSPEC_COPYSIGN))
9983    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9984   "TARGET_SSE_MATH"
9985   "#")
9986
9987 (define_split
9988   [(set (match_operand:SF 0 "register_operand" "")
9989         (unspec:SF
9990           [(match_operand:SF 2 "register_operand" "")
9991            (match_operand:SF 3 "register_operand" "")
9992            (match_operand:V4SF 4 "" "")
9993            (match_operand:V4SF 5 "" "")]
9994           UNSPEC_COPYSIGN))
9995    (clobber (match_scratch:V4SF 1 ""))]
9996   "TARGET_SSE_MATH && reload_completed"
9997   [(const_int 0)]
9998 {
9999   ix86_split_copysign_var (operands);
10000   DONE;
10001 })
10002
10003 (define_expand "negdf2"
10004   [(set (match_operand:DF 0 "nonimmediate_operand" "")
10005         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
10006   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
10007   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
10008
10009 (define_expand "absdf2"
10010   [(set (match_operand:DF 0 "nonimmediate_operand" "")
10011         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
10012   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
10013   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
10014
10015 (define_insn "*absnegdf2_mixed"
10016   [(set (match_operand:DF 0 "nonimmediate_operand"    "=x,x,f,rm")
10017         (match_operator:DF 3 "absneg_operator"
10018           [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0,0")]))
10019    (use (match_operand:V2DF 2 "nonimmediate_operand"  "xm,0,X,X"))
10020    (clobber (reg:CC FLAGS_REG))]
10021   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
10022    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10023   "#")
10024
10025 (define_insn "*absnegdf2_sse"
10026   [(set (match_operand:DF 0 "nonimmediate_operand"    "=x,x,rm")
10027         (match_operator:DF 3 "absneg_operator"
10028           [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0 ")]))
10029    (use (match_operand:V2DF 2 "nonimmediate_operand"  "xm,0,X "))
10030    (clobber (reg:CC FLAGS_REG))]
10031   "TARGET_SSE2 && TARGET_SSE_MATH
10032    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10033   "#")
10034
10035 (define_insn "*absnegdf2_i387"
10036   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
10037         (match_operator:DF 3 "absneg_operator"
10038           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
10039    (use (match_operand 2 "" ""))
10040    (clobber (reg:CC FLAGS_REG))]
10041   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
10042    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10043   "#")
10044
10045 (define_expand "copysigndf3"
10046   [(match_operand:DF 0 "register_operand" "")
10047    (match_operand:DF 1 "nonmemory_operand" "")
10048    (match_operand:DF 2 "register_operand" "")]
10049   "TARGET_SSE2 && TARGET_SSE_MATH"
10050 {
10051   ix86_expand_copysign (operands);
10052   DONE;
10053 })
10054
10055 (define_insn_and_split "copysigndf3_const"
10056   [(set (match_operand:DF 0 "register_operand"          "=x")
10057         (unspec:DF
10058           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
10059            (match_operand:DF 2 "register_operand"       "0")
10060            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
10061           UNSPEC_COPYSIGN))]
10062   "TARGET_SSE2 && TARGET_SSE_MATH"
10063   "#"
10064   "&& reload_completed"
10065   [(const_int 0)]
10066 {
10067   ix86_split_copysign_const (operands);
10068   DONE;
10069 })
10070
10071 (define_insn "copysigndf3_var"
10072   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
10073         (unspec:DF
10074           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
10075            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
10076            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
10077            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
10078           UNSPEC_COPYSIGN))
10079    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
10080   "TARGET_SSE2 && TARGET_SSE_MATH"
10081   "#")
10082
10083 (define_split
10084   [(set (match_operand:DF 0 "register_operand" "")
10085         (unspec:DF
10086           [(match_operand:DF 2 "register_operand" "")
10087            (match_operand:DF 3 "register_operand" "")
10088            (match_operand:V2DF 4 "" "")
10089            (match_operand:V2DF 5 "" "")]
10090           UNSPEC_COPYSIGN))
10091    (clobber (match_scratch:V2DF 1 ""))]
10092   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
10093   [(const_int 0)]
10094 {
10095   ix86_split_copysign_var (operands);
10096   DONE;
10097 })
10098
10099 (define_expand "negxf2"
10100   [(set (match_operand:XF 0 "nonimmediate_operand" "")
10101         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10102   "TARGET_80387"
10103   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
10104
10105 (define_expand "absxf2"
10106   [(set (match_operand:XF 0 "nonimmediate_operand" "")
10107         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10108   "TARGET_80387"
10109   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
10110
10111 (define_insn "*absnegxf2_i387"
10112   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
10113         (match_operator:XF 3 "absneg_operator"
10114           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
10115    (use (match_operand 2 "" ""))
10116    (clobber (reg:CC FLAGS_REG))]
10117   "TARGET_80387
10118    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
10119   "#")
10120
10121 ;; Splitters for fp abs and neg.
10122
10123 (define_split
10124   [(set (match_operand 0 "fp_register_operand" "")
10125         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10126    (use (match_operand 2 "" ""))
10127    (clobber (reg:CC FLAGS_REG))]
10128   "reload_completed"
10129   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10130
10131 (define_split
10132   [(set (match_operand 0 "register_operand" "")
10133         (match_operator 3 "absneg_operator"
10134           [(match_operand 1 "register_operand" "")]))
10135    (use (match_operand 2 "nonimmediate_operand" ""))
10136    (clobber (reg:CC FLAGS_REG))]
10137   "reload_completed && SSE_REG_P (operands[0])"
10138   [(set (match_dup 0) (match_dup 3))]
10139 {
10140   enum machine_mode mode = GET_MODE (operands[0]);
10141   enum machine_mode vmode = GET_MODE (operands[2]);
10142   rtx tmp;
10143
10144   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10145   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10146   if (operands_match_p (operands[0], operands[2]))
10147     {
10148       tmp = operands[1];
10149       operands[1] = operands[2];
10150       operands[2] = tmp;
10151     }
10152   if (GET_CODE (operands[3]) == ABS)
10153     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10154   else
10155     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10156   operands[3] = tmp;
10157 })
10158
10159 (define_split
10160   [(set (match_operand:SF 0 "register_operand" "")
10161         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10162    (use (match_operand:V4SF 2 "" ""))
10163    (clobber (reg:CC FLAGS_REG))]
10164   "reload_completed"
10165   [(parallel [(set (match_dup 0) (match_dup 1))
10166               (clobber (reg:CC FLAGS_REG))])]
10167 {
10168   rtx tmp;
10169   operands[0] = gen_lowpart (SImode, operands[0]);
10170   if (GET_CODE (operands[1]) == ABS)
10171     {
10172       tmp = gen_int_mode (0x7fffffff, SImode);
10173       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10174     }
10175   else
10176     {
10177       tmp = gen_int_mode (0x80000000, SImode);
10178       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10179     }
10180   operands[1] = tmp;
10181 })
10182
10183 (define_split
10184   [(set (match_operand:DF 0 "register_operand" "")
10185         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10186    (use (match_operand 2 "" ""))
10187    (clobber (reg:CC FLAGS_REG))]
10188   "reload_completed"
10189   [(parallel [(set (match_dup 0) (match_dup 1))
10190               (clobber (reg:CC FLAGS_REG))])]
10191 {
10192   rtx tmp;
10193   if (TARGET_64BIT)
10194     {
10195       tmp = gen_lowpart (DImode, operands[0]);
10196       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10197       operands[0] = tmp;
10198
10199       if (GET_CODE (operands[1]) == ABS)
10200         tmp = const0_rtx;
10201       else
10202         tmp = gen_rtx_NOT (DImode, tmp);
10203     }
10204   else
10205     {
10206       operands[0] = gen_highpart (SImode, operands[0]);
10207       if (GET_CODE (operands[1]) == ABS)
10208         {
10209           tmp = gen_int_mode (0x7fffffff, SImode);
10210           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10211         }
10212       else
10213         {
10214           tmp = gen_int_mode (0x80000000, SImode);
10215           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10216         }
10217     }
10218   operands[1] = tmp;
10219 })
10220
10221 (define_split
10222   [(set (match_operand:XF 0 "register_operand" "")
10223         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10224    (use (match_operand 2 "" ""))
10225    (clobber (reg:CC FLAGS_REG))]
10226   "reload_completed"
10227   [(parallel [(set (match_dup 0) (match_dup 1))
10228               (clobber (reg:CC FLAGS_REG))])]
10229 {
10230   rtx tmp;
10231   operands[0] = gen_rtx_REG (SImode,
10232                              true_regnum (operands[0])
10233                              + (TARGET_64BIT ? 1 : 2));
10234   if (GET_CODE (operands[1]) == ABS)
10235     {
10236       tmp = GEN_INT (0x7fff);
10237       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10238     }
10239   else
10240     {
10241       tmp = GEN_INT (0x8000);
10242       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10243     }
10244   operands[1] = tmp;
10245 })
10246
10247 (define_split
10248   [(set (match_operand 0 "memory_operand" "")
10249         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10250    (use (match_operand 2 "" ""))
10251    (clobber (reg:CC FLAGS_REG))]
10252   "reload_completed"
10253   [(parallel [(set (match_dup 0) (match_dup 1))
10254               (clobber (reg:CC FLAGS_REG))])]
10255 {
10256   enum machine_mode mode = GET_MODE (operands[0]);
10257   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
10258   rtx tmp;
10259
10260   operands[0] = adjust_address (operands[0], QImode, size - 1);
10261   if (GET_CODE (operands[1]) == ABS)
10262     {
10263       tmp = gen_int_mode (0x7f, QImode);
10264       tmp = gen_rtx_AND (QImode, operands[0], tmp);
10265     }
10266   else
10267     {
10268       tmp = gen_int_mode (0x80, QImode);
10269       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
10270     }
10271   operands[1] = tmp;
10272 })
10273
10274 ;; Conditionalize these after reload. If they match before reload, we
10275 ;; lose the clobber and ability to use integer instructions.
10276
10277 (define_insn "*negsf2_1"
10278   [(set (match_operand:SF 0 "register_operand" "=f")
10279         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10280   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10281   "fchs"
10282   [(set_attr "type" "fsgn")
10283    (set_attr "mode" "SF")])
10284
10285 (define_insn "*negdf2_1"
10286   [(set (match_operand:DF 0 "register_operand" "=f")
10287         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10288   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10289   "fchs"
10290   [(set_attr "type" "fsgn")
10291    (set_attr "mode" "DF")])
10292
10293 (define_insn "*negxf2_1"
10294   [(set (match_operand:XF 0 "register_operand" "=f")
10295         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10296   "TARGET_80387"
10297   "fchs"
10298   [(set_attr "type" "fsgn")
10299    (set_attr "mode" "XF")])
10300
10301 (define_insn "*abssf2_1"
10302   [(set (match_operand:SF 0 "register_operand" "=f")
10303         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10304   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10305   "fabs"
10306   [(set_attr "type" "fsgn")
10307    (set_attr "mode" "SF")])
10308
10309 (define_insn "*absdf2_1"
10310   [(set (match_operand:DF 0 "register_operand" "=f")
10311         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10312   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10313   "fabs"
10314   [(set_attr "type" "fsgn")
10315    (set_attr "mode" "DF")])
10316
10317 (define_insn "*absxf2_1"
10318   [(set (match_operand:XF 0 "register_operand" "=f")
10319         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10320   "TARGET_80387"
10321   "fabs"
10322   [(set_attr "type" "fsgn")
10323    (set_attr "mode" "DF")])
10324
10325 (define_insn "*negextendsfdf2"
10326   [(set (match_operand:DF 0 "register_operand" "=f")
10327         (neg:DF (float_extend:DF
10328                   (match_operand:SF 1 "register_operand" "0"))))]
10329   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10330   "fchs"
10331   [(set_attr "type" "fsgn")
10332    (set_attr "mode" "DF")])
10333
10334 (define_insn "*negextenddfxf2"
10335   [(set (match_operand:XF 0 "register_operand" "=f")
10336         (neg:XF (float_extend:XF
10337                   (match_operand:DF 1 "register_operand" "0"))))]
10338   "TARGET_80387"
10339   "fchs"
10340   [(set_attr "type" "fsgn")
10341    (set_attr "mode" "XF")])
10342
10343 (define_insn "*negextendsfxf2"
10344   [(set (match_operand:XF 0 "register_operand" "=f")
10345         (neg:XF (float_extend:XF
10346                   (match_operand:SF 1 "register_operand" "0"))))]
10347   "TARGET_80387"
10348   "fchs"
10349   [(set_attr "type" "fsgn")
10350    (set_attr "mode" "XF")])
10351
10352 (define_insn "*absextendsfdf2"
10353   [(set (match_operand:DF 0 "register_operand" "=f")
10354         (abs:DF (float_extend:DF
10355                   (match_operand:SF 1 "register_operand" "0"))))]
10356   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10357   "fabs"
10358   [(set_attr "type" "fsgn")
10359    (set_attr "mode" "DF")])
10360
10361 (define_insn "*absextenddfxf2"
10362   [(set (match_operand:XF 0 "register_operand" "=f")
10363         (abs:XF (float_extend:XF
10364           (match_operand:DF 1 "register_operand" "0"))))]
10365   "TARGET_80387"
10366   "fabs"
10367   [(set_attr "type" "fsgn")
10368    (set_attr "mode" "XF")])
10369
10370 (define_insn "*absextendsfxf2"
10371   [(set (match_operand:XF 0 "register_operand" "=f")
10372         (abs:XF (float_extend:XF
10373           (match_operand:SF 1 "register_operand" "0"))))]
10374   "TARGET_80387"
10375   "fabs"
10376   [(set_attr "type" "fsgn")
10377    (set_attr "mode" "XF")])
10378 \f
10379 ;; One complement instructions
10380
10381 (define_expand "one_cmpldi2"
10382   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10383         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10384   "TARGET_64BIT"
10385   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10386
10387 (define_insn "*one_cmpldi2_1_rex64"
10388   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10389         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10390   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10391   "not{q}\t%0"
10392   [(set_attr "type" "negnot")
10393    (set_attr "mode" "DI")])
10394
10395 (define_insn "*one_cmpldi2_2_rex64"
10396   [(set (reg FLAGS_REG)
10397         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10398                  (const_int 0)))
10399    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10400         (not:DI (match_dup 1)))]
10401   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10402    && ix86_unary_operator_ok (NOT, DImode, operands)"
10403   "#"
10404   [(set_attr "type" "alu1")
10405    (set_attr "mode" "DI")])
10406
10407 (define_split
10408   [(set (match_operand 0 "flags_reg_operand" "")
10409         (match_operator 2 "compare_operator"
10410           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10411            (const_int 0)]))
10412    (set (match_operand:DI 1 "nonimmediate_operand" "")
10413         (not:DI (match_dup 3)))]
10414   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10415   [(parallel [(set (match_dup 0)
10416                    (match_op_dup 2
10417                      [(xor:DI (match_dup 3) (const_int -1))
10418                       (const_int 0)]))
10419               (set (match_dup 1)
10420                    (xor:DI (match_dup 3) (const_int -1)))])]
10421   "")
10422
10423 (define_expand "one_cmplsi2"
10424   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10425         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10426   ""
10427   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10428
10429 (define_insn "*one_cmplsi2_1"
10430   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10431         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10432   "ix86_unary_operator_ok (NOT, SImode, operands)"
10433   "not{l}\t%0"
10434   [(set_attr "type" "negnot")
10435    (set_attr "mode" "SI")])
10436
10437 ;; ??? Currently never generated - xor is used instead.
10438 (define_insn "*one_cmplsi2_1_zext"
10439   [(set (match_operand:DI 0 "register_operand" "=r")
10440         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10441   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10442   "not{l}\t%k0"
10443   [(set_attr "type" "negnot")
10444    (set_attr "mode" "SI")])
10445
10446 (define_insn "*one_cmplsi2_2"
10447   [(set (reg FLAGS_REG)
10448         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10449                  (const_int 0)))
10450    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10451         (not:SI (match_dup 1)))]
10452   "ix86_match_ccmode (insn, CCNOmode)
10453    && ix86_unary_operator_ok (NOT, SImode, operands)"
10454   "#"
10455   [(set_attr "type" "alu1")
10456    (set_attr "mode" "SI")])
10457
10458 (define_split
10459   [(set (match_operand 0 "flags_reg_operand" "")
10460         (match_operator 2 "compare_operator"
10461           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10462            (const_int 0)]))
10463    (set (match_operand:SI 1 "nonimmediate_operand" "")
10464         (not:SI (match_dup 3)))]
10465   "ix86_match_ccmode (insn, CCNOmode)"
10466   [(parallel [(set (match_dup 0)
10467                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10468                                     (const_int 0)]))
10469               (set (match_dup 1)
10470                    (xor:SI (match_dup 3) (const_int -1)))])]
10471   "")
10472
10473 ;; ??? Currently never generated - xor is used instead.
10474 (define_insn "*one_cmplsi2_2_zext"
10475   [(set (reg FLAGS_REG)
10476         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10477                  (const_int 0)))
10478    (set (match_operand:DI 0 "register_operand" "=r")
10479         (zero_extend:DI (not:SI (match_dup 1))))]
10480   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10481    && ix86_unary_operator_ok (NOT, SImode, operands)"
10482   "#"
10483   [(set_attr "type" "alu1")
10484    (set_attr "mode" "SI")])
10485
10486 (define_split
10487   [(set (match_operand 0 "flags_reg_operand" "")
10488         (match_operator 2 "compare_operator"
10489           [(not:SI (match_operand:SI 3 "register_operand" ""))
10490            (const_int 0)]))
10491    (set (match_operand:DI 1 "register_operand" "")
10492         (zero_extend:DI (not:SI (match_dup 3))))]
10493   "ix86_match_ccmode (insn, CCNOmode)"
10494   [(parallel [(set (match_dup 0)
10495                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10496                                     (const_int 0)]))
10497               (set (match_dup 1)
10498                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10499   "")
10500
10501 (define_expand "one_cmplhi2"
10502   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10503         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10504   "TARGET_HIMODE_MATH"
10505   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10506
10507 (define_insn "*one_cmplhi2_1"
10508   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10509         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10510   "ix86_unary_operator_ok (NOT, HImode, operands)"
10511   "not{w}\t%0"
10512   [(set_attr "type" "negnot")
10513    (set_attr "mode" "HI")])
10514
10515 (define_insn "*one_cmplhi2_2"
10516   [(set (reg FLAGS_REG)
10517         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10518                  (const_int 0)))
10519    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10520         (not:HI (match_dup 1)))]
10521   "ix86_match_ccmode (insn, CCNOmode)
10522    && ix86_unary_operator_ok (NEG, HImode, operands)"
10523   "#"
10524   [(set_attr "type" "alu1")
10525    (set_attr "mode" "HI")])
10526
10527 (define_split
10528   [(set (match_operand 0 "flags_reg_operand" "")
10529         (match_operator 2 "compare_operator"
10530           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10531            (const_int 0)]))
10532    (set (match_operand:HI 1 "nonimmediate_operand" "")
10533         (not:HI (match_dup 3)))]
10534   "ix86_match_ccmode (insn, CCNOmode)"
10535   [(parallel [(set (match_dup 0)
10536                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10537                                     (const_int 0)]))
10538               (set (match_dup 1)
10539                    (xor:HI (match_dup 3) (const_int -1)))])]
10540   "")
10541
10542 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10543 (define_expand "one_cmplqi2"
10544   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10545         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10546   "TARGET_QIMODE_MATH"
10547   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10548
10549 (define_insn "*one_cmplqi2_1"
10550   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10551         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10552   "ix86_unary_operator_ok (NOT, QImode, operands)"
10553   "@
10554    not{b}\t%0
10555    not{l}\t%k0"
10556   [(set_attr "type" "negnot")
10557    (set_attr "mode" "QI,SI")])
10558
10559 (define_insn "*one_cmplqi2_2"
10560   [(set (reg FLAGS_REG)
10561         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10562                  (const_int 0)))
10563    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10564         (not:QI (match_dup 1)))]
10565   "ix86_match_ccmode (insn, CCNOmode)
10566    && ix86_unary_operator_ok (NOT, QImode, operands)"
10567   "#"
10568   [(set_attr "type" "alu1")
10569    (set_attr "mode" "QI")])
10570
10571 (define_split
10572   [(set (match_operand 0 "flags_reg_operand" "")
10573         (match_operator 2 "compare_operator"
10574           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10575            (const_int 0)]))
10576    (set (match_operand:QI 1 "nonimmediate_operand" "")
10577         (not:QI (match_dup 3)))]
10578   "ix86_match_ccmode (insn, CCNOmode)"
10579   [(parallel [(set (match_dup 0)
10580                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10581                                     (const_int 0)]))
10582               (set (match_dup 1)
10583                    (xor:QI (match_dup 3) (const_int -1)))])]
10584   "")
10585 \f
10586 ;; Arithmetic shift instructions
10587
10588 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10589 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10590 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10591 ;; from the assembler input.
10592 ;;
10593 ;; This instruction shifts the target reg/mem as usual, but instead of
10594 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10595 ;; is a left shift double, bits are taken from the high order bits of
10596 ;; reg, else if the insn is a shift right double, bits are taken from the
10597 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10598 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10599 ;;
10600 ;; Since sh[lr]d does not change the `reg' operand, that is done
10601 ;; separately, making all shifts emit pairs of shift double and normal
10602 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10603 ;; support a 63 bit shift, each shift where the count is in a reg expands
10604 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10605 ;;
10606 ;; If the shift count is a constant, we need never emit more than one
10607 ;; shift pair, instead using moves and sign extension for counts greater
10608 ;; than 31.
10609
10610 (define_expand "ashlti3"
10611   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10612                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10613                               (match_operand:QI 2 "nonmemory_operand" "")))
10614               (clobber (reg:CC FLAGS_REG))])]
10615   "TARGET_64BIT"
10616 {
10617   if (! immediate_operand (operands[2], QImode))
10618     {
10619       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10620       DONE;
10621     }
10622   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10623   DONE;
10624 })
10625
10626 (define_insn "ashlti3_1"
10627   [(set (match_operand:TI 0 "register_operand" "=r")
10628         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10629                    (match_operand:QI 2 "register_operand" "c")))
10630    (clobber (match_scratch:DI 3 "=&r"))
10631    (clobber (reg:CC FLAGS_REG))]
10632   "TARGET_64BIT"
10633   "#"
10634   [(set_attr "type" "multi")])
10635
10636 (define_insn "*ashlti3_2"
10637   [(set (match_operand:TI 0 "register_operand" "=r")
10638         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10639                    (match_operand:QI 2 "immediate_operand" "O")))
10640    (clobber (reg:CC FLAGS_REG))]
10641   "TARGET_64BIT"
10642   "#"
10643   [(set_attr "type" "multi")])
10644
10645 (define_split
10646   [(set (match_operand:TI 0 "register_operand" "")
10647         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10648                    (match_operand:QI 2 "register_operand" "")))
10649    (clobber (match_scratch:DI 3 ""))
10650    (clobber (reg:CC FLAGS_REG))]
10651   "TARGET_64BIT && reload_completed"
10652   [(const_int 0)]
10653   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10654
10655 (define_split
10656   [(set (match_operand:TI 0 "register_operand" "")
10657         (ashift:TI (match_operand:TI 1 "register_operand" "")
10658                    (match_operand:QI 2 "immediate_operand" "")))
10659    (clobber (reg:CC FLAGS_REG))]
10660   "TARGET_64BIT && reload_completed"
10661   [(const_int 0)]
10662   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10663
10664 (define_insn "x86_64_shld"
10665   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10666         (ior:DI (ashift:DI (match_dup 0)
10667                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10668                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10669                   (minus:QI (const_int 64) (match_dup 2)))))
10670    (clobber (reg:CC FLAGS_REG))]
10671   "TARGET_64BIT"
10672   "@
10673    shld{q}\t{%2, %1, %0|%0, %1, %2}
10674    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10675   [(set_attr "type" "ishift")
10676    (set_attr "prefix_0f" "1")
10677    (set_attr "mode" "DI")
10678    (set_attr "athlon_decode" "vector")
10679    (set_attr "amdfam10_decode" "vector")])   
10680
10681 (define_expand "x86_64_shift_adj"
10682   [(set (reg:CCZ FLAGS_REG)
10683         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10684                              (const_int 64))
10685                      (const_int 0)))
10686    (set (match_operand:DI 0 "register_operand" "")
10687         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10688                          (match_operand:DI 1 "register_operand" "")
10689                          (match_dup 0)))
10690    (set (match_dup 1)
10691         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10692                          (match_operand:DI 3 "register_operand" "r")
10693                          (match_dup 1)))]
10694   "TARGET_64BIT"
10695   "")
10696
10697 (define_expand "ashldi3"
10698   [(set (match_operand:DI 0 "shiftdi_operand" "")
10699         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10700                    (match_operand:QI 2 "nonmemory_operand" "")))]
10701   ""
10702   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10703
10704 (define_insn "*ashldi3_1_rex64"
10705   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10706         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10707                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10708    (clobber (reg:CC FLAGS_REG))]
10709   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10710 {
10711   switch (get_attr_type (insn))
10712     {
10713     case TYPE_ALU:
10714       gcc_assert (operands[2] == const1_rtx);
10715       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10716       return "add{q}\t%0, %0";
10717
10718     case TYPE_LEA:
10719       gcc_assert (CONST_INT_P (operands[2]));
10720       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10721       operands[1] = gen_rtx_MULT (DImode, operands[1],
10722                                   GEN_INT (1 << INTVAL (operands[2])));
10723       return "lea{q}\t{%a1, %0|%0, %a1}";
10724
10725     default:
10726       if (REG_P (operands[2]))
10727         return "sal{q}\t{%b2, %0|%0, %b2}";
10728       else if (operands[2] == const1_rtx
10729                && (TARGET_SHIFT1 || optimize_size))
10730         return "sal{q}\t%0";
10731       else
10732         return "sal{q}\t{%2, %0|%0, %2}";
10733     }
10734 }
10735   [(set (attr "type")
10736      (cond [(eq_attr "alternative" "1")
10737               (const_string "lea")
10738             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10739                           (const_int 0))
10740                       (match_operand 0 "register_operand" ""))
10741                  (match_operand 2 "const1_operand" ""))
10742               (const_string "alu")
10743            ]
10744            (const_string "ishift")))
10745    (set_attr "mode" "DI")])
10746
10747 ;; Convert lea to the lea pattern to avoid flags dependency.
10748 (define_split
10749   [(set (match_operand:DI 0 "register_operand" "")
10750         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10751                    (match_operand:QI 2 "immediate_operand" "")))
10752    (clobber (reg:CC FLAGS_REG))]
10753   "TARGET_64BIT && reload_completed
10754    && true_regnum (operands[0]) != true_regnum (operands[1])"
10755   [(set (match_dup 0)
10756         (mult:DI (match_dup 1)
10757                  (match_dup 2)))]
10758   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10759
10760 ;; This pattern can't accept a variable shift count, since shifts by
10761 ;; zero don't affect the flags.  We assume that shifts by constant
10762 ;; zero are optimized away.
10763 (define_insn "*ashldi3_cmp_rex64"
10764   [(set (reg FLAGS_REG)
10765         (compare
10766           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10767                      (match_operand:QI 2 "immediate_operand" "e"))
10768           (const_int 0)))
10769    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10770         (ashift:DI (match_dup 1) (match_dup 2)))]
10771   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10772    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10773    && (optimize_size
10774        || !TARGET_PARTIAL_FLAG_REG_STALL
10775        || (operands[2] == const1_rtx
10776            && (TARGET_SHIFT1
10777                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10778 {
10779   switch (get_attr_type (insn))
10780     {
10781     case TYPE_ALU:
10782       gcc_assert (operands[2] == const1_rtx);
10783       return "add{q}\t%0, %0";
10784
10785     default:
10786       if (REG_P (operands[2]))
10787         return "sal{q}\t{%b2, %0|%0, %b2}";
10788       else if (operands[2] == const1_rtx
10789                && (TARGET_SHIFT1 || optimize_size))
10790         return "sal{q}\t%0";
10791       else
10792         return "sal{q}\t{%2, %0|%0, %2}";
10793     }
10794 }
10795   [(set (attr "type")
10796      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10797                           (const_int 0))
10798                       (match_operand 0 "register_operand" ""))
10799                  (match_operand 2 "const1_operand" ""))
10800               (const_string "alu")
10801            ]
10802            (const_string "ishift")))
10803    (set_attr "mode" "DI")])
10804
10805 (define_insn "*ashldi3_cconly_rex64"
10806   [(set (reg FLAGS_REG)
10807         (compare
10808           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10809                      (match_operand:QI 2 "immediate_operand" "e"))
10810           (const_int 0)))
10811    (clobber (match_scratch:DI 0 "=r"))]
10812   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10813    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10814    && (optimize_size
10815        || !TARGET_PARTIAL_FLAG_REG_STALL
10816        || (operands[2] == const1_rtx
10817            && (TARGET_SHIFT1
10818                || TARGET_DOUBLE_WITH_ADD)))"
10819 {
10820   switch (get_attr_type (insn))
10821     {
10822     case TYPE_ALU:
10823       gcc_assert (operands[2] == const1_rtx);
10824       return "add{q}\t%0, %0";
10825
10826     default:
10827       if (REG_P (operands[2]))
10828         return "sal{q}\t{%b2, %0|%0, %b2}";
10829       else if (operands[2] == const1_rtx
10830                && (TARGET_SHIFT1 || optimize_size))
10831         return "sal{q}\t%0";
10832       else
10833         return "sal{q}\t{%2, %0|%0, %2}";
10834     }
10835 }
10836   [(set (attr "type")
10837      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10838                           (const_int 0))
10839                       (match_operand 0 "register_operand" ""))
10840                  (match_operand 2 "const1_operand" ""))
10841               (const_string "alu")
10842            ]
10843            (const_string "ishift")))
10844    (set_attr "mode" "DI")])
10845
10846 (define_insn "*ashldi3_1"
10847   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10848         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10849                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10850    (clobber (reg:CC FLAGS_REG))]
10851   "!TARGET_64BIT"
10852   "#"
10853   [(set_attr "type" "multi")])
10854
10855 ;; By default we don't ask for a scratch register, because when DImode
10856 ;; values are manipulated, registers are already at a premium.  But if
10857 ;; we have one handy, we won't turn it away.
10858 (define_peephole2
10859   [(match_scratch:SI 3 "r")
10860    (parallel [(set (match_operand:DI 0 "register_operand" "")
10861                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10862                               (match_operand:QI 2 "nonmemory_operand" "")))
10863               (clobber (reg:CC FLAGS_REG))])
10864    (match_dup 3)]
10865   "!TARGET_64BIT && TARGET_CMOVE"
10866   [(const_int 0)]
10867   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10868
10869 (define_split
10870   [(set (match_operand:DI 0 "register_operand" "")
10871         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10872                    (match_operand:QI 2 "nonmemory_operand" "")))
10873    (clobber (reg:CC FLAGS_REG))]
10874   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10875                      ? flow2_completed : reload_completed)"
10876   [(const_int 0)]
10877   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10878
10879 (define_insn "x86_shld_1"
10880   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10881         (ior:SI (ashift:SI (match_dup 0)
10882                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10883                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10884                   (minus:QI (const_int 32) (match_dup 2)))))
10885    (clobber (reg:CC FLAGS_REG))]
10886   ""
10887   "@
10888    shld{l}\t{%2, %1, %0|%0, %1, %2}
10889    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10890   [(set_attr "type" "ishift")
10891    (set_attr "prefix_0f" "1")
10892    (set_attr "mode" "SI")
10893    (set_attr "pent_pair" "np")
10894    (set_attr "athlon_decode" "vector")
10895    (set_attr "amdfam10_decode" "vector")])   
10896
10897 (define_expand "x86_shift_adj_1"
10898   [(set (reg:CCZ FLAGS_REG)
10899         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10900                              (const_int 32))
10901                      (const_int 0)))
10902    (set (match_operand:SI 0 "register_operand" "")
10903         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10904                          (match_operand:SI 1 "register_operand" "")
10905                          (match_dup 0)))
10906    (set (match_dup 1)
10907         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10908                          (match_operand:SI 3 "register_operand" "r")
10909                          (match_dup 1)))]
10910   "TARGET_CMOVE"
10911   "")
10912
10913 (define_expand "x86_shift_adj_2"
10914   [(use (match_operand:SI 0 "register_operand" ""))
10915    (use (match_operand:SI 1 "register_operand" ""))
10916    (use (match_operand:QI 2 "register_operand" ""))]
10917   ""
10918 {
10919   rtx label = gen_label_rtx ();
10920   rtx tmp;
10921
10922   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10923
10924   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10925   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10926   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10927                               gen_rtx_LABEL_REF (VOIDmode, label),
10928                               pc_rtx);
10929   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10930   JUMP_LABEL (tmp) = label;
10931
10932   emit_move_insn (operands[0], operands[1]);
10933   ix86_expand_clear (operands[1]);
10934
10935   emit_label (label);
10936   LABEL_NUSES (label) = 1;
10937
10938   DONE;
10939 })
10940
10941 (define_expand "ashlsi3"
10942   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10943         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10944                    (match_operand:QI 2 "nonmemory_operand" "")))
10945    (clobber (reg:CC FLAGS_REG))]
10946   ""
10947   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10948
10949 (define_insn "*ashlsi3_1"
10950   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10951         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10952                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10953    (clobber (reg:CC FLAGS_REG))]
10954   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10955 {
10956   switch (get_attr_type (insn))
10957     {
10958     case TYPE_ALU:
10959       gcc_assert (operands[2] == const1_rtx);
10960       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10961       return "add{l}\t%0, %0";
10962
10963     case TYPE_LEA:
10964       return "#";
10965
10966     default:
10967       if (REG_P (operands[2]))
10968         return "sal{l}\t{%b2, %0|%0, %b2}";
10969       else if (operands[2] == const1_rtx
10970                && (TARGET_SHIFT1 || optimize_size))
10971         return "sal{l}\t%0";
10972       else
10973         return "sal{l}\t{%2, %0|%0, %2}";
10974     }
10975 }
10976   [(set (attr "type")
10977      (cond [(eq_attr "alternative" "1")
10978               (const_string "lea")
10979             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10980                           (const_int 0))
10981                       (match_operand 0 "register_operand" ""))
10982                  (match_operand 2 "const1_operand" ""))
10983               (const_string "alu")
10984            ]
10985            (const_string "ishift")))
10986    (set_attr "mode" "SI")])
10987
10988 ;; Convert lea to the lea pattern to avoid flags dependency.
10989 (define_split
10990   [(set (match_operand 0 "register_operand" "")
10991         (ashift (match_operand 1 "index_register_operand" "")
10992                 (match_operand:QI 2 "const_int_operand" "")))
10993    (clobber (reg:CC FLAGS_REG))]
10994   "reload_completed
10995    && true_regnum (operands[0]) != true_regnum (operands[1])
10996    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10997   [(const_int 0)]
10998 {
10999   rtx pat;
11000   enum machine_mode mode = GET_MODE (operands[0]);
11001
11002   if (GET_MODE_SIZE (mode) < 4)
11003     operands[0] = gen_lowpart (SImode, operands[0]);
11004   if (mode != Pmode)
11005     operands[1] = gen_lowpart (Pmode, operands[1]);
11006   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11007
11008   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11009   if (Pmode != SImode)
11010     pat = gen_rtx_SUBREG (SImode, pat, 0);
11011   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11012   DONE;
11013 })
11014
11015 ;; Rare case of shifting RSP is handled by generating move and shift
11016 (define_split
11017   [(set (match_operand 0 "register_operand" "")
11018         (ashift (match_operand 1 "register_operand" "")
11019                 (match_operand:QI 2 "const_int_operand" "")))
11020    (clobber (reg:CC FLAGS_REG))]
11021   "reload_completed
11022    && true_regnum (operands[0]) != true_regnum (operands[1])"
11023   [(const_int 0)]
11024 {
11025   rtx pat, clob;
11026   emit_move_insn (operands[0], operands[1]);
11027   pat = gen_rtx_SET (VOIDmode, operands[0],
11028                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11029                                      operands[0], operands[2]));
11030   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11031   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11032   DONE;
11033 })
11034
11035 (define_insn "*ashlsi3_1_zext"
11036   [(set (match_operand:DI 0 "register_operand" "=r,r")
11037         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11038                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11039    (clobber (reg:CC FLAGS_REG))]
11040   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11041 {
11042   switch (get_attr_type (insn))
11043     {
11044     case TYPE_ALU:
11045       gcc_assert (operands[2] == const1_rtx);
11046       return "add{l}\t%k0, %k0";
11047
11048     case TYPE_LEA:
11049       return "#";
11050
11051     default:
11052       if (REG_P (operands[2]))
11053         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11054       else if (operands[2] == const1_rtx
11055                && (TARGET_SHIFT1 || optimize_size))
11056         return "sal{l}\t%k0";
11057       else
11058         return "sal{l}\t{%2, %k0|%k0, %2}";
11059     }
11060 }
11061   [(set (attr "type")
11062      (cond [(eq_attr "alternative" "1")
11063               (const_string "lea")
11064             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11065                      (const_int 0))
11066                  (match_operand 2 "const1_operand" ""))
11067               (const_string "alu")
11068            ]
11069            (const_string "ishift")))
11070    (set_attr "mode" "SI")])
11071
11072 ;; Convert lea to the lea pattern to avoid flags dependency.
11073 (define_split
11074   [(set (match_operand:DI 0 "register_operand" "")
11075         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11076                                 (match_operand:QI 2 "const_int_operand" ""))))
11077    (clobber (reg:CC FLAGS_REG))]
11078   "TARGET_64BIT && reload_completed
11079    && true_regnum (operands[0]) != true_regnum (operands[1])"
11080   [(set (match_dup 0) (zero_extend:DI
11081                         (subreg:SI (mult:SI (match_dup 1)
11082                                             (match_dup 2)) 0)))]
11083 {
11084   operands[1] = gen_lowpart (Pmode, operands[1]);
11085   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11086 })
11087
11088 ;; This pattern can't accept a variable shift count, since shifts by
11089 ;; zero don't affect the flags.  We assume that shifts by constant
11090 ;; zero are optimized away.
11091 (define_insn "*ashlsi3_cmp"
11092   [(set (reg FLAGS_REG)
11093         (compare
11094           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11095                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11096           (const_int 0)))
11097    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11098         (ashift:SI (match_dup 1) (match_dup 2)))]
11099   "ix86_match_ccmode (insn, CCGOCmode)
11100    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11101    && (optimize_size
11102        || !TARGET_PARTIAL_FLAG_REG_STALL
11103        || (operands[2] == const1_rtx
11104            && (TARGET_SHIFT1
11105                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11106 {
11107   switch (get_attr_type (insn))
11108     {
11109     case TYPE_ALU:
11110       gcc_assert (operands[2] == const1_rtx);
11111       return "add{l}\t%0, %0";
11112
11113     default:
11114       if (REG_P (operands[2]))
11115         return "sal{l}\t{%b2, %0|%0, %b2}";
11116       else if (operands[2] == const1_rtx
11117                && (TARGET_SHIFT1 || optimize_size))
11118         return "sal{l}\t%0";
11119       else
11120         return "sal{l}\t{%2, %0|%0, %2}";
11121     }
11122 }
11123   [(set (attr "type")
11124      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11125                           (const_int 0))
11126                       (match_operand 0 "register_operand" ""))
11127                  (match_operand 2 "const1_operand" ""))
11128               (const_string "alu")
11129            ]
11130            (const_string "ishift")))
11131    (set_attr "mode" "SI")])
11132
11133 (define_insn "*ashlsi3_cconly"
11134   [(set (reg FLAGS_REG)
11135         (compare
11136           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11137                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11138           (const_int 0)))
11139    (clobber (match_scratch:SI 0 "=r"))]
11140   "ix86_match_ccmode (insn, CCGOCmode)
11141    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11142    && (optimize_size
11143        || !TARGET_PARTIAL_FLAG_REG_STALL
11144        || (operands[2] == const1_rtx
11145            && (TARGET_SHIFT1
11146                || TARGET_DOUBLE_WITH_ADD)))"
11147 {
11148   switch (get_attr_type (insn))
11149     {
11150     case TYPE_ALU:
11151       gcc_assert (operands[2] == const1_rtx);
11152       return "add{l}\t%0, %0";
11153
11154     default:
11155       if (REG_P (operands[2]))
11156         return "sal{l}\t{%b2, %0|%0, %b2}";
11157       else if (operands[2] == const1_rtx
11158                && (TARGET_SHIFT1 || optimize_size))
11159         return "sal{l}\t%0";
11160       else
11161         return "sal{l}\t{%2, %0|%0, %2}";
11162     }
11163 }
11164   [(set (attr "type")
11165      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11166                           (const_int 0))
11167                       (match_operand 0 "register_operand" ""))
11168                  (match_operand 2 "const1_operand" ""))
11169               (const_string "alu")
11170            ]
11171            (const_string "ishift")))
11172    (set_attr "mode" "SI")])
11173
11174 (define_insn "*ashlsi3_cmp_zext"
11175   [(set (reg FLAGS_REG)
11176         (compare
11177           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11178                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11179           (const_int 0)))
11180    (set (match_operand:DI 0 "register_operand" "=r")
11181         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11182   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11183    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11184    && (optimize_size
11185        || !TARGET_PARTIAL_FLAG_REG_STALL
11186        || (operands[2] == const1_rtx
11187            && (TARGET_SHIFT1
11188                || TARGET_DOUBLE_WITH_ADD)))"
11189 {
11190   switch (get_attr_type (insn))
11191     {
11192     case TYPE_ALU:
11193       gcc_assert (operands[2] == const1_rtx);
11194       return "add{l}\t%k0, %k0";
11195
11196     default:
11197       if (REG_P (operands[2]))
11198         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11199       else if (operands[2] == const1_rtx
11200                && (TARGET_SHIFT1 || optimize_size))
11201         return "sal{l}\t%k0";
11202       else
11203         return "sal{l}\t{%2, %k0|%k0, %2}";
11204     }
11205 }
11206   [(set (attr "type")
11207      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11208                      (const_int 0))
11209                  (match_operand 2 "const1_operand" ""))
11210               (const_string "alu")
11211            ]
11212            (const_string "ishift")))
11213    (set_attr "mode" "SI")])
11214
11215 (define_expand "ashlhi3"
11216   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11217         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11218                    (match_operand:QI 2 "nonmemory_operand" "")))
11219    (clobber (reg:CC FLAGS_REG))]
11220   "TARGET_HIMODE_MATH"
11221   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11222
11223 (define_insn "*ashlhi3_1_lea"
11224   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11225         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11226                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11227    (clobber (reg:CC FLAGS_REG))]
11228   "!TARGET_PARTIAL_REG_STALL
11229    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11230 {
11231   switch (get_attr_type (insn))
11232     {
11233     case TYPE_LEA:
11234       return "#";
11235     case TYPE_ALU:
11236       gcc_assert (operands[2] == const1_rtx);
11237       return "add{w}\t%0, %0";
11238
11239     default:
11240       if (REG_P (operands[2]))
11241         return "sal{w}\t{%b2, %0|%0, %b2}";
11242       else if (operands[2] == const1_rtx
11243                && (TARGET_SHIFT1 || optimize_size))
11244         return "sal{w}\t%0";
11245       else
11246         return "sal{w}\t{%2, %0|%0, %2}";
11247     }
11248 }
11249   [(set (attr "type")
11250      (cond [(eq_attr "alternative" "1")
11251               (const_string "lea")
11252             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11253                           (const_int 0))
11254                       (match_operand 0 "register_operand" ""))
11255                  (match_operand 2 "const1_operand" ""))
11256               (const_string "alu")
11257            ]
11258            (const_string "ishift")))
11259    (set_attr "mode" "HI,SI")])
11260
11261 (define_insn "*ashlhi3_1"
11262   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11263         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11264                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11265    (clobber (reg:CC FLAGS_REG))]
11266   "TARGET_PARTIAL_REG_STALL
11267    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11268 {
11269   switch (get_attr_type (insn))
11270     {
11271     case TYPE_ALU:
11272       gcc_assert (operands[2] == const1_rtx);
11273       return "add{w}\t%0, %0";
11274
11275     default:
11276       if (REG_P (operands[2]))
11277         return "sal{w}\t{%b2, %0|%0, %b2}";
11278       else if (operands[2] == const1_rtx
11279                && (TARGET_SHIFT1 || optimize_size))
11280         return "sal{w}\t%0";
11281       else
11282         return "sal{w}\t{%2, %0|%0, %2}";
11283     }
11284 }
11285   [(set (attr "type")
11286      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11287                           (const_int 0))
11288                       (match_operand 0 "register_operand" ""))
11289                  (match_operand 2 "const1_operand" ""))
11290               (const_string "alu")
11291            ]
11292            (const_string "ishift")))
11293    (set_attr "mode" "HI")])
11294
11295 ;; This pattern can't accept a variable shift count, since shifts by
11296 ;; zero don't affect the flags.  We assume that shifts by constant
11297 ;; zero are optimized away.
11298 (define_insn "*ashlhi3_cmp"
11299   [(set (reg FLAGS_REG)
11300         (compare
11301           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11302                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11303           (const_int 0)))
11304    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11305         (ashift:HI (match_dup 1) (match_dup 2)))]
11306   "ix86_match_ccmode (insn, CCGOCmode)
11307    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11308    && (optimize_size
11309        || !TARGET_PARTIAL_FLAG_REG_STALL
11310        || (operands[2] == const1_rtx
11311            && (TARGET_SHIFT1
11312                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11313 {
11314   switch (get_attr_type (insn))
11315     {
11316     case TYPE_ALU:
11317       gcc_assert (operands[2] == const1_rtx);
11318       return "add{w}\t%0, %0";
11319
11320     default:
11321       if (REG_P (operands[2]))
11322         return "sal{w}\t{%b2, %0|%0, %b2}";
11323       else if (operands[2] == const1_rtx
11324                && (TARGET_SHIFT1 || optimize_size))
11325         return "sal{w}\t%0";
11326       else
11327         return "sal{w}\t{%2, %0|%0, %2}";
11328     }
11329 }
11330   [(set (attr "type")
11331      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11332                           (const_int 0))
11333                       (match_operand 0 "register_operand" ""))
11334                  (match_operand 2 "const1_operand" ""))
11335               (const_string "alu")
11336            ]
11337            (const_string "ishift")))
11338    (set_attr "mode" "HI")])
11339
11340 (define_insn "*ashlhi3_cconly"
11341   [(set (reg FLAGS_REG)
11342         (compare
11343           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11344                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11345           (const_int 0)))
11346    (clobber (match_scratch:HI 0 "=r"))]
11347   "ix86_match_ccmode (insn, CCGOCmode)
11348    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11349    && (optimize_size
11350        || !TARGET_PARTIAL_FLAG_REG_STALL
11351        || (operands[2] == const1_rtx
11352            && (TARGET_SHIFT1
11353                || TARGET_DOUBLE_WITH_ADD)))"
11354 {
11355   switch (get_attr_type (insn))
11356     {
11357     case TYPE_ALU:
11358       gcc_assert (operands[2] == const1_rtx);
11359       return "add{w}\t%0, %0";
11360
11361     default:
11362       if (REG_P (operands[2]))
11363         return "sal{w}\t{%b2, %0|%0, %b2}";
11364       else if (operands[2] == const1_rtx
11365                && (TARGET_SHIFT1 || optimize_size))
11366         return "sal{w}\t%0";
11367       else
11368         return "sal{w}\t{%2, %0|%0, %2}";
11369     }
11370 }
11371   [(set (attr "type")
11372      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11373                           (const_int 0))
11374                       (match_operand 0 "register_operand" ""))
11375                  (match_operand 2 "const1_operand" ""))
11376               (const_string "alu")
11377            ]
11378            (const_string "ishift")))
11379    (set_attr "mode" "HI")])
11380
11381 (define_expand "ashlqi3"
11382   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11383         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11384                    (match_operand:QI 2 "nonmemory_operand" "")))
11385    (clobber (reg:CC FLAGS_REG))]
11386   "TARGET_QIMODE_MATH"
11387   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11388
11389 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11390
11391 (define_insn "*ashlqi3_1_lea"
11392   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11393         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11394                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11395    (clobber (reg:CC FLAGS_REG))]
11396   "!TARGET_PARTIAL_REG_STALL
11397    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11398 {
11399   switch (get_attr_type (insn))
11400     {
11401     case TYPE_LEA:
11402       return "#";
11403     case TYPE_ALU:
11404       gcc_assert (operands[2] == const1_rtx);
11405       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11406         return "add{l}\t%k0, %k0";
11407       else
11408         return "add{b}\t%0, %0";
11409
11410     default:
11411       if (REG_P (operands[2]))
11412         {
11413           if (get_attr_mode (insn) == MODE_SI)
11414             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11415           else
11416             return "sal{b}\t{%b2, %0|%0, %b2}";
11417         }
11418       else if (operands[2] == const1_rtx
11419                && (TARGET_SHIFT1 || optimize_size))
11420         {
11421           if (get_attr_mode (insn) == MODE_SI)
11422             return "sal{l}\t%0";
11423           else
11424             return "sal{b}\t%0";
11425         }
11426       else
11427         {
11428           if (get_attr_mode (insn) == MODE_SI)
11429             return "sal{l}\t{%2, %k0|%k0, %2}";
11430           else
11431             return "sal{b}\t{%2, %0|%0, %2}";
11432         }
11433     }
11434 }
11435   [(set (attr "type")
11436      (cond [(eq_attr "alternative" "2")
11437               (const_string "lea")
11438             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11439                           (const_int 0))
11440                       (match_operand 0 "register_operand" ""))
11441                  (match_operand 2 "const1_operand" ""))
11442               (const_string "alu")
11443            ]
11444            (const_string "ishift")))
11445    (set_attr "mode" "QI,SI,SI")])
11446
11447 (define_insn "*ashlqi3_1"
11448   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11449         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11450                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11451    (clobber (reg:CC FLAGS_REG))]
11452   "TARGET_PARTIAL_REG_STALL
11453    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11454 {
11455   switch (get_attr_type (insn))
11456     {
11457     case TYPE_ALU:
11458       gcc_assert (operands[2] == const1_rtx);
11459       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11460         return "add{l}\t%k0, %k0";
11461       else
11462         return "add{b}\t%0, %0";
11463
11464     default:
11465       if (REG_P (operands[2]))
11466         {
11467           if (get_attr_mode (insn) == MODE_SI)
11468             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11469           else
11470             return "sal{b}\t{%b2, %0|%0, %b2}";
11471         }
11472       else if (operands[2] == const1_rtx
11473                && (TARGET_SHIFT1 || optimize_size))
11474         {
11475           if (get_attr_mode (insn) == MODE_SI)
11476             return "sal{l}\t%0";
11477           else
11478             return "sal{b}\t%0";
11479         }
11480       else
11481         {
11482           if (get_attr_mode (insn) == MODE_SI)
11483             return "sal{l}\t{%2, %k0|%k0, %2}";
11484           else
11485             return "sal{b}\t{%2, %0|%0, %2}";
11486         }
11487     }
11488 }
11489   [(set (attr "type")
11490      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11491                           (const_int 0))
11492                       (match_operand 0 "register_operand" ""))
11493                  (match_operand 2 "const1_operand" ""))
11494               (const_string "alu")
11495            ]
11496            (const_string "ishift")))
11497    (set_attr "mode" "QI,SI")])
11498
11499 ;; This pattern can't accept a variable shift count, since shifts by
11500 ;; zero don't affect the flags.  We assume that shifts by constant
11501 ;; zero are optimized away.
11502 (define_insn "*ashlqi3_cmp"
11503   [(set (reg FLAGS_REG)
11504         (compare
11505           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11506                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11507           (const_int 0)))
11508    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11509         (ashift:QI (match_dup 1) (match_dup 2)))]
11510   "ix86_match_ccmode (insn, CCGOCmode)
11511    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11512    && (optimize_size
11513        || !TARGET_PARTIAL_FLAG_REG_STALL
11514        || (operands[2] == const1_rtx
11515            && (TARGET_SHIFT1
11516                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11517 {
11518   switch (get_attr_type (insn))
11519     {
11520     case TYPE_ALU:
11521       gcc_assert (operands[2] == const1_rtx);
11522       return "add{b}\t%0, %0";
11523
11524     default:
11525       if (REG_P (operands[2]))
11526         return "sal{b}\t{%b2, %0|%0, %b2}";
11527       else if (operands[2] == const1_rtx
11528                && (TARGET_SHIFT1 || optimize_size))
11529         return "sal{b}\t%0";
11530       else
11531         return "sal{b}\t{%2, %0|%0, %2}";
11532     }
11533 }
11534   [(set (attr "type")
11535      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11536                           (const_int 0))
11537                       (match_operand 0 "register_operand" ""))
11538                  (match_operand 2 "const1_operand" ""))
11539               (const_string "alu")
11540            ]
11541            (const_string "ishift")))
11542    (set_attr "mode" "QI")])
11543
11544 (define_insn "*ashlqi3_cconly"
11545   [(set (reg FLAGS_REG)
11546         (compare
11547           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11548                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11549           (const_int 0)))
11550    (clobber (match_scratch:QI 0 "=q"))]
11551   "ix86_match_ccmode (insn, CCGOCmode)
11552    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11553    && (optimize_size
11554        || !TARGET_PARTIAL_FLAG_REG_STALL
11555        || (operands[2] == const1_rtx
11556            && (TARGET_SHIFT1
11557                || TARGET_DOUBLE_WITH_ADD)))"
11558 {
11559   switch (get_attr_type (insn))
11560     {
11561     case TYPE_ALU:
11562       gcc_assert (operands[2] == const1_rtx);
11563       return "add{b}\t%0, %0";
11564
11565     default:
11566       if (REG_P (operands[2]))
11567         return "sal{b}\t{%b2, %0|%0, %b2}";
11568       else if (operands[2] == const1_rtx
11569                && (TARGET_SHIFT1 || optimize_size))
11570         return "sal{b}\t%0";
11571       else
11572         return "sal{b}\t{%2, %0|%0, %2}";
11573     }
11574 }
11575   [(set (attr "type")
11576      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11577                           (const_int 0))
11578                       (match_operand 0 "register_operand" ""))
11579                  (match_operand 2 "const1_operand" ""))
11580               (const_string "alu")
11581            ]
11582            (const_string "ishift")))
11583    (set_attr "mode" "QI")])
11584
11585 ;; See comment above `ashldi3' about how this works.
11586
11587 (define_expand "ashrti3"
11588   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11589                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11590                                 (match_operand:QI 2 "nonmemory_operand" "")))
11591               (clobber (reg:CC FLAGS_REG))])]
11592   "TARGET_64BIT"
11593 {
11594   if (! immediate_operand (operands[2], QImode))
11595     {
11596       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11597       DONE;
11598     }
11599   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11600   DONE;
11601 })
11602
11603 (define_insn "ashrti3_1"
11604   [(set (match_operand:TI 0 "register_operand" "=r")
11605         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11606                      (match_operand:QI 2 "register_operand" "c")))
11607    (clobber (match_scratch:DI 3 "=&r"))
11608    (clobber (reg:CC FLAGS_REG))]
11609   "TARGET_64BIT"
11610   "#"
11611   [(set_attr "type" "multi")])
11612
11613 (define_insn "*ashrti3_2"
11614   [(set (match_operand:TI 0 "register_operand" "=r")
11615         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11616                      (match_operand:QI 2 "immediate_operand" "O")))
11617    (clobber (reg:CC FLAGS_REG))]
11618   "TARGET_64BIT"
11619   "#"
11620   [(set_attr "type" "multi")])
11621
11622 (define_split
11623   [(set (match_operand:TI 0 "register_operand" "")
11624         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11625                      (match_operand:QI 2 "register_operand" "")))
11626    (clobber (match_scratch:DI 3 ""))
11627    (clobber (reg:CC FLAGS_REG))]
11628   "TARGET_64BIT && reload_completed"
11629   [(const_int 0)]
11630   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11631
11632 (define_split
11633   [(set (match_operand:TI 0 "register_operand" "")
11634         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11635                      (match_operand:QI 2 "immediate_operand" "")))
11636    (clobber (reg:CC FLAGS_REG))]
11637   "TARGET_64BIT && reload_completed"
11638   [(const_int 0)]
11639   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11640
11641 (define_insn "x86_64_shrd"
11642   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11643         (ior:DI (ashiftrt:DI (match_dup 0)
11644                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11645                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11646                   (minus:QI (const_int 64) (match_dup 2)))))
11647    (clobber (reg:CC FLAGS_REG))]
11648   "TARGET_64BIT"
11649   "@
11650    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11651    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11652   [(set_attr "type" "ishift")
11653    (set_attr "prefix_0f" "1")
11654    (set_attr "mode" "DI")
11655    (set_attr "athlon_decode" "vector")
11656    (set_attr "amdfam10_decode" "vector")])   
11657
11658 (define_expand "ashrdi3"
11659   [(set (match_operand:DI 0 "shiftdi_operand" "")
11660         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11661                      (match_operand:QI 2 "nonmemory_operand" "")))]
11662   ""
11663   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11664
11665 (define_insn "*ashrdi3_63_rex64"
11666   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11667         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11668                      (match_operand:DI 2 "const_int_operand" "i,i")))
11669    (clobber (reg:CC FLAGS_REG))]
11670   "TARGET_64BIT && INTVAL (operands[2]) == 63
11671    && (TARGET_USE_CLTD || optimize_size)
11672    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11673   "@
11674    {cqto|cqo}
11675    sar{q}\t{%2, %0|%0, %2}"
11676   [(set_attr "type" "imovx,ishift")
11677    (set_attr "prefix_0f" "0,*")
11678    (set_attr "length_immediate" "0,*")
11679    (set_attr "modrm" "0,1")
11680    (set_attr "mode" "DI")])
11681
11682 (define_insn "*ashrdi3_1_one_bit_rex64"
11683   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11684         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11685                      (match_operand:QI 2 "const1_operand" "")))
11686    (clobber (reg:CC FLAGS_REG))]
11687   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11688    && (TARGET_SHIFT1 || optimize_size)"
11689   "sar{q}\t%0"
11690   [(set_attr "type" "ishift")
11691    (set (attr "length")
11692      (if_then_else (match_operand:DI 0 "register_operand" "")
11693         (const_string "2")
11694         (const_string "*")))])
11695
11696 (define_insn "*ashrdi3_1_rex64"
11697   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11698         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11699                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11700    (clobber (reg:CC FLAGS_REG))]
11701   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11702   "@
11703    sar{q}\t{%2, %0|%0, %2}
11704    sar{q}\t{%b2, %0|%0, %b2}"
11705   [(set_attr "type" "ishift")
11706    (set_attr "mode" "DI")])
11707
11708 ;; This pattern can't accept a variable shift count, since shifts by
11709 ;; zero don't affect the flags.  We assume that shifts by constant
11710 ;; zero are optimized away.
11711 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11712   [(set (reg FLAGS_REG)
11713         (compare
11714           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11715                        (match_operand:QI 2 "const1_operand" ""))
11716           (const_int 0)))
11717    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11718         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11719   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11720    && (TARGET_SHIFT1 || optimize_size)
11721    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11722   "sar{q}\t%0"
11723   [(set_attr "type" "ishift")
11724    (set (attr "length")
11725      (if_then_else (match_operand:DI 0 "register_operand" "")
11726         (const_string "2")
11727         (const_string "*")))])
11728
11729 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11730   [(set (reg FLAGS_REG)
11731         (compare
11732           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11733                        (match_operand:QI 2 "const1_operand" ""))
11734           (const_int 0)))
11735    (clobber (match_scratch:DI 0 "=r"))]
11736   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11737    && (TARGET_SHIFT1 || optimize_size)
11738    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11739   "sar{q}\t%0"
11740   [(set_attr "type" "ishift")
11741    (set_attr "length" "2")])
11742
11743 ;; This pattern can't accept a variable shift count, since shifts by
11744 ;; zero don't affect the flags.  We assume that shifts by constant
11745 ;; zero are optimized away.
11746 (define_insn "*ashrdi3_cmp_rex64"
11747   [(set (reg FLAGS_REG)
11748         (compare
11749           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11750                        (match_operand:QI 2 "const_int_operand" "n"))
11751           (const_int 0)))
11752    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11753         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11754   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11755    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11756    && (optimize_size
11757        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11758   "sar{q}\t{%2, %0|%0, %2}"
11759   [(set_attr "type" "ishift")
11760    (set_attr "mode" "DI")])
11761
11762 (define_insn "*ashrdi3_cconly_rex64"
11763   [(set (reg FLAGS_REG)
11764         (compare
11765           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11766                        (match_operand:QI 2 "const_int_operand" "n"))
11767           (const_int 0)))
11768    (clobber (match_scratch:DI 0 "=r"))]
11769   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11770    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11771    && (optimize_size
11772        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11773   "sar{q}\t{%2, %0|%0, %2}"
11774   [(set_attr "type" "ishift")
11775    (set_attr "mode" "DI")])
11776
11777 (define_insn "*ashrdi3_1"
11778   [(set (match_operand:DI 0 "register_operand" "=r")
11779         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11780                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11781    (clobber (reg:CC FLAGS_REG))]
11782   "!TARGET_64BIT"
11783   "#"
11784   [(set_attr "type" "multi")])
11785
11786 ;; By default we don't ask for a scratch register, because when DImode
11787 ;; values are manipulated, registers are already at a premium.  But if
11788 ;; we have one handy, we won't turn it away.
11789 (define_peephole2
11790   [(match_scratch:SI 3 "r")
11791    (parallel [(set (match_operand:DI 0 "register_operand" "")
11792                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11793                                 (match_operand:QI 2 "nonmemory_operand" "")))
11794               (clobber (reg:CC FLAGS_REG))])
11795    (match_dup 3)]
11796   "!TARGET_64BIT && TARGET_CMOVE"
11797   [(const_int 0)]
11798   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11799
11800 (define_split
11801   [(set (match_operand:DI 0 "register_operand" "")
11802         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11803                      (match_operand:QI 2 "nonmemory_operand" "")))
11804    (clobber (reg:CC FLAGS_REG))]
11805   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11806                      ? flow2_completed : reload_completed)"
11807   [(const_int 0)]
11808   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11809
11810 (define_insn "x86_shrd_1"
11811   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11812         (ior:SI (ashiftrt:SI (match_dup 0)
11813                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11814                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11815                   (minus:QI (const_int 32) (match_dup 2)))))
11816    (clobber (reg:CC FLAGS_REG))]
11817   ""
11818   "@
11819    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11820    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11821   [(set_attr "type" "ishift")
11822    (set_attr "prefix_0f" "1")
11823    (set_attr "pent_pair" "np")
11824    (set_attr "mode" "SI")])
11825
11826 (define_expand "x86_shift_adj_3"
11827   [(use (match_operand:SI 0 "register_operand" ""))
11828    (use (match_operand:SI 1 "register_operand" ""))
11829    (use (match_operand:QI 2 "register_operand" ""))]
11830   ""
11831 {
11832   rtx label = gen_label_rtx ();
11833   rtx tmp;
11834
11835   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11836
11837   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11838   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11839   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11840                               gen_rtx_LABEL_REF (VOIDmode, label),
11841                               pc_rtx);
11842   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11843   JUMP_LABEL (tmp) = label;
11844
11845   emit_move_insn (operands[0], operands[1]);
11846   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11847
11848   emit_label (label);
11849   LABEL_NUSES (label) = 1;
11850
11851   DONE;
11852 })
11853
11854 (define_insn "ashrsi3_31"
11855   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11856         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11857                      (match_operand:SI 2 "const_int_operand" "i,i")))
11858    (clobber (reg:CC FLAGS_REG))]
11859   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11860    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11861   "@
11862    {cltd|cdq}
11863    sar{l}\t{%2, %0|%0, %2}"
11864   [(set_attr "type" "imovx,ishift")
11865    (set_attr "prefix_0f" "0,*")
11866    (set_attr "length_immediate" "0,*")
11867    (set_attr "modrm" "0,1")
11868    (set_attr "mode" "SI")])
11869
11870 (define_insn "*ashrsi3_31_zext"
11871   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11872         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11873                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11874    (clobber (reg:CC FLAGS_REG))]
11875   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11876    && INTVAL (operands[2]) == 31
11877    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11878   "@
11879    {cltd|cdq}
11880    sar{l}\t{%2, %k0|%k0, %2}"
11881   [(set_attr "type" "imovx,ishift")
11882    (set_attr "prefix_0f" "0,*")
11883    (set_attr "length_immediate" "0,*")
11884    (set_attr "modrm" "0,1")
11885    (set_attr "mode" "SI")])
11886
11887 (define_expand "ashrsi3"
11888   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11889         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11890                      (match_operand:QI 2 "nonmemory_operand" "")))
11891    (clobber (reg:CC FLAGS_REG))]
11892   ""
11893   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11894
11895 (define_insn "*ashrsi3_1_one_bit"
11896   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11897         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11898                      (match_operand:QI 2 "const1_operand" "")))
11899    (clobber (reg:CC FLAGS_REG))]
11900   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11901    && (TARGET_SHIFT1 || optimize_size)"
11902   "sar{l}\t%0"
11903   [(set_attr "type" "ishift")
11904    (set (attr "length")
11905      (if_then_else (match_operand:SI 0 "register_operand" "")
11906         (const_string "2")
11907         (const_string "*")))])
11908
11909 (define_insn "*ashrsi3_1_one_bit_zext"
11910   [(set (match_operand:DI 0 "register_operand" "=r")
11911         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11912                                      (match_operand:QI 2 "const1_operand" ""))))
11913    (clobber (reg:CC FLAGS_REG))]
11914   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11915    && (TARGET_SHIFT1 || optimize_size)"
11916   "sar{l}\t%k0"
11917   [(set_attr "type" "ishift")
11918    (set_attr "length" "2")])
11919
11920 (define_insn "*ashrsi3_1"
11921   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11922         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11923                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11924    (clobber (reg:CC FLAGS_REG))]
11925   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11926   "@
11927    sar{l}\t{%2, %0|%0, %2}
11928    sar{l}\t{%b2, %0|%0, %b2}"
11929   [(set_attr "type" "ishift")
11930    (set_attr "mode" "SI")])
11931
11932 (define_insn "*ashrsi3_1_zext"
11933   [(set (match_operand:DI 0 "register_operand" "=r,r")
11934         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11935                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11936    (clobber (reg:CC FLAGS_REG))]
11937   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11938   "@
11939    sar{l}\t{%2, %k0|%k0, %2}
11940    sar{l}\t{%b2, %k0|%k0, %b2}"
11941   [(set_attr "type" "ishift")
11942    (set_attr "mode" "SI")])
11943
11944 ;; This pattern can't accept a variable shift count, since shifts by
11945 ;; zero don't affect the flags.  We assume that shifts by constant
11946 ;; zero are optimized away.
11947 (define_insn "*ashrsi3_one_bit_cmp"
11948   [(set (reg FLAGS_REG)
11949         (compare
11950           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11951                        (match_operand:QI 2 "const1_operand" ""))
11952           (const_int 0)))
11953    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11954         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11955   "ix86_match_ccmode (insn, CCGOCmode)
11956    && (TARGET_SHIFT1 || optimize_size)
11957    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11958   "sar{l}\t%0"
11959   [(set_attr "type" "ishift")
11960    (set (attr "length")
11961      (if_then_else (match_operand:SI 0 "register_operand" "")
11962         (const_string "2")
11963         (const_string "*")))])
11964
11965 (define_insn "*ashrsi3_one_bit_cconly"
11966   [(set (reg FLAGS_REG)
11967         (compare
11968           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11969                        (match_operand:QI 2 "const1_operand" ""))
11970           (const_int 0)))
11971    (clobber (match_scratch:SI 0 "=r"))]
11972   "ix86_match_ccmode (insn, CCGOCmode)
11973    && (TARGET_SHIFT1 || optimize_size)
11974    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11975   "sar{l}\t%0"
11976   [(set_attr "type" "ishift")
11977    (set_attr "length" "2")])
11978
11979 (define_insn "*ashrsi3_one_bit_cmp_zext"
11980   [(set (reg FLAGS_REG)
11981         (compare
11982           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11983                        (match_operand:QI 2 "const1_operand" ""))
11984           (const_int 0)))
11985    (set (match_operand:DI 0 "register_operand" "=r")
11986         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11987   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11988    && (TARGET_SHIFT1 || optimize_size)
11989    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11990   "sar{l}\t%k0"
11991   [(set_attr "type" "ishift")
11992    (set_attr "length" "2")])
11993
11994 ;; This pattern can't accept a variable shift count, since shifts by
11995 ;; zero don't affect the flags.  We assume that shifts by constant
11996 ;; zero are optimized away.
11997 (define_insn "*ashrsi3_cmp"
11998   [(set (reg FLAGS_REG)
11999         (compare
12000           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12001                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12002           (const_int 0)))
12003    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12004         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12005   "ix86_match_ccmode (insn, CCGOCmode)
12006    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
12007    && (optimize_size
12008        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12009   "sar{l}\t{%2, %0|%0, %2}"
12010   [(set_attr "type" "ishift")
12011    (set_attr "mode" "SI")])
12012
12013 (define_insn "*ashrsi3_cconly"
12014   [(set (reg FLAGS_REG)
12015         (compare
12016           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12017                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12018           (const_int 0)))
12019    (clobber (match_scratch:SI 0 "=r"))]
12020   "ix86_match_ccmode (insn, CCGOCmode)
12021    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
12022    && (optimize_size
12023        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12024   "sar{l}\t{%2, %0|%0, %2}"
12025   [(set_attr "type" "ishift")
12026    (set_attr "mode" "SI")])
12027
12028 (define_insn "*ashrsi3_cmp_zext"
12029   [(set (reg FLAGS_REG)
12030         (compare
12031           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12032                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12033           (const_int 0)))
12034    (set (match_operand:DI 0 "register_operand" "=r")
12035         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12036   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12037    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
12038    && (optimize_size
12039        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12040   "sar{l}\t{%2, %k0|%k0, %2}"
12041   [(set_attr "type" "ishift")
12042    (set_attr "mode" "SI")])
12043
12044 (define_expand "ashrhi3"
12045   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12046         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12047                      (match_operand:QI 2 "nonmemory_operand" "")))
12048    (clobber (reg:CC FLAGS_REG))]
12049   "TARGET_HIMODE_MATH"
12050   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12051
12052 (define_insn "*ashrhi3_1_one_bit"
12053   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12054         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12055                      (match_operand:QI 2 "const1_operand" "")))
12056    (clobber (reg:CC FLAGS_REG))]
12057   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12058    && (TARGET_SHIFT1 || optimize_size)"
12059   "sar{w}\t%0"
12060   [(set_attr "type" "ishift")
12061    (set (attr "length")
12062      (if_then_else (match_operand 0 "register_operand" "")
12063         (const_string "2")
12064         (const_string "*")))])
12065
12066 (define_insn "*ashrhi3_1"
12067   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12068         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12069                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12070    (clobber (reg:CC FLAGS_REG))]
12071   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12072   "@
12073    sar{w}\t{%2, %0|%0, %2}
12074    sar{w}\t{%b2, %0|%0, %b2}"
12075   [(set_attr "type" "ishift")
12076    (set_attr "mode" "HI")])
12077
12078 ;; This pattern can't accept a variable shift count, since shifts by
12079 ;; zero don't affect the flags.  We assume that shifts by constant
12080 ;; zero are optimized away.
12081 (define_insn "*ashrhi3_one_bit_cmp"
12082   [(set (reg FLAGS_REG)
12083         (compare
12084           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12085                        (match_operand:QI 2 "const1_operand" ""))
12086           (const_int 0)))
12087    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12088         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12089   "ix86_match_ccmode (insn, CCGOCmode)
12090    && (TARGET_SHIFT1 || optimize_size)
12091    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12092   "sar{w}\t%0"
12093   [(set_attr "type" "ishift")
12094    (set (attr "length")
12095      (if_then_else (match_operand 0 "register_operand" "")
12096         (const_string "2")
12097         (const_string "*")))])
12098
12099 (define_insn "*ashrhi3_one_bit_cconly"
12100   [(set (reg FLAGS_REG)
12101         (compare
12102           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12103                        (match_operand:QI 2 "const1_operand" ""))
12104           (const_int 0)))
12105    (clobber (match_scratch:HI 0 "=r"))]
12106   "ix86_match_ccmode (insn, CCGOCmode)
12107    && (TARGET_SHIFT1 || optimize_size)
12108    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12109   "sar{w}\t%0"
12110   [(set_attr "type" "ishift")
12111    (set_attr "length" "2")])
12112
12113 ;; This pattern can't accept a variable shift count, since shifts by
12114 ;; zero don't affect the flags.  We assume that shifts by constant
12115 ;; zero are optimized away.
12116 (define_insn "*ashrhi3_cmp"
12117   [(set (reg FLAGS_REG)
12118         (compare
12119           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12120                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12121           (const_int 0)))
12122    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12123         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12124   "ix86_match_ccmode (insn, CCGOCmode)
12125    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12126    && (optimize_size
12127        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12128   "sar{w}\t{%2, %0|%0, %2}"
12129   [(set_attr "type" "ishift")
12130    (set_attr "mode" "HI")])
12131
12132 (define_insn "*ashrhi3_cconly"
12133   [(set (reg FLAGS_REG)
12134         (compare
12135           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12136                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12137           (const_int 0)))
12138    (clobber (match_scratch:HI 0 "=r"))]
12139   "ix86_match_ccmode (insn, CCGOCmode)
12140    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12141    && (optimize_size
12142        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12143   "sar{w}\t{%2, %0|%0, %2}"
12144   [(set_attr "type" "ishift")
12145    (set_attr "mode" "HI")])
12146
12147 (define_expand "ashrqi3"
12148   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12149         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12150                      (match_operand:QI 2 "nonmemory_operand" "")))
12151    (clobber (reg:CC FLAGS_REG))]
12152   "TARGET_QIMODE_MATH"
12153   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12154
12155 (define_insn "*ashrqi3_1_one_bit"
12156   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12157         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12158                      (match_operand:QI 2 "const1_operand" "")))
12159    (clobber (reg:CC FLAGS_REG))]
12160   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12161    && (TARGET_SHIFT1 || optimize_size)"
12162   "sar{b}\t%0"
12163   [(set_attr "type" "ishift")
12164    (set (attr "length")
12165      (if_then_else (match_operand 0 "register_operand" "")
12166         (const_string "2")
12167         (const_string "*")))])
12168
12169 (define_insn "*ashrqi3_1_one_bit_slp"
12170   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12171         (ashiftrt:QI (match_dup 0)
12172                      (match_operand:QI 1 "const1_operand" "")))
12173    (clobber (reg:CC FLAGS_REG))]
12174   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12175    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
12176    && (TARGET_SHIFT1 || optimize_size)"
12177   "sar{b}\t%0"
12178   [(set_attr "type" "ishift1")
12179    (set (attr "length")
12180      (if_then_else (match_operand 0 "register_operand" "")
12181         (const_string "2")
12182         (const_string "*")))])
12183
12184 (define_insn "*ashrqi3_1"
12185   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12186         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12187                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12188    (clobber (reg:CC FLAGS_REG))]
12189   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12190   "@
12191    sar{b}\t{%2, %0|%0, %2}
12192    sar{b}\t{%b2, %0|%0, %b2}"
12193   [(set_attr "type" "ishift")
12194    (set_attr "mode" "QI")])
12195
12196 (define_insn "*ashrqi3_1_slp"
12197   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12198         (ashiftrt:QI (match_dup 0)
12199                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12200    (clobber (reg:CC FLAGS_REG))]
12201   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12202    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12203   "@
12204    sar{b}\t{%1, %0|%0, %1}
12205    sar{b}\t{%b1, %0|%0, %b1}"
12206   [(set_attr "type" "ishift1")
12207    (set_attr "mode" "QI")])
12208
12209 ;; This pattern can't accept a variable shift count, since shifts by
12210 ;; zero don't affect the flags.  We assume that shifts by constant
12211 ;; zero are optimized away.
12212 (define_insn "*ashrqi3_one_bit_cmp"
12213   [(set (reg FLAGS_REG)
12214         (compare
12215           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12216                        (match_operand:QI 2 "const1_operand" "I"))
12217           (const_int 0)))
12218    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12219         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12220   "ix86_match_ccmode (insn, CCGOCmode)
12221    && (TARGET_SHIFT1 || optimize_size)
12222    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12223   "sar{b}\t%0"
12224   [(set_attr "type" "ishift")
12225    (set (attr "length")
12226      (if_then_else (match_operand 0 "register_operand" "")
12227         (const_string "2")
12228         (const_string "*")))])
12229
12230 (define_insn "*ashrqi3_one_bit_cconly"
12231   [(set (reg FLAGS_REG)
12232         (compare
12233           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12234                        (match_operand:QI 2 "const1_operand" "I"))
12235           (const_int 0)))
12236    (clobber (match_scratch:QI 0 "=q"))]
12237   "ix86_match_ccmode (insn, CCGOCmode)
12238    && (TARGET_SHIFT1 || optimize_size)
12239    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12240   "sar{b}\t%0"
12241   [(set_attr "type" "ishift")
12242    (set_attr "length" "2")])
12243
12244 ;; This pattern can't accept a variable shift count, since shifts by
12245 ;; zero don't affect the flags.  We assume that shifts by constant
12246 ;; zero are optimized away.
12247 (define_insn "*ashrqi3_cmp"
12248   [(set (reg FLAGS_REG)
12249         (compare
12250           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12251                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12252           (const_int 0)))
12253    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12254         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12255   "ix86_match_ccmode (insn, CCGOCmode)
12256    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12257    && (optimize_size
12258        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12259   "sar{b}\t{%2, %0|%0, %2}"
12260   [(set_attr "type" "ishift")
12261    (set_attr "mode" "QI")])
12262
12263 (define_insn "*ashrqi3_cconly"
12264   [(set (reg FLAGS_REG)
12265         (compare
12266           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12267                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12268           (const_int 0)))
12269    (clobber (match_scratch:QI 0 "=q"))]
12270   "ix86_match_ccmode (insn, CCGOCmode)
12271    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12272    && (optimize_size
12273        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12274   "sar{b}\t{%2, %0|%0, %2}"
12275   [(set_attr "type" "ishift")
12276    (set_attr "mode" "QI")])
12277
12278 \f
12279 ;; Logical shift instructions
12280
12281 ;; See comment above `ashldi3' about how this works.
12282
12283 (define_expand "lshrti3"
12284   [(parallel [(set (match_operand:TI 0 "register_operand" "")
12285                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12286                                 (match_operand:QI 2 "nonmemory_operand" "")))
12287               (clobber (reg:CC FLAGS_REG))])]
12288   "TARGET_64BIT"
12289 {
12290   if (! immediate_operand (operands[2], QImode))
12291     {
12292       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12293       DONE;
12294     }
12295   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12296   DONE;
12297 })
12298
12299 (define_insn "lshrti3_1"
12300   [(set (match_operand:TI 0 "register_operand" "=r")
12301         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12302                      (match_operand:QI 2 "register_operand" "c")))
12303    (clobber (match_scratch:DI 3 "=&r"))
12304    (clobber (reg:CC FLAGS_REG))]
12305   "TARGET_64BIT"
12306   "#"
12307   [(set_attr "type" "multi")])
12308
12309 (define_insn "*lshrti3_2"
12310   [(set (match_operand:TI 0 "register_operand" "=r")
12311         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12312                      (match_operand:QI 2 "immediate_operand" "O")))
12313    (clobber (reg:CC FLAGS_REG))]
12314   "TARGET_64BIT"
12315   "#"
12316   [(set_attr "type" "multi")])
12317
12318 (define_split
12319   [(set (match_operand:TI 0 "register_operand" "")
12320         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12321                      (match_operand:QI 2 "register_operand" "")))
12322    (clobber (match_scratch:DI 3 ""))
12323    (clobber (reg:CC FLAGS_REG))]
12324   "TARGET_64BIT && reload_completed"
12325   [(const_int 0)]
12326   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12327
12328 (define_split
12329   [(set (match_operand:TI 0 "register_operand" "")
12330         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12331                      (match_operand:QI 2 "immediate_operand" "")))
12332    (clobber (reg:CC FLAGS_REG))]
12333   "TARGET_64BIT && reload_completed"
12334   [(const_int 0)]
12335   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12336
12337 (define_expand "lshrdi3"
12338   [(set (match_operand:DI 0 "shiftdi_operand" "")
12339         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12340                      (match_operand:QI 2 "nonmemory_operand" "")))]
12341   ""
12342   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12343
12344 (define_insn "*lshrdi3_1_one_bit_rex64"
12345   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12346         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12347                      (match_operand:QI 2 "const1_operand" "")))
12348    (clobber (reg:CC FLAGS_REG))]
12349   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12350    && (TARGET_SHIFT1 || optimize_size)"
12351   "shr{q}\t%0"
12352   [(set_attr "type" "ishift")
12353    (set (attr "length")
12354      (if_then_else (match_operand:DI 0 "register_operand" "")
12355         (const_string "2")
12356         (const_string "*")))])
12357
12358 (define_insn "*lshrdi3_1_rex64"
12359   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12360         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12361                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12362    (clobber (reg:CC FLAGS_REG))]
12363   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12364   "@
12365    shr{q}\t{%2, %0|%0, %2}
12366    shr{q}\t{%b2, %0|%0, %b2}"
12367   [(set_attr "type" "ishift")
12368    (set_attr "mode" "DI")])
12369
12370 ;; This pattern can't accept a variable shift count, since shifts by
12371 ;; zero don't affect the flags.  We assume that shifts by constant
12372 ;; zero are optimized away.
12373 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12374   [(set (reg FLAGS_REG)
12375         (compare
12376           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12377                        (match_operand:QI 2 "const1_operand" ""))
12378           (const_int 0)))
12379    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12380         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12381   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12382    && (TARGET_SHIFT1 || optimize_size)
12383    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12384   "shr{q}\t%0"
12385   [(set_attr "type" "ishift")
12386    (set (attr "length")
12387      (if_then_else (match_operand:DI 0 "register_operand" "")
12388         (const_string "2")
12389         (const_string "*")))])
12390
12391 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12392   [(set (reg FLAGS_REG)
12393         (compare
12394           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12395                        (match_operand:QI 2 "const1_operand" ""))
12396           (const_int 0)))
12397    (clobber (match_scratch:DI 0 "=r"))]
12398   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12399    && (TARGET_SHIFT1 || optimize_size)
12400    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12401   "shr{q}\t%0"
12402   [(set_attr "type" "ishift")
12403    (set_attr "length" "2")])
12404
12405 ;; This pattern can't accept a variable shift count, since shifts by
12406 ;; zero don't affect the flags.  We assume that shifts by constant
12407 ;; zero are optimized away.
12408 (define_insn "*lshrdi3_cmp_rex64"
12409   [(set (reg FLAGS_REG)
12410         (compare
12411           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12412                        (match_operand:QI 2 "const_int_operand" "e"))
12413           (const_int 0)))
12414    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12415         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12416   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12417    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12418    && (optimize_size
12419        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12420   "shr{q}\t{%2, %0|%0, %2}"
12421   [(set_attr "type" "ishift")
12422    (set_attr "mode" "DI")])
12423
12424 (define_insn "*lshrdi3_cconly_rex64"
12425   [(set (reg FLAGS_REG)
12426         (compare
12427           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12428                        (match_operand:QI 2 "const_int_operand" "e"))
12429           (const_int 0)))
12430    (clobber (match_scratch:DI 0 "=r"))]
12431   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12432    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12433    && (optimize_size
12434        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12435   "shr{q}\t{%2, %0|%0, %2}"
12436   [(set_attr "type" "ishift")
12437    (set_attr "mode" "DI")])
12438
12439 (define_insn "*lshrdi3_1"
12440   [(set (match_operand:DI 0 "register_operand" "=r")
12441         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12442                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12443    (clobber (reg:CC FLAGS_REG))]
12444   "!TARGET_64BIT"
12445   "#"
12446   [(set_attr "type" "multi")])
12447
12448 ;; By default we don't ask for a scratch register, because when DImode
12449 ;; values are manipulated, registers are already at a premium.  But if
12450 ;; we have one handy, we won't turn it away.
12451 (define_peephole2
12452   [(match_scratch:SI 3 "r")
12453    (parallel [(set (match_operand:DI 0 "register_operand" "")
12454                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12455                                 (match_operand:QI 2 "nonmemory_operand" "")))
12456               (clobber (reg:CC FLAGS_REG))])
12457    (match_dup 3)]
12458   "!TARGET_64BIT && TARGET_CMOVE"
12459   [(const_int 0)]
12460   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12461
12462 (define_split
12463   [(set (match_operand:DI 0 "register_operand" "")
12464         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12465                      (match_operand:QI 2 "nonmemory_operand" "")))
12466    (clobber (reg:CC FLAGS_REG))]
12467   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12468                      ? flow2_completed : reload_completed)"
12469   [(const_int 0)]
12470   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12471
12472 (define_expand "lshrsi3"
12473   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12474         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12475                      (match_operand:QI 2 "nonmemory_operand" "")))
12476    (clobber (reg:CC FLAGS_REG))]
12477   ""
12478   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12479
12480 (define_insn "*lshrsi3_1_one_bit"
12481   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12482         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12483                      (match_operand:QI 2 "const1_operand" "")))
12484    (clobber (reg:CC FLAGS_REG))]
12485   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12486    && (TARGET_SHIFT1 || optimize_size)"
12487   "shr{l}\t%0"
12488   [(set_attr "type" "ishift")
12489    (set (attr "length")
12490      (if_then_else (match_operand:SI 0 "register_operand" "")
12491         (const_string "2")
12492         (const_string "*")))])
12493
12494 (define_insn "*lshrsi3_1_one_bit_zext"
12495   [(set (match_operand:DI 0 "register_operand" "=r")
12496         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12497                      (match_operand:QI 2 "const1_operand" "")))
12498    (clobber (reg:CC FLAGS_REG))]
12499   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12500    && (TARGET_SHIFT1 || optimize_size)"
12501   "shr{l}\t%k0"
12502   [(set_attr "type" "ishift")
12503    (set_attr "length" "2")])
12504
12505 (define_insn "*lshrsi3_1"
12506   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12507         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12508                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12509    (clobber (reg:CC FLAGS_REG))]
12510   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12511   "@
12512    shr{l}\t{%2, %0|%0, %2}
12513    shr{l}\t{%b2, %0|%0, %b2}"
12514   [(set_attr "type" "ishift")
12515    (set_attr "mode" "SI")])
12516
12517 (define_insn "*lshrsi3_1_zext"
12518   [(set (match_operand:DI 0 "register_operand" "=r,r")
12519         (zero_extend:DI
12520           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12521                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12522    (clobber (reg:CC FLAGS_REG))]
12523   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12524   "@
12525    shr{l}\t{%2, %k0|%k0, %2}
12526    shr{l}\t{%b2, %k0|%k0, %b2}"
12527   [(set_attr "type" "ishift")
12528    (set_attr "mode" "SI")])
12529
12530 ;; This pattern can't accept a variable shift count, since shifts by
12531 ;; zero don't affect the flags.  We assume that shifts by constant
12532 ;; zero are optimized away.
12533 (define_insn "*lshrsi3_one_bit_cmp"
12534   [(set (reg FLAGS_REG)
12535         (compare
12536           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12537                        (match_operand:QI 2 "const1_operand" ""))
12538           (const_int 0)))
12539    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12540         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12541   "ix86_match_ccmode (insn, CCGOCmode)
12542    && (TARGET_SHIFT1 || optimize_size)
12543    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12544   "shr{l}\t%0"
12545   [(set_attr "type" "ishift")
12546    (set (attr "length")
12547      (if_then_else (match_operand:SI 0 "register_operand" "")
12548         (const_string "2")
12549         (const_string "*")))])
12550
12551 (define_insn "*lshrsi3_one_bit_cconly"
12552   [(set (reg FLAGS_REG)
12553         (compare
12554           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12555                        (match_operand:QI 2 "const1_operand" ""))
12556           (const_int 0)))
12557    (clobber (match_scratch:SI 0 "=r"))]
12558   "ix86_match_ccmode (insn, CCGOCmode)
12559    && (TARGET_SHIFT1 || optimize_size)
12560    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12561   "shr{l}\t%0"
12562   [(set_attr "type" "ishift")
12563    (set_attr "length" "2")])
12564
12565 (define_insn "*lshrsi3_cmp_one_bit_zext"
12566   [(set (reg FLAGS_REG)
12567         (compare
12568           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12569                        (match_operand:QI 2 "const1_operand" ""))
12570           (const_int 0)))
12571    (set (match_operand:DI 0 "register_operand" "=r")
12572         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12573   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12574    && (TARGET_SHIFT1 || optimize_size)
12575    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12576   "shr{l}\t%k0"
12577   [(set_attr "type" "ishift")
12578    (set_attr "length" "2")])
12579
12580 ;; This pattern can't accept a variable shift count, since shifts by
12581 ;; zero don't affect the flags.  We assume that shifts by constant
12582 ;; zero are optimized away.
12583 (define_insn "*lshrsi3_cmp"
12584   [(set (reg FLAGS_REG)
12585         (compare
12586           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12587                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12588           (const_int 0)))
12589    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12590         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12591   "ix86_match_ccmode (insn, CCGOCmode)
12592    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12593    && (optimize_size
12594        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12595   "shr{l}\t{%2, %0|%0, %2}"
12596   [(set_attr "type" "ishift")
12597    (set_attr "mode" "SI")])
12598
12599 (define_insn "*lshrsi3_cconly"
12600   [(set (reg FLAGS_REG)
12601       (compare
12602         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12603                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12604         (const_int 0)))
12605    (clobber (match_scratch:SI 0 "=r"))]
12606   "ix86_match_ccmode (insn, CCGOCmode)
12607    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12608    && (optimize_size
12609        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12610   "shr{l}\t{%2, %0|%0, %2}"
12611   [(set_attr "type" "ishift")
12612    (set_attr "mode" "SI")])
12613
12614 (define_insn "*lshrsi3_cmp_zext"
12615   [(set (reg FLAGS_REG)
12616         (compare
12617           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12618                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12619           (const_int 0)))
12620    (set (match_operand:DI 0 "register_operand" "=r")
12621         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12622   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12623    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12624    && (optimize_size
12625        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12626   "shr{l}\t{%2, %k0|%k0, %2}"
12627   [(set_attr "type" "ishift")
12628    (set_attr "mode" "SI")])
12629
12630 (define_expand "lshrhi3"
12631   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12632         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12633                      (match_operand:QI 2 "nonmemory_operand" "")))
12634    (clobber (reg:CC FLAGS_REG))]
12635   "TARGET_HIMODE_MATH"
12636   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12637
12638 (define_insn "*lshrhi3_1_one_bit"
12639   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12640         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12641                      (match_operand:QI 2 "const1_operand" "")))
12642    (clobber (reg:CC FLAGS_REG))]
12643   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12644    && (TARGET_SHIFT1 || optimize_size)"
12645   "shr{w}\t%0"
12646   [(set_attr "type" "ishift")
12647    (set (attr "length")
12648      (if_then_else (match_operand 0 "register_operand" "")
12649         (const_string "2")
12650         (const_string "*")))])
12651
12652 (define_insn "*lshrhi3_1"
12653   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12654         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12655                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12656    (clobber (reg:CC FLAGS_REG))]
12657   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12658   "@
12659    shr{w}\t{%2, %0|%0, %2}
12660    shr{w}\t{%b2, %0|%0, %b2}"
12661   [(set_attr "type" "ishift")
12662    (set_attr "mode" "HI")])
12663
12664 ;; This pattern can't accept a variable shift count, since shifts by
12665 ;; zero don't affect the flags.  We assume that shifts by constant
12666 ;; zero are optimized away.
12667 (define_insn "*lshrhi3_one_bit_cmp"
12668   [(set (reg FLAGS_REG)
12669         (compare
12670           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12671                        (match_operand:QI 2 "const1_operand" ""))
12672           (const_int 0)))
12673    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12674         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12675   "ix86_match_ccmode (insn, CCGOCmode)
12676    && (TARGET_SHIFT1 || optimize_size)
12677    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12678   "shr{w}\t%0"
12679   [(set_attr "type" "ishift")
12680    (set (attr "length")
12681      (if_then_else (match_operand:SI 0 "register_operand" "")
12682         (const_string "2")
12683         (const_string "*")))])
12684
12685 (define_insn "*lshrhi3_one_bit_cconly"
12686   [(set (reg FLAGS_REG)
12687         (compare
12688           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12689                        (match_operand:QI 2 "const1_operand" ""))
12690           (const_int 0)))
12691    (clobber (match_scratch:HI 0 "=r"))]
12692   "ix86_match_ccmode (insn, CCGOCmode)
12693    && (TARGET_SHIFT1 || optimize_size)
12694    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12695   "shr{w}\t%0"
12696   [(set_attr "type" "ishift")
12697    (set_attr "length" "2")])
12698
12699 ;; This pattern can't accept a variable shift count, since shifts by
12700 ;; zero don't affect the flags.  We assume that shifts by constant
12701 ;; zero are optimized away.
12702 (define_insn "*lshrhi3_cmp"
12703   [(set (reg FLAGS_REG)
12704         (compare
12705           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12706                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12707           (const_int 0)))
12708    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12709         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12710   "ix86_match_ccmode (insn, CCGOCmode)
12711    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12712    && (optimize_size
12713        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12714   "shr{w}\t{%2, %0|%0, %2}"
12715   [(set_attr "type" "ishift")
12716    (set_attr "mode" "HI")])
12717
12718 (define_insn "*lshrhi3_cconly"
12719   [(set (reg FLAGS_REG)
12720         (compare
12721           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12722                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12723           (const_int 0)))
12724    (clobber (match_scratch:HI 0 "=r"))]
12725   "ix86_match_ccmode (insn, CCGOCmode)
12726    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12727    && (optimize_size
12728        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12729   "shr{w}\t{%2, %0|%0, %2}"
12730   [(set_attr "type" "ishift")
12731    (set_attr "mode" "HI")])
12732
12733 (define_expand "lshrqi3"
12734   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12735         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12736                      (match_operand:QI 2 "nonmemory_operand" "")))
12737    (clobber (reg:CC FLAGS_REG))]
12738   "TARGET_QIMODE_MATH"
12739   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12740
12741 (define_insn "*lshrqi3_1_one_bit"
12742   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12743         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12744                      (match_operand:QI 2 "const1_operand" "")))
12745    (clobber (reg:CC FLAGS_REG))]
12746   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12747    && (TARGET_SHIFT1 || optimize_size)"
12748   "shr{b}\t%0"
12749   [(set_attr "type" "ishift")
12750    (set (attr "length")
12751      (if_then_else (match_operand 0 "register_operand" "")
12752         (const_string "2")
12753         (const_string "*")))])
12754
12755 (define_insn "*lshrqi3_1_one_bit_slp"
12756   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12757         (lshiftrt:QI (match_dup 0)
12758                      (match_operand:QI 1 "const1_operand" "")))
12759    (clobber (reg:CC FLAGS_REG))]
12760   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12761    && (TARGET_SHIFT1 || optimize_size)"
12762   "shr{b}\t%0"
12763   [(set_attr "type" "ishift1")
12764    (set (attr "length")
12765      (if_then_else (match_operand 0 "register_operand" "")
12766         (const_string "2")
12767         (const_string "*")))])
12768
12769 (define_insn "*lshrqi3_1"
12770   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12771         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12772                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12773    (clobber (reg:CC FLAGS_REG))]
12774   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12775   "@
12776    shr{b}\t{%2, %0|%0, %2}
12777    shr{b}\t{%b2, %0|%0, %b2}"
12778   [(set_attr "type" "ishift")
12779    (set_attr "mode" "QI")])
12780
12781 (define_insn "*lshrqi3_1_slp"
12782   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12783         (lshiftrt:QI (match_dup 0)
12784                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12785    (clobber (reg:CC FLAGS_REG))]
12786   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12787    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12788   "@
12789    shr{b}\t{%1, %0|%0, %1}
12790    shr{b}\t{%b1, %0|%0, %b1}"
12791   [(set_attr "type" "ishift1")
12792    (set_attr "mode" "QI")])
12793
12794 ;; This pattern can't accept a variable shift count, since shifts by
12795 ;; zero don't affect the flags.  We assume that shifts by constant
12796 ;; zero are optimized away.
12797 (define_insn "*lshrqi2_one_bit_cmp"
12798   [(set (reg FLAGS_REG)
12799         (compare
12800           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12801                        (match_operand:QI 2 "const1_operand" ""))
12802           (const_int 0)))
12803    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12804         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12805   "ix86_match_ccmode (insn, CCGOCmode)
12806    && (TARGET_SHIFT1 || optimize_size)
12807    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12808   "shr{b}\t%0"
12809   [(set_attr "type" "ishift")
12810    (set (attr "length")
12811      (if_then_else (match_operand:SI 0 "register_operand" "")
12812         (const_string "2")
12813         (const_string "*")))])
12814
12815 (define_insn "*lshrqi2_one_bit_cconly"
12816   [(set (reg FLAGS_REG)
12817         (compare
12818           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12819                        (match_operand:QI 2 "const1_operand" ""))
12820           (const_int 0)))
12821    (clobber (match_scratch:QI 0 "=q"))]
12822   "ix86_match_ccmode (insn, CCGOCmode)
12823    && (TARGET_SHIFT1 || optimize_size)
12824    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12825   "shr{b}\t%0"
12826   [(set_attr "type" "ishift")
12827    (set_attr "length" "2")])
12828
12829 ;; This pattern can't accept a variable shift count, since shifts by
12830 ;; zero don't affect the flags.  We assume that shifts by constant
12831 ;; zero are optimized away.
12832 (define_insn "*lshrqi2_cmp"
12833   [(set (reg FLAGS_REG)
12834         (compare
12835           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12836                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12837           (const_int 0)))
12838    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12839         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12840   "ix86_match_ccmode (insn, CCGOCmode)
12841    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12842    && (optimize_size
12843        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12844   "shr{b}\t{%2, %0|%0, %2}"
12845   [(set_attr "type" "ishift")
12846    (set_attr "mode" "QI")])
12847
12848 (define_insn "*lshrqi2_cconly"
12849   [(set (reg FLAGS_REG)
12850         (compare
12851           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12852                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12853           (const_int 0)))
12854    (clobber (match_scratch:QI 0 "=q"))]
12855   "ix86_match_ccmode (insn, CCGOCmode)
12856    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12857    && (optimize_size
12858        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12859   "shr{b}\t{%2, %0|%0, %2}"
12860   [(set_attr "type" "ishift")
12861    (set_attr "mode" "QI")])
12862 \f
12863 ;; Rotate instructions
12864
12865 (define_expand "rotldi3"
12866   [(set (match_operand:DI 0 "shiftdi_operand" "")
12867         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12868                    (match_operand:QI 2 "nonmemory_operand" "")))
12869    (clobber (reg:CC FLAGS_REG))]
12870  ""
12871 {
12872   if (TARGET_64BIT)
12873     {
12874       ix86_expand_binary_operator (ROTATE, DImode, operands);
12875       DONE;
12876     }
12877   if (!const_1_to_31_operand (operands[2], VOIDmode))
12878     FAIL;
12879   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12880   DONE;
12881 })
12882
12883 ;; Implement rotation using two double-precision shift instructions
12884 ;; and a scratch register.
12885 (define_insn_and_split "ix86_rotldi3"
12886  [(set (match_operand:DI 0 "register_operand" "=r")
12887        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12888                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12889   (clobber (reg:CC FLAGS_REG))
12890   (clobber (match_scratch:SI 3 "=&r"))]
12891  "!TARGET_64BIT"
12892  ""
12893  "&& reload_completed"
12894  [(set (match_dup 3) (match_dup 4))
12895   (parallel
12896    [(set (match_dup 4)
12897          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12898                  (lshiftrt:SI (match_dup 5)
12899                               (minus:QI (const_int 32) (match_dup 2)))))
12900     (clobber (reg:CC FLAGS_REG))])
12901   (parallel
12902    [(set (match_dup 5)
12903          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12904                  (lshiftrt:SI (match_dup 3)
12905                               (minus:QI (const_int 32) (match_dup 2)))))
12906     (clobber (reg:CC FLAGS_REG))])]
12907  "split_di (operands, 1, operands + 4, operands + 5);")
12908
12909 (define_insn "*rotlsi3_1_one_bit_rex64"
12910   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12911         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12912                    (match_operand:QI 2 "const1_operand" "")))
12913    (clobber (reg:CC FLAGS_REG))]
12914   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12915    && (TARGET_SHIFT1 || optimize_size)"
12916   "rol{q}\t%0"
12917   [(set_attr "type" "rotate")
12918    (set (attr "length")
12919      (if_then_else (match_operand:DI 0 "register_operand" "")
12920         (const_string "2")
12921         (const_string "*")))])
12922
12923 (define_insn "*rotldi3_1_rex64"
12924   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12925         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12926                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12927    (clobber (reg:CC FLAGS_REG))]
12928   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12929   "@
12930    rol{q}\t{%2, %0|%0, %2}
12931    rol{q}\t{%b2, %0|%0, %b2}"
12932   [(set_attr "type" "rotate")
12933    (set_attr "mode" "DI")])
12934
12935 (define_expand "rotlsi3"
12936   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12937         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12938                    (match_operand:QI 2 "nonmemory_operand" "")))
12939    (clobber (reg:CC FLAGS_REG))]
12940   ""
12941   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12942
12943 (define_insn "*rotlsi3_1_one_bit"
12944   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12945         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12946                    (match_operand:QI 2 "const1_operand" "")))
12947    (clobber (reg:CC FLAGS_REG))]
12948   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12949    && (TARGET_SHIFT1 || optimize_size)"
12950   "rol{l}\t%0"
12951   [(set_attr "type" "rotate")
12952    (set (attr "length")
12953      (if_then_else (match_operand:SI 0 "register_operand" "")
12954         (const_string "2")
12955         (const_string "*")))])
12956
12957 (define_insn "*rotlsi3_1_one_bit_zext"
12958   [(set (match_operand:DI 0 "register_operand" "=r")
12959         (zero_extend:DI
12960           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12961                      (match_operand:QI 2 "const1_operand" ""))))
12962    (clobber (reg:CC FLAGS_REG))]
12963   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12964    && (TARGET_SHIFT1 || optimize_size)"
12965   "rol{l}\t%k0"
12966   [(set_attr "type" "rotate")
12967    (set_attr "length" "2")])
12968
12969 (define_insn "*rotlsi3_1"
12970   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12971         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12972                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12973    (clobber (reg:CC FLAGS_REG))]
12974   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12975   "@
12976    rol{l}\t{%2, %0|%0, %2}
12977    rol{l}\t{%b2, %0|%0, %b2}"
12978   [(set_attr "type" "rotate")
12979    (set_attr "mode" "SI")])
12980
12981 (define_insn "*rotlsi3_1_zext"
12982   [(set (match_operand:DI 0 "register_operand" "=r,r")
12983         (zero_extend:DI
12984           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12985                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12986    (clobber (reg:CC FLAGS_REG))]
12987   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12988   "@
12989    rol{l}\t{%2, %k0|%k0, %2}
12990    rol{l}\t{%b2, %k0|%k0, %b2}"
12991   [(set_attr "type" "rotate")
12992    (set_attr "mode" "SI")])
12993
12994 (define_expand "rotlhi3"
12995   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12996         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12997                    (match_operand:QI 2 "nonmemory_operand" "")))
12998    (clobber (reg:CC FLAGS_REG))]
12999   "TARGET_HIMODE_MATH"
13000   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13001
13002 (define_insn "*rotlhi3_1_one_bit"
13003   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13004         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13005                    (match_operand:QI 2 "const1_operand" "")))
13006    (clobber (reg:CC FLAGS_REG))]
13007   "ix86_binary_operator_ok (ROTATE, HImode, operands)
13008    && (TARGET_SHIFT1 || optimize_size)"
13009   "rol{w}\t%0"
13010   [(set_attr "type" "rotate")
13011    (set (attr "length")
13012      (if_then_else (match_operand 0 "register_operand" "")
13013         (const_string "2")
13014         (const_string "*")))])
13015
13016 (define_insn "*rotlhi3_1"
13017   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13018         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13019                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13020    (clobber (reg:CC FLAGS_REG))]
13021   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13022   "@
13023    rol{w}\t{%2, %0|%0, %2}
13024    rol{w}\t{%b2, %0|%0, %b2}"
13025   [(set_attr "type" "rotate")
13026    (set_attr "mode" "HI")])
13027
13028 (define_split
13029  [(set (match_operand:HI 0 "register_operand" "")
13030        (rotate:HI (match_dup 0) (const_int 8)))
13031   (clobber (reg:CC FLAGS_REG))]
13032  "reload_completed"
13033  [(parallel [(set (strict_low_part (match_dup 0))
13034                   (bswap:HI (match_dup 0)))
13035              (clobber (reg:CC FLAGS_REG))])]
13036  "")
13037
13038 (define_expand "rotlqi3"
13039   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13040         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13041                    (match_operand:QI 2 "nonmemory_operand" "")))
13042    (clobber (reg:CC FLAGS_REG))]
13043   "TARGET_QIMODE_MATH"
13044   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13045
13046 (define_insn "*rotlqi3_1_one_bit_slp"
13047   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13048         (rotate:QI (match_dup 0)
13049                    (match_operand:QI 1 "const1_operand" "")))
13050    (clobber (reg:CC FLAGS_REG))]
13051   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13052    && (TARGET_SHIFT1 || optimize_size)"
13053   "rol{b}\t%0"
13054   [(set_attr "type" "rotate1")
13055    (set (attr "length")
13056      (if_then_else (match_operand 0 "register_operand" "")
13057         (const_string "2")
13058         (const_string "*")))])
13059
13060 (define_insn "*rotlqi3_1_one_bit"
13061   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13062         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13063                    (match_operand:QI 2 "const1_operand" "")))
13064    (clobber (reg:CC FLAGS_REG))]
13065   "ix86_binary_operator_ok (ROTATE, QImode, operands)
13066    && (TARGET_SHIFT1 || optimize_size)"
13067   "rol{b}\t%0"
13068   [(set_attr "type" "rotate")
13069    (set (attr "length")
13070      (if_then_else (match_operand 0 "register_operand" "")
13071         (const_string "2")
13072         (const_string "*")))])
13073
13074 (define_insn "*rotlqi3_1_slp"
13075   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13076         (rotate:QI (match_dup 0)
13077                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13078    (clobber (reg:CC FLAGS_REG))]
13079   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13080    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13081   "@
13082    rol{b}\t{%1, %0|%0, %1}
13083    rol{b}\t{%b1, %0|%0, %b1}"
13084   [(set_attr "type" "rotate1")
13085    (set_attr "mode" "QI")])
13086
13087 (define_insn "*rotlqi3_1"
13088   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13089         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13090                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13091    (clobber (reg:CC FLAGS_REG))]
13092   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13093   "@
13094    rol{b}\t{%2, %0|%0, %2}
13095    rol{b}\t{%b2, %0|%0, %b2}"
13096   [(set_attr "type" "rotate")
13097    (set_attr "mode" "QI")])
13098
13099 (define_expand "rotrdi3"
13100   [(set (match_operand:DI 0 "shiftdi_operand" "")
13101         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13102                    (match_operand:QI 2 "nonmemory_operand" "")))
13103    (clobber (reg:CC FLAGS_REG))]
13104  ""
13105 {
13106   if (TARGET_64BIT)
13107     {
13108       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13109       DONE;
13110     }
13111   if (!const_1_to_31_operand (operands[2], VOIDmode))
13112     FAIL;
13113   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13114   DONE;
13115 })
13116
13117 ;; Implement rotation using two double-precision shift instructions
13118 ;; and a scratch register.
13119 (define_insn_and_split "ix86_rotrdi3"
13120  [(set (match_operand:DI 0 "register_operand" "=r")
13121        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13122                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13123   (clobber (reg:CC FLAGS_REG))
13124   (clobber (match_scratch:SI 3 "=&r"))]
13125  "!TARGET_64BIT"
13126  ""
13127  "&& reload_completed"
13128  [(set (match_dup 3) (match_dup 4))
13129   (parallel
13130    [(set (match_dup 4)
13131          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13132                  (ashift:SI (match_dup 5)
13133                             (minus:QI (const_int 32) (match_dup 2)))))
13134     (clobber (reg:CC FLAGS_REG))])
13135   (parallel
13136    [(set (match_dup 5)
13137          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13138                  (ashift:SI (match_dup 3)
13139                             (minus:QI (const_int 32) (match_dup 2)))))
13140     (clobber (reg:CC FLAGS_REG))])]
13141  "split_di (operands, 1, operands + 4, operands + 5);")
13142
13143 (define_insn "*rotrdi3_1_one_bit_rex64"
13144   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13145         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13146                      (match_operand:QI 2 "const1_operand" "")))
13147    (clobber (reg:CC FLAGS_REG))]
13148   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
13149    && (TARGET_SHIFT1 || optimize_size)"
13150   "ror{q}\t%0"
13151   [(set_attr "type" "rotate")
13152    (set (attr "length")
13153      (if_then_else (match_operand:DI 0 "register_operand" "")
13154         (const_string "2")
13155         (const_string "*")))])
13156
13157 (define_insn "*rotrdi3_1_rex64"
13158   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13159         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13160                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13161    (clobber (reg:CC FLAGS_REG))]
13162   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13163   "@
13164    ror{q}\t{%2, %0|%0, %2}
13165    ror{q}\t{%b2, %0|%0, %b2}"
13166   [(set_attr "type" "rotate")
13167    (set_attr "mode" "DI")])
13168
13169 (define_expand "rotrsi3"
13170   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13171         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13172                      (match_operand:QI 2 "nonmemory_operand" "")))
13173    (clobber (reg:CC FLAGS_REG))]
13174   ""
13175   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13176
13177 (define_insn "*rotrsi3_1_one_bit"
13178   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13179         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13180                      (match_operand:QI 2 "const1_operand" "")))
13181    (clobber (reg:CC FLAGS_REG))]
13182   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
13183    && (TARGET_SHIFT1 || optimize_size)"
13184   "ror{l}\t%0"
13185   [(set_attr "type" "rotate")
13186    (set (attr "length")
13187      (if_then_else (match_operand:SI 0 "register_operand" "")
13188         (const_string "2")
13189         (const_string "*")))])
13190
13191 (define_insn "*rotrsi3_1_one_bit_zext"
13192   [(set (match_operand:DI 0 "register_operand" "=r")
13193         (zero_extend:DI
13194           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13195                        (match_operand:QI 2 "const1_operand" ""))))
13196    (clobber (reg:CC FLAGS_REG))]
13197   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
13198    && (TARGET_SHIFT1 || optimize_size)"
13199   "ror{l}\t%k0"
13200   [(set_attr "type" "rotate")
13201    (set (attr "length")
13202      (if_then_else (match_operand:SI 0 "register_operand" "")
13203         (const_string "2")
13204         (const_string "*")))])
13205
13206 (define_insn "*rotrsi3_1"
13207   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13208         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13209                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13210    (clobber (reg:CC FLAGS_REG))]
13211   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13212   "@
13213    ror{l}\t{%2, %0|%0, %2}
13214    ror{l}\t{%b2, %0|%0, %b2}"
13215   [(set_attr "type" "rotate")
13216    (set_attr "mode" "SI")])
13217
13218 (define_insn "*rotrsi3_1_zext"
13219   [(set (match_operand:DI 0 "register_operand" "=r,r")
13220         (zero_extend:DI
13221           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13222                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13223    (clobber (reg:CC FLAGS_REG))]
13224   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13225   "@
13226    ror{l}\t{%2, %k0|%k0, %2}
13227    ror{l}\t{%b2, %k0|%k0, %b2}"
13228   [(set_attr "type" "rotate")
13229    (set_attr "mode" "SI")])
13230
13231 (define_expand "rotrhi3"
13232   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13233         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13234                      (match_operand:QI 2 "nonmemory_operand" "")))
13235    (clobber (reg:CC FLAGS_REG))]
13236   "TARGET_HIMODE_MATH"
13237   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13238
13239 (define_insn "*rotrhi3_one_bit"
13240   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13241         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13242                      (match_operand:QI 2 "const1_operand" "")))
13243    (clobber (reg:CC FLAGS_REG))]
13244   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
13245    && (TARGET_SHIFT1 || optimize_size)"
13246   "ror{w}\t%0"
13247   [(set_attr "type" "rotate")
13248    (set (attr "length")
13249      (if_then_else (match_operand 0 "register_operand" "")
13250         (const_string "2")
13251         (const_string "*")))])
13252
13253 (define_insn "*rotrhi3_1"
13254   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13255         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13256                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13257    (clobber (reg:CC FLAGS_REG))]
13258   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13259   "@
13260    ror{w}\t{%2, %0|%0, %2}
13261    ror{w}\t{%b2, %0|%0, %b2}"
13262   [(set_attr "type" "rotate")
13263    (set_attr "mode" "HI")])
13264
13265 (define_split
13266  [(set (match_operand:HI 0 "register_operand" "")
13267        (rotatert:HI (match_dup 0) (const_int 8)))
13268   (clobber (reg:CC FLAGS_REG))]
13269  "reload_completed"
13270  [(parallel [(set (strict_low_part (match_dup 0))
13271                   (bswap:HI (match_dup 0)))
13272              (clobber (reg:CC FLAGS_REG))])]
13273  "")
13274
13275 (define_expand "rotrqi3"
13276   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13277         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13278                      (match_operand:QI 2 "nonmemory_operand" "")))
13279    (clobber (reg:CC FLAGS_REG))]
13280   "TARGET_QIMODE_MATH"
13281   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13282
13283 (define_insn "*rotrqi3_1_one_bit"
13284   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13285         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13286                      (match_operand:QI 2 "const1_operand" "")))
13287    (clobber (reg:CC FLAGS_REG))]
13288   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
13289    && (TARGET_SHIFT1 || optimize_size)"
13290   "ror{b}\t%0"
13291   [(set_attr "type" "rotate")
13292    (set (attr "length")
13293      (if_then_else (match_operand 0 "register_operand" "")
13294         (const_string "2")
13295         (const_string "*")))])
13296
13297 (define_insn "*rotrqi3_1_one_bit_slp"
13298   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13299         (rotatert:QI (match_dup 0)
13300                      (match_operand:QI 1 "const1_operand" "")))
13301    (clobber (reg:CC FLAGS_REG))]
13302   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13303    && (TARGET_SHIFT1 || optimize_size)"
13304   "ror{b}\t%0"
13305   [(set_attr "type" "rotate1")
13306    (set (attr "length")
13307      (if_then_else (match_operand 0 "register_operand" "")
13308         (const_string "2")
13309         (const_string "*")))])
13310
13311 (define_insn "*rotrqi3_1"
13312   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13313         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13314                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13315    (clobber (reg:CC FLAGS_REG))]
13316   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13317   "@
13318    ror{b}\t{%2, %0|%0, %2}
13319    ror{b}\t{%b2, %0|%0, %b2}"
13320   [(set_attr "type" "rotate")
13321    (set_attr "mode" "QI")])
13322
13323 (define_insn "*rotrqi3_1_slp"
13324   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13325         (rotatert:QI (match_dup 0)
13326                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13327    (clobber (reg:CC FLAGS_REG))]
13328   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13329    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13330   "@
13331    ror{b}\t{%1, %0|%0, %1}
13332    ror{b}\t{%b1, %0|%0, %b1}"
13333   [(set_attr "type" "rotate1")
13334    (set_attr "mode" "QI")])
13335 \f
13336 ;; Bit set / bit test instructions
13337
13338 (define_expand "extv"
13339   [(set (match_operand:SI 0 "register_operand" "")
13340         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13341                          (match_operand:SI 2 "const8_operand" "")
13342                          (match_operand:SI 3 "const8_operand" "")))]
13343   ""
13344 {
13345   /* Handle extractions from %ah et al.  */
13346   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13347     FAIL;
13348
13349   /* From mips.md: extract_bit_field doesn't verify that our source
13350      matches the predicate, so check it again here.  */
13351   if (! ext_register_operand (operands[1], VOIDmode))
13352     FAIL;
13353 })
13354
13355 (define_expand "extzv"
13356   [(set (match_operand:SI 0 "register_operand" "")
13357         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13358                          (match_operand:SI 2 "const8_operand" "")
13359                          (match_operand:SI 3 "const8_operand" "")))]
13360   ""
13361 {
13362   /* Handle extractions from %ah et al.  */
13363   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13364     FAIL;
13365
13366   /* From mips.md: extract_bit_field doesn't verify that our source
13367      matches the predicate, so check it again here.  */
13368   if (! ext_register_operand (operands[1], VOIDmode))
13369     FAIL;
13370 })
13371
13372 (define_expand "insv"
13373   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13374                       (match_operand 1 "const8_operand" "")
13375                       (match_operand 2 "const8_operand" ""))
13376         (match_operand 3 "register_operand" ""))]
13377   ""
13378 {
13379   /* Handle insertions to %ah et al.  */
13380   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13381     FAIL;
13382
13383   /* From mips.md: insert_bit_field doesn't verify that our source
13384      matches the predicate, so check it again here.  */
13385   if (! ext_register_operand (operands[0], VOIDmode))
13386     FAIL;
13387
13388   if (TARGET_64BIT)
13389     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13390   else
13391     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13392
13393   DONE;
13394 })
13395
13396 ;; %%% bts, btr, btc, bt.
13397 ;; In general these instructions are *slow* when applied to memory,
13398 ;; since they enforce atomic operation.  When applied to registers,
13399 ;; it depends on the cpu implementation.  They're never faster than
13400 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13401 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13402 ;; within the instruction itself, so operating on bits in the high
13403 ;; 32-bits of a register becomes easier.
13404 ;;
13405 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13406 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13407 ;; negdf respectively, so they can never be disabled entirely.
13408
13409 (define_insn "*btsq"
13410   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13411                          (const_int 1)
13412                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13413         (const_int 1))
13414    (clobber (reg:CC FLAGS_REG))]
13415   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13416   "bts{q} %1,%0"
13417   [(set_attr "type" "alu1")])
13418
13419 (define_insn "*btrq"
13420   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13421                          (const_int 1)
13422                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13423         (const_int 0))
13424    (clobber (reg:CC FLAGS_REG))]
13425   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13426   "btr{q} %1,%0"
13427   [(set_attr "type" "alu1")])
13428
13429 (define_insn "*btcq"
13430   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13431                          (const_int 1)
13432                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13433         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13434    (clobber (reg:CC FLAGS_REG))]
13435   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13436   "btc{q} %1,%0"
13437   [(set_attr "type" "alu1")])
13438
13439 ;; Allow Nocona to avoid these instructions if a register is available.
13440
13441 (define_peephole2
13442   [(match_scratch:DI 2 "r")
13443    (parallel [(set (zero_extract:DI
13444                      (match_operand:DI 0 "register_operand" "")
13445                      (const_int 1)
13446                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13447                    (const_int 1))
13448               (clobber (reg:CC FLAGS_REG))])]
13449   "TARGET_64BIT && !TARGET_USE_BT"
13450   [(const_int 0)]
13451 {
13452   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13453   rtx op1;
13454
13455   if (HOST_BITS_PER_WIDE_INT >= 64)
13456     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13457   else if (i < HOST_BITS_PER_WIDE_INT)
13458     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13459   else
13460     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13461
13462   op1 = immed_double_const (lo, hi, DImode);
13463   if (i >= 31)
13464     {
13465       emit_move_insn (operands[2], op1);
13466       op1 = operands[2];
13467     }
13468
13469   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13470   DONE;
13471 })
13472
13473 (define_peephole2
13474   [(match_scratch:DI 2 "r")
13475    (parallel [(set (zero_extract:DI
13476                      (match_operand:DI 0 "register_operand" "")
13477                      (const_int 1)
13478                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13479                    (const_int 0))
13480               (clobber (reg:CC FLAGS_REG))])]
13481   "TARGET_64BIT && !TARGET_USE_BT"
13482   [(const_int 0)]
13483 {
13484   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13485   rtx op1;
13486
13487   if (HOST_BITS_PER_WIDE_INT >= 64)
13488     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13489   else if (i < HOST_BITS_PER_WIDE_INT)
13490     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13491   else
13492     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13493
13494   op1 = immed_double_const (~lo, ~hi, DImode);
13495   if (i >= 32)
13496     {
13497       emit_move_insn (operands[2], op1);
13498       op1 = operands[2];
13499     }
13500
13501   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13502   DONE;
13503 })
13504
13505 (define_peephole2
13506   [(match_scratch:DI 2 "r")
13507    (parallel [(set (zero_extract:DI
13508                      (match_operand:DI 0 "register_operand" "")
13509                      (const_int 1)
13510                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13511               (not:DI (zero_extract:DI
13512                         (match_dup 0) (const_int 1) (match_dup 1))))
13513               (clobber (reg:CC FLAGS_REG))])]
13514   "TARGET_64BIT && !TARGET_USE_BT"
13515   [(const_int 0)]
13516 {
13517   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13518   rtx op1;
13519
13520   if (HOST_BITS_PER_WIDE_INT >= 64)
13521     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13522   else if (i < HOST_BITS_PER_WIDE_INT)
13523     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13524   else
13525     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13526
13527   op1 = immed_double_const (lo, hi, DImode);
13528   if (i >= 31)
13529     {
13530       emit_move_insn (operands[2], op1);
13531       op1 = operands[2];
13532     }
13533
13534   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13535   DONE;
13536 })
13537 \f
13538 ;; Store-flag instructions.
13539
13540 ;; For all sCOND expanders, also expand the compare or test insn that
13541 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13542
13543 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13544 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13545 ;; way, which can later delete the movzx if only QImode is needed.
13546
13547 (define_expand "seq"
13548   [(set (match_operand:QI 0 "register_operand" "")
13549         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13550   ""
13551   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13552
13553 (define_expand "sne"
13554   [(set (match_operand:QI 0 "register_operand" "")
13555         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13556   ""
13557   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13558
13559 (define_expand "sgt"
13560   [(set (match_operand:QI 0 "register_operand" "")
13561         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13562   ""
13563   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13564
13565 (define_expand "sgtu"
13566   [(set (match_operand:QI 0 "register_operand" "")
13567         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13568   ""
13569   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13570
13571 (define_expand "slt"
13572   [(set (match_operand:QI 0 "register_operand" "")
13573         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13574   ""
13575   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13576
13577 (define_expand "sltu"
13578   [(set (match_operand:QI 0 "register_operand" "")
13579         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13580   ""
13581   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13582
13583 (define_expand "sge"
13584   [(set (match_operand:QI 0 "register_operand" "")
13585         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13586   ""
13587   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13588
13589 (define_expand "sgeu"
13590   [(set (match_operand:QI 0 "register_operand" "")
13591         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13592   ""
13593   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13594
13595 (define_expand "sle"
13596   [(set (match_operand:QI 0 "register_operand" "")
13597         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13598   ""
13599   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13600
13601 (define_expand "sleu"
13602   [(set (match_operand:QI 0 "register_operand" "")
13603         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13604   ""
13605   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13606
13607 (define_expand "sunordered"
13608   [(set (match_operand:QI 0 "register_operand" "")
13609         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13610   "TARGET_80387 || TARGET_SSE"
13611   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13612
13613 (define_expand "sordered"
13614   [(set (match_operand:QI 0 "register_operand" "")
13615         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13616   "TARGET_80387"
13617   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13618
13619 (define_expand "suneq"
13620   [(set (match_operand:QI 0 "register_operand" "")
13621         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13622   "TARGET_80387 || TARGET_SSE"
13623   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13624
13625 (define_expand "sunge"
13626   [(set (match_operand:QI 0 "register_operand" "")
13627         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13628   "TARGET_80387 || TARGET_SSE"
13629   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13630
13631 (define_expand "sungt"
13632   [(set (match_operand:QI 0 "register_operand" "")
13633         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13634   "TARGET_80387 || TARGET_SSE"
13635   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13636
13637 (define_expand "sunle"
13638   [(set (match_operand:QI 0 "register_operand" "")
13639         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13640   "TARGET_80387 || TARGET_SSE"
13641   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13642
13643 (define_expand "sunlt"
13644   [(set (match_operand:QI 0 "register_operand" "")
13645         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13646   "TARGET_80387 || TARGET_SSE"
13647   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13648
13649 (define_expand "sltgt"
13650   [(set (match_operand:QI 0 "register_operand" "")
13651         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13652   "TARGET_80387 || TARGET_SSE"
13653   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13654
13655 (define_insn "*setcc_1"
13656   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13657         (match_operator:QI 1 "ix86_comparison_operator"
13658           [(reg FLAGS_REG) (const_int 0)]))]
13659   ""
13660   "set%C1\t%0"
13661   [(set_attr "type" "setcc")
13662    (set_attr "mode" "QI")])
13663
13664 (define_insn "*setcc_2"
13665   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13666         (match_operator:QI 1 "ix86_comparison_operator"
13667           [(reg FLAGS_REG) (const_int 0)]))]
13668   ""
13669   "set%C1\t%0"
13670   [(set_attr "type" "setcc")
13671    (set_attr "mode" "QI")])
13672
13673 ;; In general it is not safe to assume too much about CCmode registers,
13674 ;; so simplify-rtx stops when it sees a second one.  Under certain
13675 ;; conditions this is safe on x86, so help combine not create
13676 ;;
13677 ;;      seta    %al
13678 ;;      testb   %al, %al
13679 ;;      sete    %al
13680
13681 (define_split
13682   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13683         (ne:QI (match_operator 1 "ix86_comparison_operator"
13684                  [(reg FLAGS_REG) (const_int 0)])
13685             (const_int 0)))]
13686   ""
13687   [(set (match_dup 0) (match_dup 1))]
13688 {
13689   PUT_MODE (operands[1], QImode);
13690 })
13691
13692 (define_split
13693   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13694         (ne:QI (match_operator 1 "ix86_comparison_operator"
13695                  [(reg FLAGS_REG) (const_int 0)])
13696             (const_int 0)))]
13697   ""
13698   [(set (match_dup 0) (match_dup 1))]
13699 {
13700   PUT_MODE (operands[1], QImode);
13701 })
13702
13703 (define_split
13704   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13705         (eq:QI (match_operator 1 "ix86_comparison_operator"
13706                  [(reg FLAGS_REG) (const_int 0)])
13707             (const_int 0)))]
13708   ""
13709   [(set (match_dup 0) (match_dup 1))]
13710 {
13711   rtx new_op1 = copy_rtx (operands[1]);
13712   operands[1] = new_op1;
13713   PUT_MODE (new_op1, QImode);
13714   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13715                                              GET_MODE (XEXP (new_op1, 0))));
13716
13717   /* Make sure that (a) the CCmode we have for the flags is strong
13718      enough for the reversed compare or (b) we have a valid FP compare.  */
13719   if (! ix86_comparison_operator (new_op1, VOIDmode))
13720     FAIL;
13721 })
13722
13723 (define_split
13724   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13725         (eq:QI (match_operator 1 "ix86_comparison_operator"
13726                  [(reg FLAGS_REG) (const_int 0)])
13727             (const_int 0)))]
13728   ""
13729   [(set (match_dup 0) (match_dup 1))]
13730 {
13731   rtx new_op1 = copy_rtx (operands[1]);
13732   operands[1] = new_op1;
13733   PUT_MODE (new_op1, QImode);
13734   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13735                                              GET_MODE (XEXP (new_op1, 0))));
13736
13737   /* Make sure that (a) the CCmode we have for the flags is strong
13738      enough for the reversed compare or (b) we have a valid FP compare.  */
13739   if (! ix86_comparison_operator (new_op1, VOIDmode))
13740     FAIL;
13741 })
13742
13743 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13744 ;; subsequent logical operations are used to imitate conditional moves.
13745 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13746 ;; it directly.
13747
13748 (define_insn "*sse_setccsf"
13749   [(set (match_operand:SF 0 "register_operand" "=x")
13750         (match_operator:SF 1 "sse_comparison_operator"
13751           [(match_operand:SF 2 "register_operand" "0")
13752            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13753   "TARGET_SSE"
13754   "cmp%D1ss\t{%3, %0|%0, %3}"
13755   [(set_attr "type" "ssecmp")
13756    (set_attr "mode" "SF")])
13757
13758 (define_insn "*sse_setccdf"
13759   [(set (match_operand:DF 0 "register_operand" "=x")
13760         (match_operator:DF 1 "sse_comparison_operator"
13761           [(match_operand:DF 2 "register_operand" "0")
13762            (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
13763   "TARGET_SSE2"
13764   "cmp%D1sd\t{%3, %0|%0, %3}"
13765   [(set_attr "type" "ssecmp")
13766    (set_attr "mode" "DF")])
13767 \f
13768 ;; Basic conditional jump instructions.
13769 ;; We ignore the overflow flag for signed branch instructions.
13770
13771 ;; For all bCOND expanders, also expand the compare or test insn that
13772 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13773
13774 (define_expand "beq"
13775   [(set (pc)
13776         (if_then_else (match_dup 1)
13777                       (label_ref (match_operand 0 "" ""))
13778                       (pc)))]
13779   ""
13780   "ix86_expand_branch (EQ, operands[0]); DONE;")
13781
13782 (define_expand "bne"
13783   [(set (pc)
13784         (if_then_else (match_dup 1)
13785                       (label_ref (match_operand 0 "" ""))
13786                       (pc)))]
13787   ""
13788   "ix86_expand_branch (NE, operands[0]); DONE;")
13789
13790 (define_expand "bgt"
13791   [(set (pc)
13792         (if_then_else (match_dup 1)
13793                       (label_ref (match_operand 0 "" ""))
13794                       (pc)))]
13795   ""
13796   "ix86_expand_branch (GT, operands[0]); DONE;")
13797
13798 (define_expand "bgtu"
13799   [(set (pc)
13800         (if_then_else (match_dup 1)
13801                       (label_ref (match_operand 0 "" ""))
13802                       (pc)))]
13803   ""
13804   "ix86_expand_branch (GTU, operands[0]); DONE;")
13805
13806 (define_expand "blt"
13807   [(set (pc)
13808         (if_then_else (match_dup 1)
13809                       (label_ref (match_operand 0 "" ""))
13810                       (pc)))]
13811   ""
13812   "ix86_expand_branch (LT, operands[0]); DONE;")
13813
13814 (define_expand "bltu"
13815   [(set (pc)
13816         (if_then_else (match_dup 1)
13817                       (label_ref (match_operand 0 "" ""))
13818                       (pc)))]
13819   ""
13820   "ix86_expand_branch (LTU, operands[0]); DONE;")
13821
13822 (define_expand "bge"
13823   [(set (pc)
13824         (if_then_else (match_dup 1)
13825                       (label_ref (match_operand 0 "" ""))
13826                       (pc)))]
13827   ""
13828   "ix86_expand_branch (GE, operands[0]); DONE;")
13829
13830 (define_expand "bgeu"
13831   [(set (pc)
13832         (if_then_else (match_dup 1)
13833                       (label_ref (match_operand 0 "" ""))
13834                       (pc)))]
13835   ""
13836   "ix86_expand_branch (GEU, operands[0]); DONE;")
13837
13838 (define_expand "ble"
13839   [(set (pc)
13840         (if_then_else (match_dup 1)
13841                       (label_ref (match_operand 0 "" ""))
13842                       (pc)))]
13843   ""
13844   "ix86_expand_branch (LE, operands[0]); DONE;")
13845
13846 (define_expand "bleu"
13847   [(set (pc)
13848         (if_then_else (match_dup 1)
13849                       (label_ref (match_operand 0 "" ""))
13850                       (pc)))]
13851   ""
13852   "ix86_expand_branch (LEU, operands[0]); DONE;")
13853
13854 (define_expand "bunordered"
13855   [(set (pc)
13856         (if_then_else (match_dup 1)
13857                       (label_ref (match_operand 0 "" ""))
13858                       (pc)))]
13859   "TARGET_80387 || TARGET_SSE_MATH"
13860   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13861
13862 (define_expand "bordered"
13863   [(set (pc)
13864         (if_then_else (match_dup 1)
13865                       (label_ref (match_operand 0 "" ""))
13866                       (pc)))]
13867   "TARGET_80387 || TARGET_SSE_MATH"
13868   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13869
13870 (define_expand "buneq"
13871   [(set (pc)
13872         (if_then_else (match_dup 1)
13873                       (label_ref (match_operand 0 "" ""))
13874                       (pc)))]
13875   "TARGET_80387 || TARGET_SSE_MATH"
13876   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13877
13878 (define_expand "bunge"
13879   [(set (pc)
13880         (if_then_else (match_dup 1)
13881                       (label_ref (match_operand 0 "" ""))
13882                       (pc)))]
13883   "TARGET_80387 || TARGET_SSE_MATH"
13884   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13885
13886 (define_expand "bungt"
13887   [(set (pc)
13888         (if_then_else (match_dup 1)
13889                       (label_ref (match_operand 0 "" ""))
13890                       (pc)))]
13891   "TARGET_80387 || TARGET_SSE_MATH"
13892   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13893
13894 (define_expand "bunle"
13895   [(set (pc)
13896         (if_then_else (match_dup 1)
13897                       (label_ref (match_operand 0 "" ""))
13898                       (pc)))]
13899   "TARGET_80387 || TARGET_SSE_MATH"
13900   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13901
13902 (define_expand "bunlt"
13903   [(set (pc)
13904         (if_then_else (match_dup 1)
13905                       (label_ref (match_operand 0 "" ""))
13906                       (pc)))]
13907   "TARGET_80387 || TARGET_SSE_MATH"
13908   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13909
13910 (define_expand "bltgt"
13911   [(set (pc)
13912         (if_then_else (match_dup 1)
13913                       (label_ref (match_operand 0 "" ""))
13914                       (pc)))]
13915   "TARGET_80387 || TARGET_SSE_MATH"
13916   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13917
13918 (define_insn "*jcc_1"
13919   [(set (pc)
13920         (if_then_else (match_operator 1 "ix86_comparison_operator"
13921                                       [(reg FLAGS_REG) (const_int 0)])
13922                       (label_ref (match_operand 0 "" ""))
13923                       (pc)))]
13924   ""
13925   "%+j%C1\t%l0"
13926   [(set_attr "type" "ibr")
13927    (set_attr "modrm" "0")
13928    (set (attr "length")
13929            (if_then_else (and (ge (minus (match_dup 0) (pc))
13930                                   (const_int -126))
13931                               (lt (minus (match_dup 0) (pc))
13932                                   (const_int 128)))
13933              (const_int 2)
13934              (const_int 6)))])
13935
13936 (define_insn "*jcc_2"
13937   [(set (pc)
13938         (if_then_else (match_operator 1 "ix86_comparison_operator"
13939                                       [(reg FLAGS_REG) (const_int 0)])
13940                       (pc)
13941                       (label_ref (match_operand 0 "" ""))))]
13942   ""
13943   "%+j%c1\t%l0"
13944   [(set_attr "type" "ibr")
13945    (set_attr "modrm" "0")
13946    (set (attr "length")
13947            (if_then_else (and (ge (minus (match_dup 0) (pc))
13948                                   (const_int -126))
13949                               (lt (minus (match_dup 0) (pc))
13950                                   (const_int 128)))
13951              (const_int 2)
13952              (const_int 6)))])
13953
13954 ;; In general it is not safe to assume too much about CCmode registers,
13955 ;; so simplify-rtx stops when it sees a second one.  Under certain
13956 ;; conditions this is safe on x86, so help combine not create
13957 ;;
13958 ;;      seta    %al
13959 ;;      testb   %al, %al
13960 ;;      je      Lfoo
13961
13962 (define_split
13963   [(set (pc)
13964         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13965                                       [(reg FLAGS_REG) (const_int 0)])
13966                           (const_int 0))
13967                       (label_ref (match_operand 1 "" ""))
13968                       (pc)))]
13969   ""
13970   [(set (pc)
13971         (if_then_else (match_dup 0)
13972                       (label_ref (match_dup 1))
13973                       (pc)))]
13974 {
13975   PUT_MODE (operands[0], VOIDmode);
13976 })
13977
13978 (define_split
13979   [(set (pc)
13980         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13981                                       [(reg FLAGS_REG) (const_int 0)])
13982                           (const_int 0))
13983                       (label_ref (match_operand 1 "" ""))
13984                       (pc)))]
13985   ""
13986   [(set (pc)
13987         (if_then_else (match_dup 0)
13988                       (label_ref (match_dup 1))
13989                       (pc)))]
13990 {
13991   rtx new_op0 = copy_rtx (operands[0]);
13992   operands[0] = new_op0;
13993   PUT_MODE (new_op0, VOIDmode);
13994   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13995                                              GET_MODE (XEXP (new_op0, 0))));
13996
13997   /* Make sure that (a) the CCmode we have for the flags is strong
13998      enough for the reversed compare or (b) we have a valid FP compare.  */
13999   if (! ix86_comparison_operator (new_op0, VOIDmode))
14000     FAIL;
14001 })
14002
14003 ;; Define combination compare-and-branch fp compare instructions to use
14004 ;; during early optimization.  Splitting the operation apart early makes
14005 ;; for bad code when we want to reverse the operation.
14006
14007 (define_insn "*fp_jcc_1_mixed"
14008   [(set (pc)
14009         (if_then_else (match_operator 0 "comparison_operator"
14010                         [(match_operand 1 "register_operand" "f,x")
14011                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14012           (label_ref (match_operand 3 "" ""))
14013           (pc)))
14014    (clobber (reg:CCFP FPSR_REG))
14015    (clobber (reg:CCFP FLAGS_REG))]
14016   "TARGET_MIX_SSE_I387
14017    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14018    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14019    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14020   "#")
14021
14022 (define_insn "*fp_jcc_1_sse"
14023   [(set (pc)
14024         (if_then_else (match_operator 0 "comparison_operator"
14025                         [(match_operand 1 "register_operand" "x")
14026                          (match_operand 2 "nonimmediate_operand" "xm")])
14027           (label_ref (match_operand 3 "" ""))
14028           (pc)))
14029    (clobber (reg:CCFP FPSR_REG))
14030    (clobber (reg:CCFP FLAGS_REG))]
14031   "TARGET_SSE_MATH
14032    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14033    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14034    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14035   "#")
14036
14037 (define_insn "*fp_jcc_1_387"
14038   [(set (pc)
14039         (if_then_else (match_operator 0 "comparison_operator"
14040                         [(match_operand 1 "register_operand" "f")
14041                          (match_operand 2 "register_operand" "f")])
14042           (label_ref (match_operand 3 "" ""))
14043           (pc)))
14044    (clobber (reg:CCFP FPSR_REG))
14045    (clobber (reg:CCFP FLAGS_REG))]
14046   "TARGET_CMOVE && TARGET_80387
14047    && FLOAT_MODE_P (GET_MODE (operands[1]))
14048    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14049    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14050   "#")
14051
14052 (define_insn "*fp_jcc_2_mixed"
14053   [(set (pc)
14054         (if_then_else (match_operator 0 "comparison_operator"
14055                         [(match_operand 1 "register_operand" "f,x")
14056                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14057           (pc)
14058           (label_ref (match_operand 3 "" ""))))
14059    (clobber (reg:CCFP FPSR_REG))
14060    (clobber (reg:CCFP FLAGS_REG))]
14061   "TARGET_MIX_SSE_I387
14062    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14063    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14064    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14065   "#")
14066
14067 (define_insn "*fp_jcc_2_sse"
14068   [(set (pc)
14069         (if_then_else (match_operator 0 "comparison_operator"
14070                         [(match_operand 1 "register_operand" "x")
14071                          (match_operand 2 "nonimmediate_operand" "xm")])
14072           (pc)
14073           (label_ref (match_operand 3 "" ""))))
14074    (clobber (reg:CCFP FPSR_REG))
14075    (clobber (reg:CCFP FLAGS_REG))]
14076   "TARGET_SSE_MATH
14077    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14078    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14079    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14080   "#")
14081
14082 (define_insn "*fp_jcc_2_387"
14083   [(set (pc)
14084         (if_then_else (match_operator 0 "comparison_operator"
14085                         [(match_operand 1 "register_operand" "f")
14086                          (match_operand 2 "register_operand" "f")])
14087           (pc)
14088           (label_ref (match_operand 3 "" ""))))
14089    (clobber (reg:CCFP FPSR_REG))
14090    (clobber (reg:CCFP FLAGS_REG))]
14091   "TARGET_CMOVE && TARGET_80387
14092    && FLOAT_MODE_P (GET_MODE (operands[1]))
14093    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14094    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14095   "#")
14096
14097 (define_insn "*fp_jcc_3_387"
14098   [(set (pc)
14099         (if_then_else (match_operator 0 "comparison_operator"
14100                         [(match_operand 1 "register_operand" "f")
14101                          (match_operand 2 "nonimmediate_operand" "fm")])
14102           (label_ref (match_operand 3 "" ""))
14103           (pc)))
14104    (clobber (reg:CCFP FPSR_REG))
14105    (clobber (reg:CCFP FLAGS_REG))
14106    (clobber (match_scratch:HI 4 "=a"))]
14107   "TARGET_80387
14108    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14109    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14110    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14111    && SELECT_CC_MODE (GET_CODE (operands[0]),
14112                       operands[1], operands[2]) == CCFPmode
14113    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14114   "#")
14115
14116 (define_insn "*fp_jcc_4_387"
14117   [(set (pc)
14118         (if_then_else (match_operator 0 "comparison_operator"
14119                         [(match_operand 1 "register_operand" "f")
14120                          (match_operand 2 "nonimmediate_operand" "fm")])
14121           (pc)
14122           (label_ref (match_operand 3 "" ""))))
14123    (clobber (reg:CCFP FPSR_REG))
14124    (clobber (reg:CCFP FLAGS_REG))
14125    (clobber (match_scratch:HI 4 "=a"))]
14126   "TARGET_80387
14127    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14128    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14129    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14130    && SELECT_CC_MODE (GET_CODE (operands[0]),
14131                       operands[1], operands[2]) == CCFPmode
14132    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14133   "#")
14134
14135 (define_insn "*fp_jcc_5_387"
14136   [(set (pc)
14137         (if_then_else (match_operator 0 "comparison_operator"
14138                         [(match_operand 1 "register_operand" "f")
14139                          (match_operand 2 "register_operand" "f")])
14140           (label_ref (match_operand 3 "" ""))
14141           (pc)))
14142    (clobber (reg:CCFP FPSR_REG))
14143    (clobber (reg:CCFP FLAGS_REG))
14144    (clobber (match_scratch:HI 4 "=a"))]
14145   "TARGET_80387
14146    && FLOAT_MODE_P (GET_MODE (operands[1]))
14147    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14148    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14149   "#")
14150
14151 (define_insn "*fp_jcc_6_387"
14152   [(set (pc)
14153         (if_then_else (match_operator 0 "comparison_operator"
14154                         [(match_operand 1 "register_operand" "f")
14155                          (match_operand 2 "register_operand" "f")])
14156           (pc)
14157           (label_ref (match_operand 3 "" ""))))
14158    (clobber (reg:CCFP FPSR_REG))
14159    (clobber (reg:CCFP FLAGS_REG))
14160    (clobber (match_scratch:HI 4 "=a"))]
14161   "TARGET_80387
14162    && FLOAT_MODE_P (GET_MODE (operands[1]))
14163    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14164    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14165   "#")
14166
14167 (define_insn "*fp_jcc_7_387"
14168   [(set (pc)
14169         (if_then_else (match_operator 0 "comparison_operator"
14170                         [(match_operand 1 "register_operand" "f")
14171                          (match_operand 2 "const0_operand" "X")])
14172           (label_ref (match_operand 3 "" ""))
14173           (pc)))
14174    (clobber (reg:CCFP FPSR_REG))
14175    (clobber (reg:CCFP FLAGS_REG))
14176    (clobber (match_scratch:HI 4 "=a"))]
14177   "TARGET_80387
14178    && FLOAT_MODE_P (GET_MODE (operands[1]))
14179    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14180    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14181    && SELECT_CC_MODE (GET_CODE (operands[0]),
14182                       operands[1], operands[2]) == CCFPmode
14183    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14184   "#")
14185
14186 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14187 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14188 ;; with a precedence over other operators and is always put in the first
14189 ;; place. Swap condition and operands to match ficom instruction.
14190
14191 (define_insn "*fp_jcc_8<mode>_387"
14192   [(set (pc)
14193         (if_then_else (match_operator 0 "comparison_operator"
14194                         [(match_operator 1 "float_operator"
14195                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14196                            (match_operand 3 "register_operand" "f,f")])
14197           (label_ref (match_operand 4 "" ""))
14198           (pc)))
14199    (clobber (reg:CCFP FPSR_REG))
14200    (clobber (reg:CCFP FLAGS_REG))
14201    (clobber (match_scratch:HI 5 "=a,a"))]
14202   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14203    && FLOAT_MODE_P (GET_MODE (operands[3]))
14204    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14205    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14206    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14207    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14208   "#")
14209
14210 (define_split
14211   [(set (pc)
14212         (if_then_else (match_operator 0 "comparison_operator"
14213                         [(match_operand 1 "register_operand" "")
14214                          (match_operand 2 "nonimmediate_operand" "")])
14215           (match_operand 3 "" "")
14216           (match_operand 4 "" "")))
14217    (clobber (reg:CCFP FPSR_REG))
14218    (clobber (reg:CCFP FLAGS_REG))]
14219   "reload_completed"
14220   [(const_int 0)]
14221 {
14222   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14223                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14224   DONE;
14225 })
14226
14227 (define_split
14228   [(set (pc)
14229         (if_then_else (match_operator 0 "comparison_operator"
14230                         [(match_operand 1 "register_operand" "")
14231                          (match_operand 2 "general_operand" "")])
14232           (match_operand 3 "" "")
14233           (match_operand 4 "" "")))
14234    (clobber (reg:CCFP FPSR_REG))
14235    (clobber (reg:CCFP FLAGS_REG))
14236    (clobber (match_scratch:HI 5 "=a"))]
14237   "reload_completed"
14238   [(const_int 0)]
14239 {
14240   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14241                         operands[3], operands[4], operands[5], NULL_RTX);
14242   DONE;
14243 })
14244
14245 (define_split
14246   [(set (pc)
14247         (if_then_else (match_operator 0 "comparison_operator"
14248                         [(match_operator 1 "float_operator"
14249                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14250                            (match_operand 3 "register_operand" "")])
14251           (match_operand 4 "" "")
14252           (match_operand 5 "" "")))
14253    (clobber (reg:CCFP FPSR_REG))
14254    (clobber (reg:CCFP FLAGS_REG))
14255    (clobber (match_scratch:HI 6 "=a"))]
14256   "reload_completed"
14257   [(const_int 0)]
14258 {
14259   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14260   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14261                         operands[3], operands[7],
14262                         operands[4], operands[5], operands[6], NULL_RTX);
14263   DONE;
14264 })
14265
14266 ;; %%% Kill this when reload knows how to do it.
14267 (define_split
14268   [(set (pc)
14269         (if_then_else (match_operator 0 "comparison_operator"
14270                         [(match_operator 1 "float_operator"
14271                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14272                            (match_operand 3 "register_operand" "")])
14273           (match_operand 4 "" "")
14274           (match_operand 5 "" "")))
14275    (clobber (reg:CCFP FPSR_REG))
14276    (clobber (reg:CCFP FLAGS_REG))
14277    (clobber (match_scratch:HI 6 "=a"))]
14278   "reload_completed"
14279   [(const_int 0)]
14280 {
14281   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14282   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14283   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14284                         operands[3], operands[7],
14285                         operands[4], operands[5], operands[6], operands[2]);
14286   DONE;
14287 })
14288 \f
14289 ;; Unconditional and other jump instructions
14290
14291 (define_insn "jump"
14292   [(set (pc)
14293         (label_ref (match_operand 0 "" "")))]
14294   ""
14295   "jmp\t%l0"
14296   [(set_attr "type" "ibr")
14297    (set (attr "length")
14298            (if_then_else (and (ge (minus (match_dup 0) (pc))
14299                                   (const_int -126))
14300                               (lt (minus (match_dup 0) (pc))
14301                                   (const_int 128)))
14302              (const_int 2)
14303              (const_int 5)))
14304    (set_attr "modrm" "0")])
14305
14306 (define_expand "indirect_jump"
14307   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
14308   ""
14309   "")
14310
14311 (define_insn "*indirect_jump"
14312   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14313   "!TARGET_64BIT"
14314   "jmp\t%A0"
14315   [(set_attr "type" "ibr")
14316    (set_attr "length_immediate" "0")])
14317
14318 (define_insn "*indirect_jump_rtx64"
14319   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14320   "TARGET_64BIT"
14321   "jmp\t%A0"
14322   [(set_attr "type" "ibr")
14323    (set_attr "length_immediate" "0")])
14324
14325 (define_expand "tablejump"
14326   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14327               (use (label_ref (match_operand 1 "" "")))])]
14328   ""
14329 {
14330   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14331      relative.  Convert the relative address to an absolute address.  */
14332   if (flag_pic)
14333     {
14334       rtx op0, op1;
14335       enum rtx_code code;
14336
14337       if (TARGET_64BIT)
14338         {
14339           code = PLUS;
14340           op0 = operands[0];
14341           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14342         }
14343       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14344         {
14345           code = PLUS;
14346           op0 = operands[0];
14347           op1 = pic_offset_table_rtx;
14348         }
14349       else
14350         {
14351           code = MINUS;
14352           op0 = pic_offset_table_rtx;
14353           op1 = operands[0];
14354         }
14355
14356       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14357                                          OPTAB_DIRECT);
14358     }
14359 })
14360
14361 (define_insn "*tablejump_1"
14362   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14363    (use (label_ref (match_operand 1 "" "")))]
14364   "!TARGET_64BIT"
14365   "jmp\t%A0"
14366   [(set_attr "type" "ibr")
14367    (set_attr "length_immediate" "0")])
14368
14369 (define_insn "*tablejump_1_rtx64"
14370   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14371    (use (label_ref (match_operand 1 "" "")))]
14372   "TARGET_64BIT"
14373   "jmp\t%A0"
14374   [(set_attr "type" "ibr")
14375    (set_attr "length_immediate" "0")])
14376 \f
14377 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14378
14379 (define_peephole2
14380   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14381    (set (match_operand:QI 1 "register_operand" "")
14382         (match_operator:QI 2 "ix86_comparison_operator"
14383           [(reg FLAGS_REG) (const_int 0)]))
14384    (set (match_operand 3 "q_regs_operand" "")
14385         (zero_extend (match_dup 1)))]
14386   "(peep2_reg_dead_p (3, operands[1])
14387     || operands_match_p (operands[1], operands[3]))
14388    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14389   [(set (match_dup 4) (match_dup 0))
14390    (set (strict_low_part (match_dup 5))
14391         (match_dup 2))]
14392 {
14393   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14394   operands[5] = gen_lowpart (QImode, operands[3]);
14395   ix86_expand_clear (operands[3]);
14396 })
14397
14398 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14399
14400 (define_peephole2
14401   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14402    (set (match_operand:QI 1 "register_operand" "")
14403         (match_operator:QI 2 "ix86_comparison_operator"
14404           [(reg FLAGS_REG) (const_int 0)]))
14405    (parallel [(set (match_operand 3 "q_regs_operand" "")
14406                    (zero_extend (match_dup 1)))
14407               (clobber (reg:CC FLAGS_REG))])]
14408   "(peep2_reg_dead_p (3, operands[1])
14409     || operands_match_p (operands[1], operands[3]))
14410    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14411   [(set (match_dup 4) (match_dup 0))
14412    (set (strict_low_part (match_dup 5))
14413         (match_dup 2))]
14414 {
14415   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14416   operands[5] = gen_lowpart (QImode, operands[3]);
14417   ix86_expand_clear (operands[3]);
14418 })
14419 \f
14420 ;; Call instructions.
14421
14422 ;; The predicates normally associated with named expanders are not properly
14423 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14424 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14425
14426 ;; Call subroutine returning no value.
14427
14428 (define_expand "call_pop"
14429   [(parallel [(call (match_operand:QI 0 "" "")
14430                     (match_operand:SI 1 "" ""))
14431               (set (reg:SI SP_REG)
14432                    (plus:SI (reg:SI SP_REG)
14433                             (match_operand:SI 3 "" "")))])]
14434   "!TARGET_64BIT"
14435 {
14436   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14437   DONE;
14438 })
14439
14440 (define_insn "*call_pop_0"
14441   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14442          (match_operand:SI 1 "" ""))
14443    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14444                             (match_operand:SI 2 "immediate_operand" "")))]
14445   "!TARGET_64BIT"
14446 {
14447   if (SIBLING_CALL_P (insn))
14448     return "jmp\t%P0";
14449   else
14450     return "call\t%P0";
14451 }
14452   [(set_attr "type" "call")])
14453
14454 (define_insn "*call_pop_1"
14455   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14456          (match_operand:SI 1 "" ""))
14457    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14458                             (match_operand:SI 2 "immediate_operand" "i")))]
14459   "!TARGET_64BIT"
14460 {
14461   if (constant_call_address_operand (operands[0], Pmode))
14462     {
14463       if (SIBLING_CALL_P (insn))
14464         return "jmp\t%P0";
14465       else
14466         return "call\t%P0";
14467     }
14468   if (SIBLING_CALL_P (insn))
14469     return "jmp\t%A0";
14470   else
14471     return "call\t%A0";
14472 }
14473   [(set_attr "type" "call")])
14474
14475 (define_expand "call"
14476   [(call (match_operand:QI 0 "" "")
14477          (match_operand 1 "" ""))
14478    (use (match_operand 2 "" ""))]
14479   ""
14480 {
14481   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14482   DONE;
14483 })
14484
14485 (define_expand "sibcall"
14486   [(call (match_operand:QI 0 "" "")
14487          (match_operand 1 "" ""))
14488    (use (match_operand 2 "" ""))]
14489   ""
14490 {
14491   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14492   DONE;
14493 })
14494
14495 (define_insn "*call_0"
14496   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14497          (match_operand 1 "" ""))]
14498   ""
14499 {
14500   if (SIBLING_CALL_P (insn))
14501     return "jmp\t%P0";
14502   else
14503     return "call\t%P0";
14504 }
14505   [(set_attr "type" "call")])
14506
14507 (define_insn "*call_1"
14508   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14509          (match_operand 1 "" ""))]
14510   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14511 {
14512   if (constant_call_address_operand (operands[0], Pmode))
14513     return "call\t%P0";
14514   return "call\t%A0";
14515 }
14516   [(set_attr "type" "call")])
14517
14518 (define_insn "*sibcall_1"
14519   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14520          (match_operand 1 "" ""))]
14521   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14522 {
14523   if (constant_call_address_operand (operands[0], Pmode))
14524     return "jmp\t%P0";
14525   return "jmp\t%A0";
14526 }
14527   [(set_attr "type" "call")])
14528
14529 (define_insn "*call_1_rex64"
14530   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14531          (match_operand 1 "" ""))]
14532   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14533 {
14534   if (constant_call_address_operand (operands[0], Pmode))
14535     return "call\t%P0";
14536   return "call\t%A0";
14537 }
14538   [(set_attr "type" "call")])
14539
14540 (define_insn "*sibcall_1_rex64"
14541   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14542          (match_operand 1 "" ""))]
14543   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14544   "jmp\t%P0"
14545   [(set_attr "type" "call")])
14546
14547 (define_insn "*sibcall_1_rex64_v"
14548   [(call (mem:QI (reg:DI R11_REG))
14549          (match_operand 0 "" ""))]
14550   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14551   "jmp\t*%%r11"
14552   [(set_attr "type" "call")])
14553
14554
14555 ;; Call subroutine, returning value in operand 0
14556
14557 (define_expand "call_value_pop"
14558   [(parallel [(set (match_operand 0 "" "")
14559                    (call (match_operand:QI 1 "" "")
14560                          (match_operand:SI 2 "" "")))
14561               (set (reg:SI SP_REG)
14562                    (plus:SI (reg:SI SP_REG)
14563                             (match_operand:SI 4 "" "")))])]
14564   "!TARGET_64BIT"
14565 {
14566   ix86_expand_call (operands[0], operands[1], operands[2],
14567                     operands[3], operands[4], 0);
14568   DONE;
14569 })
14570
14571 (define_expand "call_value"
14572   [(set (match_operand 0 "" "")
14573         (call (match_operand:QI 1 "" "")
14574               (match_operand:SI 2 "" "")))
14575    (use (match_operand:SI 3 "" ""))]
14576   ;; Operand 2 not used on the i386.
14577   ""
14578 {
14579   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14580   DONE;
14581 })
14582
14583 (define_expand "sibcall_value"
14584   [(set (match_operand 0 "" "")
14585         (call (match_operand:QI 1 "" "")
14586               (match_operand:SI 2 "" "")))
14587    (use (match_operand:SI 3 "" ""))]
14588   ;; Operand 2 not used on the i386.
14589   ""
14590 {
14591   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14592   DONE;
14593 })
14594
14595 ;; Call subroutine returning any type.
14596
14597 (define_expand "untyped_call"
14598   [(parallel [(call (match_operand 0 "" "")
14599                     (const_int 0))
14600               (match_operand 1 "" "")
14601               (match_operand 2 "" "")])]
14602   ""
14603 {
14604   int i;
14605
14606   /* In order to give reg-stack an easier job in validating two
14607      coprocessor registers as containing a possible return value,
14608      simply pretend the untyped call returns a complex long double
14609      value.  */
14610
14611   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14612                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14613                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14614                     NULL, 0);
14615
14616   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14617     {
14618       rtx set = XVECEXP (operands[2], 0, i);
14619       emit_move_insn (SET_DEST (set), SET_SRC (set));
14620     }
14621
14622   /* The optimizer does not know that the call sets the function value
14623      registers we stored in the result block.  We avoid problems by
14624      claiming that all hard registers are used and clobbered at this
14625      point.  */
14626   emit_insn (gen_blockage (const0_rtx));
14627
14628   DONE;
14629 })
14630 \f
14631 ;; Prologue and epilogue instructions
14632
14633 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14634 ;; all of memory.  This blocks insns from being moved across this point.
14635
14636 (define_insn "blockage"
14637   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14638   ""
14639   ""
14640   [(set_attr "length" "0")])
14641
14642 ;; Insn emitted into the body of a function to return from a function.
14643 ;; This is only done if the function's epilogue is known to be simple.
14644 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14645
14646 (define_expand "return"
14647   [(return)]
14648   "ix86_can_use_return_insn_p ()"
14649 {
14650   if (current_function_pops_args)
14651     {
14652       rtx popc = GEN_INT (current_function_pops_args);
14653       emit_jump_insn (gen_return_pop_internal (popc));
14654       DONE;
14655     }
14656 })
14657
14658 (define_insn "return_internal"
14659   [(return)]
14660   "reload_completed"
14661   "ret"
14662   [(set_attr "length" "1")
14663    (set_attr "length_immediate" "0")
14664    (set_attr "modrm" "0")])
14665
14666 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14667 ;; instruction Athlon and K8 have.
14668
14669 (define_insn "return_internal_long"
14670   [(return)
14671    (unspec [(const_int 0)] UNSPEC_REP)]
14672   "reload_completed"
14673   "rep {;} ret"
14674   [(set_attr "length" "1")
14675    (set_attr "length_immediate" "0")
14676    (set_attr "prefix_rep" "1")
14677    (set_attr "modrm" "0")])
14678
14679 (define_insn "return_pop_internal"
14680   [(return)
14681    (use (match_operand:SI 0 "const_int_operand" ""))]
14682   "reload_completed"
14683   "ret\t%0"
14684   [(set_attr "length" "3")
14685    (set_attr "length_immediate" "2")
14686    (set_attr "modrm" "0")])
14687
14688 (define_insn "return_indirect_internal"
14689   [(return)
14690    (use (match_operand:SI 0 "register_operand" "r"))]
14691   "reload_completed"
14692   "jmp\t%A0"
14693   [(set_attr "type" "ibr")
14694    (set_attr "length_immediate" "0")])
14695
14696 (define_insn "nop"
14697   [(const_int 0)]
14698   ""
14699   "nop"
14700   [(set_attr "length" "1")
14701    (set_attr "length_immediate" "0")
14702    (set_attr "modrm" "0")])
14703
14704 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14705 ;; branch prediction penalty for the third jump in a 16-byte
14706 ;; block on K8.
14707
14708 (define_insn "align"
14709   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14710   ""
14711 {
14712 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14713   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14714 #else
14715   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14716      The align insn is used to avoid 3 jump instructions in the row to improve
14717      branch prediction and the benefits hardly outweigh the cost of extra 8
14718      nops on the average inserted by full alignment pseudo operation.  */
14719 #endif
14720   return "";
14721 }
14722   [(set_attr "length" "16")])
14723
14724 (define_expand "prologue"
14725   [(const_int 1)]
14726   ""
14727   "ix86_expand_prologue (); DONE;")
14728
14729 (define_insn "set_got"
14730   [(set (match_operand:SI 0 "register_operand" "=r")
14731         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14732    (clobber (reg:CC FLAGS_REG))]
14733   "!TARGET_64BIT"
14734   { return output_set_got (operands[0], NULL_RTX); }
14735   [(set_attr "type" "multi")
14736    (set_attr "length" "12")])
14737
14738 (define_insn "set_got_labelled"
14739   [(set (match_operand:SI 0 "register_operand" "=r")
14740         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14741          UNSPEC_SET_GOT))
14742    (clobber (reg:CC FLAGS_REG))]
14743   "!TARGET_64BIT"
14744   { return output_set_got (operands[0], operands[1]); }
14745   [(set_attr "type" "multi")
14746    (set_attr "length" "12")])
14747
14748 (define_insn "set_got_rex64"
14749   [(set (match_operand:DI 0 "register_operand" "=r")
14750         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14751   "TARGET_64BIT"
14752   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14753   [(set_attr "type" "lea")
14754    (set_attr "length" "6")])
14755
14756 (define_expand "epilogue"
14757   [(const_int 1)]
14758   ""
14759   "ix86_expand_epilogue (1); DONE;")
14760
14761 (define_expand "sibcall_epilogue"
14762   [(const_int 1)]
14763   ""
14764   "ix86_expand_epilogue (0); DONE;")
14765
14766 (define_expand "eh_return"
14767   [(use (match_operand 0 "register_operand" ""))]
14768   ""
14769 {
14770   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14771
14772   /* Tricky bit: we write the address of the handler to which we will
14773      be returning into someone else's stack frame, one word below the
14774      stack address we wish to restore.  */
14775   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14776   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14777   tmp = gen_rtx_MEM (Pmode, tmp);
14778   emit_move_insn (tmp, ra);
14779
14780   if (Pmode == SImode)
14781     emit_jump_insn (gen_eh_return_si (sa));
14782   else
14783     emit_jump_insn (gen_eh_return_di (sa));
14784   emit_barrier ();
14785   DONE;
14786 })
14787
14788 (define_insn_and_split "eh_return_si"
14789   [(set (pc)
14790         (unspec [(match_operand:SI 0 "register_operand" "c")]
14791                  UNSPEC_EH_RETURN))]
14792   "!TARGET_64BIT"
14793   "#"
14794   "reload_completed"
14795   [(const_int 1)]
14796   "ix86_expand_epilogue (2); DONE;")
14797
14798 (define_insn_and_split "eh_return_di"
14799   [(set (pc)
14800         (unspec [(match_operand:DI 0 "register_operand" "c")]
14801                  UNSPEC_EH_RETURN))]
14802   "TARGET_64BIT"
14803   "#"
14804   "reload_completed"
14805   [(const_int 1)]
14806   "ix86_expand_epilogue (2); DONE;")
14807
14808 (define_insn "leave"
14809   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14810    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14811    (clobber (mem:BLK (scratch)))]
14812   "!TARGET_64BIT"
14813   "leave"
14814   [(set_attr "type" "leave")])
14815
14816 (define_insn "leave_rex64"
14817   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14818    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14819    (clobber (mem:BLK (scratch)))]
14820   "TARGET_64BIT"
14821   "leave"
14822   [(set_attr "type" "leave")])
14823 \f
14824 (define_expand "ffssi2"
14825   [(parallel
14826      [(set (match_operand:SI 0 "register_operand" "")
14827            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14828       (clobber (match_scratch:SI 2 ""))
14829       (clobber (reg:CC FLAGS_REG))])]
14830   ""
14831   "")
14832
14833 (define_insn_and_split "*ffs_cmove"
14834   [(set (match_operand:SI 0 "register_operand" "=r")
14835         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14836    (clobber (match_scratch:SI 2 "=&r"))
14837    (clobber (reg:CC FLAGS_REG))]
14838   "TARGET_CMOVE"
14839   "#"
14840   "&& reload_completed"
14841   [(set (match_dup 2) (const_int -1))
14842    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14843               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14844    (set (match_dup 0) (if_then_else:SI
14845                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14846                         (match_dup 2)
14847                         (match_dup 0)))
14848    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14849               (clobber (reg:CC FLAGS_REG))])]
14850   "")
14851
14852 (define_insn_and_split "*ffs_no_cmove"
14853   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14854         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14855    (clobber (match_scratch:SI 2 "=&q"))
14856    (clobber (reg:CC FLAGS_REG))]
14857   ""
14858   "#"
14859   "reload_completed"
14860   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14861               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14862    (set (strict_low_part (match_dup 3))
14863         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14864    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14865               (clobber (reg:CC FLAGS_REG))])
14866    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14867               (clobber (reg:CC FLAGS_REG))])
14868    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14869               (clobber (reg:CC FLAGS_REG))])]
14870 {
14871   operands[3] = gen_lowpart (QImode, operands[2]);
14872   ix86_expand_clear (operands[2]);
14873 })
14874
14875 (define_insn "*ffssi_1"
14876   [(set (reg:CCZ FLAGS_REG)
14877         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14878                      (const_int 0)))
14879    (set (match_operand:SI 0 "register_operand" "=r")
14880         (ctz:SI (match_dup 1)))]
14881   ""
14882   "bsf{l}\t{%1, %0|%0, %1}"
14883   [(set_attr "prefix_0f" "1")])
14884
14885 (define_expand "ffsdi2"
14886   [(parallel
14887      [(set (match_operand:DI 0 "register_operand" "")
14888            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14889       (clobber (match_scratch:DI 2 ""))
14890       (clobber (reg:CC FLAGS_REG))])]
14891   "TARGET_64BIT && TARGET_CMOVE"
14892   "")
14893
14894 (define_insn_and_split "*ffs_rex64"
14895   [(set (match_operand:DI 0 "register_operand" "=r")
14896         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14897    (clobber (match_scratch:DI 2 "=&r"))
14898    (clobber (reg:CC FLAGS_REG))]
14899   "TARGET_64BIT && TARGET_CMOVE"
14900   "#"
14901   "&& reload_completed"
14902   [(set (match_dup 2) (const_int -1))
14903    (parallel [(set (reg:CCZ FLAGS_REG)
14904                    (compare:CCZ (match_dup 1) (const_int 0)))
14905               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14906    (set (match_dup 0) (if_then_else:DI
14907                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14908                         (match_dup 2)
14909                         (match_dup 0)))
14910    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14911               (clobber (reg:CC FLAGS_REG))])]
14912   "")
14913
14914 (define_insn "*ffsdi_1"
14915   [(set (reg:CCZ FLAGS_REG)
14916         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14917                      (const_int 0)))
14918    (set (match_operand:DI 0 "register_operand" "=r")
14919         (ctz:DI (match_dup 1)))]
14920   "TARGET_64BIT"
14921   "bsf{q}\t{%1, %0|%0, %1}"
14922   [(set_attr "prefix_0f" "1")])
14923
14924 (define_insn "ctzsi2"
14925   [(set (match_operand:SI 0 "register_operand" "=r")
14926         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14927    (clobber (reg:CC FLAGS_REG))]
14928   ""
14929   "bsf{l}\t{%1, %0|%0, %1}"
14930   [(set_attr "prefix_0f" "1")])
14931
14932 (define_insn "ctzdi2"
14933   [(set (match_operand:DI 0 "register_operand" "=r")
14934         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14935    (clobber (reg:CC FLAGS_REG))]
14936   "TARGET_64BIT"
14937   "bsf{q}\t{%1, %0|%0, %1}"
14938   [(set_attr "prefix_0f" "1")])
14939
14940 (define_expand "clzsi2"
14941   [(parallel
14942      [(set (match_operand:SI 0 "register_operand" "")
14943            (minus:SI (const_int 31)
14944                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14945       (clobber (reg:CC FLAGS_REG))])
14946    (parallel
14947      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14948       (clobber (reg:CC FLAGS_REG))])]
14949   ""
14950 {
14951   if (TARGET_ABM)
14952     {
14953       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14954       DONE;
14955     }
14956 })
14957
14958 (define_insn "clzsi2_abm"
14959   [(set (match_operand:SI 0 "register_operand" "=r")
14960         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14961    (clobber (reg:CC FLAGS_REG))]
14962   "TARGET_ABM"
14963   "lzcnt{l}\t{%1, %0|%0, %1}"
14964   [(set_attr "prefix_rep" "1")
14965    (set_attr "type" "bitmanip")
14966    (set_attr "mode" "SI")])
14967
14968 (define_insn "*bsr"
14969   [(set (match_operand:SI 0 "register_operand" "=r")
14970         (minus:SI (const_int 31)
14971                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14972    (clobber (reg:CC FLAGS_REG))]
14973   ""
14974   "bsr{l}\t{%1, %0|%0, %1}"
14975   [(set_attr "prefix_0f" "1")
14976    (set_attr "mode" "SI")])
14977
14978 (define_insn "popcountsi2"
14979   [(set (match_operand:SI 0 "register_operand" "=r")
14980         (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14981    (clobber (reg:CC FLAGS_REG))]
14982   "TARGET_POPCNT"
14983   "popcnt{l}\t{%1, %0|%0, %1}"
14984   [(set_attr "prefix_rep" "1")
14985    (set_attr "type" "bitmanip")
14986    (set_attr "mode" "SI")])
14987
14988 (define_insn "*popcountsi2_cmp"
14989   [(set (reg FLAGS_REG)
14990         (compare
14991           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14992           (const_int 0)))
14993    (set (match_operand:SI 0 "register_operand" "=r")
14994         (popcount:SI (match_dup 1)))]
14995   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14996   "popcnt{l}\t{%1, %0|%0, %1}"
14997   [(set_attr "prefix_rep" "1")
14998    (set_attr "type" "bitmanip")
14999    (set_attr "mode" "SI")])
15000
15001 (define_insn "*popcountsi2_cmp_zext"
15002   [(set (reg FLAGS_REG)
15003         (compare
15004           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15005           (const_int 0)))
15006    (set (match_operand:DI 0 "register_operand" "=r")
15007         (zero_extend:DI(popcount:SI (match_dup 1))))]
15008   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15009   "popcnt{l}\t{%1, %0|%0, %1}"
15010   [(set_attr "prefix_rep" "1")
15011    (set_attr "type" "bitmanip")
15012    (set_attr "mode" "SI")])
15013
15014 (define_expand "bswapsi2"
15015   [(set (match_operand:SI 0 "register_operand" "")
15016         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15017   ""
15018 {
15019   if (!TARGET_BSWAP)
15020     {
15021       rtx x = operands[0];
15022
15023       emit_move_insn (x, operands[1]);
15024       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15025       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15026       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15027       DONE;
15028     }
15029 })
15030
15031 (define_insn "*bswapsi_1"
15032   [(set (match_operand:SI 0 "register_operand" "=r")
15033         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15034   "TARGET_BSWAP"
15035   "bswap\t%0"
15036   [(set_attr "prefix_0f" "1")
15037    (set_attr "length" "2")])
15038
15039 (define_insn "*bswaphi_lowpart_1"
15040   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15041         (bswap:HI (match_dup 0)))
15042    (clobber (reg:CC FLAGS_REG))]
15043   "TARGET_USE_XCHGB || optimize_size"
15044   "@
15045     xchg{b}\t{%h0, %b0|%b0, %h0}
15046     rol{w}\t{$8, %0|%0, 8}"
15047   [(set_attr "length" "2,4")
15048    (set_attr "mode" "QI,HI")])
15049
15050 (define_insn "bswaphi_lowpart"
15051   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15052         (bswap:HI (match_dup 0)))
15053    (clobber (reg:CC FLAGS_REG))]
15054   ""
15055   "rol{w}\t{$8, %0|%0, 8}"
15056   [(set_attr "length" "4")
15057    (set_attr "mode" "HI")])
15058
15059 (define_insn "bswapdi2"
15060   [(set (match_operand:DI 0 "register_operand" "=r")
15061         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15062   "TARGET_64BIT"
15063   "bswap\t%0"
15064   [(set_attr "prefix_0f" "1")
15065    (set_attr "length" "3")])
15066
15067 (define_expand "clzdi2"
15068   [(parallel
15069      [(set (match_operand:DI 0 "register_operand" "")
15070            (minus:DI (const_int 63)
15071                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15072       (clobber (reg:CC FLAGS_REG))])
15073    (parallel
15074      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15075       (clobber (reg:CC FLAGS_REG))])]
15076   "TARGET_64BIT"
15077 {
15078   if (TARGET_ABM)
15079     {
15080       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15081       DONE;
15082     }
15083 })
15084
15085 (define_insn "clzdi2_abm"
15086   [(set (match_operand:DI 0 "register_operand" "=r")
15087         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15088    (clobber (reg:CC FLAGS_REG))]
15089   "TARGET_64BIT && TARGET_ABM"
15090   "lzcnt{q}\t{%1, %0|%0, %1}"
15091   [(set_attr "prefix_rep" "1")
15092    (set_attr "type" "bitmanip")
15093    (set_attr "mode" "DI")])
15094
15095 (define_insn "*bsr_rex64"
15096   [(set (match_operand:DI 0 "register_operand" "=r")
15097         (minus:DI (const_int 63)
15098                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15099    (clobber (reg:CC FLAGS_REG))]
15100   "TARGET_64BIT"
15101   "bsr{q}\t{%1, %0|%0, %1}"
15102   [(set_attr "prefix_0f" "1")
15103    (set_attr "mode" "DI")])
15104
15105 (define_insn "popcountdi2"
15106   [(set (match_operand:DI 0 "register_operand" "=r")
15107         (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15108    (clobber (reg:CC FLAGS_REG))]
15109   "TARGET_64BIT && TARGET_POPCNT"
15110   "popcnt{q}\t{%1, %0|%0, %1}"
15111   [(set_attr "prefix_rep" "1")
15112    (set_attr "type" "bitmanip")
15113    (set_attr "mode" "DI")])
15114
15115 (define_insn "*popcountdi2_cmp"
15116   [(set (reg FLAGS_REG)
15117         (compare
15118           (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15119           (const_int 0)))
15120    (set (match_operand:DI 0 "register_operand" "=r")
15121         (popcount:DI (match_dup 1)))]
15122   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15123   "popcnt{q}\t{%1, %0|%0, %1}"
15124   [(set_attr "prefix_rep" "1")
15125    (set_attr "type" "bitmanip")
15126    (set_attr "mode" "DI")])
15127
15128 (define_expand "clzhi2"
15129   [(parallel
15130      [(set (match_operand:HI 0 "register_operand" "")
15131            (minus:HI (const_int 15)
15132                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15133       (clobber (reg:CC FLAGS_REG))])
15134    (parallel
15135      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15136       (clobber (reg:CC FLAGS_REG))])]
15137   ""
15138 {
15139   if (TARGET_ABM)
15140     {
15141       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15142       DONE;
15143     }
15144 })
15145
15146 (define_insn "clzhi2_abm"
15147   [(set (match_operand:HI 0 "register_operand" "=r")
15148         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15149    (clobber (reg:CC FLAGS_REG))]
15150   "TARGET_ABM"
15151   "lzcnt{w}\t{%1, %0|%0, %1}"
15152   [(set_attr "prefix_rep" "1")
15153    (set_attr "type" "bitmanip")
15154    (set_attr "mode" "HI")])
15155
15156 (define_insn "*bsrhi"
15157   [(set (match_operand:HI 0 "register_operand" "=r")
15158         (minus:HI (const_int 15)
15159                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15160    (clobber (reg:CC FLAGS_REG))]
15161   ""
15162   "bsr{w}\t{%1, %0|%0, %1}"
15163   [(set_attr "prefix_0f" "1")
15164    (set_attr "mode" "HI")])
15165
15166 (define_insn "popcounthi2"
15167   [(set (match_operand:HI 0 "register_operand" "=r")
15168         (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15169    (clobber (reg:CC FLAGS_REG))]
15170   "TARGET_POPCNT"
15171   "popcnt{w}\t{%1, %0|%0, %1}"
15172   [(set_attr "prefix_rep" "1")
15173    (set_attr "type" "bitmanip")
15174    (set_attr "mode" "HI")])
15175
15176 (define_insn "*popcounthi2_cmp"
15177   [(set (reg FLAGS_REG)
15178         (compare
15179           (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15180           (const_int 0)))
15181    (set (match_operand:HI 0 "register_operand" "=r")
15182         (popcount:HI (match_dup 1)))]
15183   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15184   "popcnt{w}\t{%1, %0|%0, %1}"
15185   [(set_attr "prefix_rep" "1")
15186    (set_attr "type" "bitmanip")
15187    (set_attr "mode" "HI")])
15188
15189 (define_expand "paritydi2"
15190   [(set (match_operand:DI 0 "register_operand" "")
15191         (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
15192   "! TARGET_POPCNT"
15193 {
15194   rtx scratch = gen_reg_rtx (QImode);
15195   rtx cond;
15196
15197   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15198                                 NULL_RTX, operands[1]));
15199
15200   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15201                          gen_rtx_REG (CCmode, FLAGS_REG),
15202                          const0_rtx);
15203   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15204
15205   if (TARGET_64BIT)
15206     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15207   else
15208     {
15209       rtx tmp = gen_reg_rtx (SImode);
15210
15211       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15212       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15213     }
15214   DONE;
15215 })
15216
15217 (define_insn_and_split "paritydi2_cmp"
15218   [(set (reg:CC FLAGS_REG)
15219         (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m")))
15220    (clobber (match_scratch:DI 0 "=r,X"))
15221    (clobber (match_scratch:SI 1 "=r,r"))
15222    (clobber (match_scratch:HI 2 "=Q,Q"))]
15223   "! TARGET_POPCNT"
15224   "#"
15225   "&& reload_completed"
15226   [(parallel
15227      [(set (match_dup 1)
15228            (xor:SI (match_dup 1) (match_dup 4)))
15229       (clobber (reg:CC FLAGS_REG))])
15230    (parallel
15231      [(set (reg:CC FLAGS_REG)
15232            (parity:CC (match_dup 1)))
15233       (clobber (match_dup 1))
15234       (clobber (match_dup 2))])]
15235 {
15236   operands[4] = gen_lowpart (SImode, operands[3]);
15237
15238   if (MEM_P (operands[3]))
15239     emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
15240   else if (! TARGET_64BIT)
15241     operands[1] = gen_highpart (SImode, operands[3]);
15242   else
15243     {
15244       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15245       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15246     }
15247 })
15248
15249 (define_expand "paritysi2"
15250   [(set (match_operand:SI 0 "register_operand" "")
15251         (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
15252   "! TARGET_POPCNT"
15253 {
15254   rtx scratch = gen_reg_rtx (QImode);
15255   rtx cond;
15256
15257   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15258
15259   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15260                          gen_rtx_REG (CCmode, FLAGS_REG),
15261                          const0_rtx);
15262   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15263
15264   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15265   DONE;
15266 })
15267
15268 (define_insn_and_split "paritysi2_cmp"
15269   [(set (reg:CC FLAGS_REG)
15270         (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
15271    (clobber (match_scratch:SI 0 "=r,X"))
15272    (clobber (match_scratch:HI 1 "=Q,Q"))]
15273   "! TARGET_POPCNT"
15274   "#"
15275   "&& reload_completed"
15276   [(parallel
15277      [(set (match_dup 1)
15278            (xor:HI (match_dup 1) (match_dup 3)))
15279       (clobber (reg:CC FLAGS_REG))])
15280    (parallel
15281      [(set (reg:CC FLAGS_REG)
15282            (parity:CC (match_dup 1)))
15283       (clobber (match_dup 1))])]
15284 {
15285   operands[3] = gen_lowpart (HImode, operands[2]);
15286
15287   if (MEM_P (operands[2]))
15288     emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
15289   else
15290     {
15291       emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15292       emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15293     }
15294 })
15295
15296 (define_insn "*parityhi2_cmp"
15297   [(set (reg:CC FLAGS_REG)
15298         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15299    (clobber (match_scratch:HI 0 "=Q"))]
15300   "! TARGET_POPCNT"
15301   "xor{b}\t{%h0, %b0|%b0, %h0}"
15302   [(set_attr "length" "2")
15303    (set_attr "mode" "HI")])
15304
15305 (define_insn "*parityqi2_cmp"
15306   [(set (reg:CC FLAGS_REG)
15307         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15308   "! TARGET_POPCNT"
15309   "test{b}\t%0, %0"
15310   [(set_attr "length" "2")
15311    (set_attr "mode" "QI")])
15312 \f
15313 ;; Thread-local storage patterns for ELF.
15314 ;;
15315 ;; Note that these code sequences must appear exactly as shown
15316 ;; in order to allow linker relaxation.
15317
15318 (define_insn "*tls_global_dynamic_32_gnu"
15319   [(set (match_operand:SI 0 "register_operand" "=a")
15320         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15321                     (match_operand:SI 2 "tls_symbolic_operand" "")
15322                     (match_operand:SI 3 "call_insn_operand" "")]
15323                     UNSPEC_TLS_GD))
15324    (clobber (match_scratch:SI 4 "=d"))
15325    (clobber (match_scratch:SI 5 "=c"))
15326    (clobber (reg:CC FLAGS_REG))]
15327   "!TARGET_64BIT && TARGET_GNU_TLS"
15328   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15329   [(set_attr "type" "multi")
15330    (set_attr "length" "12")])
15331
15332 (define_insn "*tls_global_dynamic_32_sun"
15333   [(set (match_operand:SI 0 "register_operand" "=a")
15334         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15335                     (match_operand:SI 2 "tls_symbolic_operand" "")
15336                     (match_operand:SI 3 "call_insn_operand" "")]
15337                     UNSPEC_TLS_GD))
15338    (clobber (match_scratch:SI 4 "=d"))
15339    (clobber (match_scratch:SI 5 "=c"))
15340    (clobber (reg:CC FLAGS_REG))]
15341   "!TARGET_64BIT && TARGET_SUN_TLS"
15342   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15343         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15344   [(set_attr "type" "multi")
15345    (set_attr "length" "14")])
15346
15347 (define_expand "tls_global_dynamic_32"
15348   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15349                    (unspec:SI
15350                     [(match_dup 2)
15351                      (match_operand:SI 1 "tls_symbolic_operand" "")
15352                      (match_dup 3)]
15353                     UNSPEC_TLS_GD))
15354               (clobber (match_scratch:SI 4 ""))
15355               (clobber (match_scratch:SI 5 ""))
15356               (clobber (reg:CC FLAGS_REG))])]
15357   ""
15358 {
15359   if (flag_pic)
15360     operands[2] = pic_offset_table_rtx;
15361   else
15362     {
15363       operands[2] = gen_reg_rtx (Pmode);
15364       emit_insn (gen_set_got (operands[2]));
15365     }
15366   if (TARGET_GNU2_TLS)
15367     {
15368        emit_insn (gen_tls_dynamic_gnu2_32
15369                   (operands[0], operands[1], operands[2]));
15370        DONE;
15371     }
15372   operands[3] = ix86_tls_get_addr ();
15373 })
15374
15375 (define_insn "*tls_global_dynamic_64"
15376   [(set (match_operand:DI 0 "register_operand" "=a")
15377         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15378                  (match_operand:DI 3 "" "")))
15379    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15380               UNSPEC_TLS_GD)]
15381   "TARGET_64BIT"
15382   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15383   [(set_attr "type" "multi")
15384    (set_attr "length" "16")])
15385
15386 (define_expand "tls_global_dynamic_64"
15387   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15388                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15389               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15390                          UNSPEC_TLS_GD)])]
15391   ""
15392 {
15393   if (TARGET_GNU2_TLS)
15394     {
15395        emit_insn (gen_tls_dynamic_gnu2_64
15396                   (operands[0], operands[1]));
15397        DONE;
15398     }
15399   operands[2] = ix86_tls_get_addr ();
15400 })
15401
15402 (define_insn "*tls_local_dynamic_base_32_gnu"
15403   [(set (match_operand:SI 0 "register_operand" "=a")
15404         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15405                     (match_operand:SI 2 "call_insn_operand" "")]
15406                    UNSPEC_TLS_LD_BASE))
15407    (clobber (match_scratch:SI 3 "=d"))
15408    (clobber (match_scratch:SI 4 "=c"))
15409    (clobber (reg:CC FLAGS_REG))]
15410   "!TARGET_64BIT && TARGET_GNU_TLS"
15411   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15412   [(set_attr "type" "multi")
15413    (set_attr "length" "11")])
15414
15415 (define_insn "*tls_local_dynamic_base_32_sun"
15416   [(set (match_operand:SI 0 "register_operand" "=a")
15417         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15418                     (match_operand:SI 2 "call_insn_operand" "")]
15419                    UNSPEC_TLS_LD_BASE))
15420    (clobber (match_scratch:SI 3 "=d"))
15421    (clobber (match_scratch:SI 4 "=c"))
15422    (clobber (reg:CC FLAGS_REG))]
15423   "!TARGET_64BIT && TARGET_SUN_TLS"
15424   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15425         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15426   [(set_attr "type" "multi")
15427    (set_attr "length" "13")])
15428
15429 (define_expand "tls_local_dynamic_base_32"
15430   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15431                    (unspec:SI [(match_dup 1) (match_dup 2)]
15432                               UNSPEC_TLS_LD_BASE))
15433               (clobber (match_scratch:SI 3 ""))
15434               (clobber (match_scratch:SI 4 ""))
15435               (clobber (reg:CC FLAGS_REG))])]
15436   ""
15437 {
15438   if (flag_pic)
15439     operands[1] = pic_offset_table_rtx;
15440   else
15441     {
15442       operands[1] = gen_reg_rtx (Pmode);
15443       emit_insn (gen_set_got (operands[1]));
15444     }
15445   if (TARGET_GNU2_TLS)
15446     {
15447        emit_insn (gen_tls_dynamic_gnu2_32
15448                   (operands[0], ix86_tls_module_base (), operands[1]));
15449        DONE;
15450     }
15451   operands[2] = ix86_tls_get_addr ();
15452 })
15453
15454 (define_insn "*tls_local_dynamic_base_64"
15455   [(set (match_operand:DI 0 "register_operand" "=a")
15456         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15457                  (match_operand:DI 2 "" "")))
15458    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15459   "TARGET_64BIT"
15460   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15461   [(set_attr "type" "multi")
15462    (set_attr "length" "12")])
15463
15464 (define_expand "tls_local_dynamic_base_64"
15465   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15466                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15467               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15468   ""
15469 {
15470   if (TARGET_GNU2_TLS)
15471     {
15472        emit_insn (gen_tls_dynamic_gnu2_64
15473                   (operands[0], ix86_tls_module_base ()));
15474        DONE;
15475     }
15476   operands[1] = ix86_tls_get_addr ();
15477 })
15478
15479 ;; Local dynamic of a single variable is a lose.  Show combine how
15480 ;; to convert that back to global dynamic.
15481
15482 (define_insn_and_split "*tls_local_dynamic_32_once"
15483   [(set (match_operand:SI 0 "register_operand" "=a")
15484         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15485                              (match_operand:SI 2 "call_insn_operand" "")]
15486                             UNSPEC_TLS_LD_BASE)
15487                  (const:SI (unspec:SI
15488                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15489                             UNSPEC_DTPOFF))))
15490    (clobber (match_scratch:SI 4 "=d"))
15491    (clobber (match_scratch:SI 5 "=c"))
15492    (clobber (reg:CC FLAGS_REG))]
15493   ""
15494   "#"
15495   ""
15496   [(parallel [(set (match_dup 0)
15497                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15498                               UNSPEC_TLS_GD))
15499               (clobber (match_dup 4))
15500               (clobber (match_dup 5))
15501               (clobber (reg:CC FLAGS_REG))])]
15502   "")
15503
15504 ;; Load and add the thread base pointer from %gs:0.
15505
15506 (define_insn "*load_tp_si"
15507   [(set (match_operand:SI 0 "register_operand" "=r")
15508         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15509   "!TARGET_64BIT"
15510   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15511   [(set_attr "type" "imov")
15512    (set_attr "modrm" "0")
15513    (set_attr "length" "7")
15514    (set_attr "memory" "load")
15515    (set_attr "imm_disp" "false")])
15516
15517 (define_insn "*add_tp_si"
15518   [(set (match_operand:SI 0 "register_operand" "=r")
15519         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15520                  (match_operand:SI 1 "register_operand" "0")))
15521    (clobber (reg:CC FLAGS_REG))]
15522   "!TARGET_64BIT"
15523   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15524   [(set_attr "type" "alu")
15525    (set_attr "modrm" "0")
15526    (set_attr "length" "7")
15527    (set_attr "memory" "load")
15528    (set_attr "imm_disp" "false")])
15529
15530 (define_insn "*load_tp_di"
15531   [(set (match_operand:DI 0 "register_operand" "=r")
15532         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15533   "TARGET_64BIT"
15534   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15535   [(set_attr "type" "imov")
15536    (set_attr "modrm" "0")
15537    (set_attr "length" "7")
15538    (set_attr "memory" "load")
15539    (set_attr "imm_disp" "false")])
15540
15541 (define_insn "*add_tp_di"
15542   [(set (match_operand:DI 0 "register_operand" "=r")
15543         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15544                  (match_operand:DI 1 "register_operand" "0")))
15545    (clobber (reg:CC FLAGS_REG))]
15546   "TARGET_64BIT"
15547   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15548   [(set_attr "type" "alu")
15549    (set_attr "modrm" "0")
15550    (set_attr "length" "7")
15551    (set_attr "memory" "load")
15552    (set_attr "imm_disp" "false")])
15553
15554 ;; GNU2 TLS patterns can be split.
15555
15556 (define_expand "tls_dynamic_gnu2_32"
15557   [(set (match_dup 3)
15558         (plus:SI (match_operand:SI 2 "register_operand" "")
15559                  (const:SI
15560                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15561                              UNSPEC_TLSDESC))))
15562    (parallel
15563     [(set (match_operand:SI 0 "register_operand" "")
15564           (unspec:SI [(match_dup 1) (match_dup 3)
15565                       (match_dup 2) (reg:SI SP_REG)]
15566                       UNSPEC_TLSDESC))
15567      (clobber (reg:CC FLAGS_REG))])]
15568   "!TARGET_64BIT && TARGET_GNU2_TLS"
15569 {
15570   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15571   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15572 })
15573
15574 (define_insn "*tls_dynamic_lea_32"
15575   [(set (match_operand:SI 0 "register_operand" "=r")
15576         (plus:SI (match_operand:SI 1 "register_operand" "b")
15577                  (const:SI
15578                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15579                               UNSPEC_TLSDESC))))]
15580   "!TARGET_64BIT && TARGET_GNU2_TLS"
15581   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15582   [(set_attr "type" "lea")
15583    (set_attr "mode" "SI")
15584    (set_attr "length" "6")
15585    (set_attr "length_address" "4")])
15586
15587 (define_insn "*tls_dynamic_call_32"
15588   [(set (match_operand:SI 0 "register_operand" "=a")
15589         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15590                     (match_operand:SI 2 "register_operand" "0")
15591                     ;; we have to make sure %ebx still points to the GOT
15592                     (match_operand:SI 3 "register_operand" "b")
15593                     (reg:SI SP_REG)]
15594                    UNSPEC_TLSDESC))
15595    (clobber (reg:CC FLAGS_REG))]
15596   "!TARGET_64BIT && TARGET_GNU2_TLS"
15597   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15598   [(set_attr "type" "call")
15599    (set_attr "length" "2")
15600    (set_attr "length_address" "0")])
15601
15602 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15603   [(set (match_operand:SI 0 "register_operand" "=&a")
15604         (plus:SI
15605          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15606                      (match_operand:SI 4 "" "")
15607                      (match_operand:SI 2 "register_operand" "b")
15608                      (reg:SI SP_REG)]
15609                     UNSPEC_TLSDESC)
15610          (const:SI (unspec:SI
15611                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15612                     UNSPEC_DTPOFF))))
15613    (clobber (reg:CC FLAGS_REG))]
15614   "!TARGET_64BIT && TARGET_GNU2_TLS"
15615   "#"
15616   ""
15617   [(set (match_dup 0) (match_dup 5))]
15618 {
15619   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15620   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15621 })
15622
15623 (define_expand "tls_dynamic_gnu2_64"
15624   [(set (match_dup 2)
15625         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15626                    UNSPEC_TLSDESC))
15627    (parallel
15628     [(set (match_operand:DI 0 "register_operand" "")
15629           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15630                      UNSPEC_TLSDESC))
15631      (clobber (reg:CC FLAGS_REG))])]
15632   "TARGET_64BIT && TARGET_GNU2_TLS"
15633 {
15634   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15635   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15636 })
15637
15638 (define_insn "*tls_dynamic_lea_64"
15639   [(set (match_operand:DI 0 "register_operand" "=r")
15640         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15641                    UNSPEC_TLSDESC))]
15642   "TARGET_64BIT && TARGET_GNU2_TLS"
15643   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15644   [(set_attr "type" "lea")
15645    (set_attr "mode" "DI")
15646    (set_attr "length" "7")
15647    (set_attr "length_address" "4")])
15648
15649 (define_insn "*tls_dynamic_call_64"
15650   [(set (match_operand:DI 0 "register_operand" "=a")
15651         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15652                     (match_operand:DI 2 "register_operand" "0")
15653                     (reg:DI SP_REG)]
15654                    UNSPEC_TLSDESC))
15655    (clobber (reg:CC FLAGS_REG))]
15656   "TARGET_64BIT && TARGET_GNU2_TLS"
15657   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15658   [(set_attr "type" "call")
15659    (set_attr "length" "2")
15660    (set_attr "length_address" "0")])
15661
15662 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15663   [(set (match_operand:DI 0 "register_operand" "=&a")
15664         (plus:DI
15665          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15666                      (match_operand:DI 3 "" "")
15667                      (reg:DI SP_REG)]
15668                     UNSPEC_TLSDESC)
15669          (const:DI (unspec:DI
15670                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15671                     UNSPEC_DTPOFF))))
15672    (clobber (reg:CC FLAGS_REG))]
15673   "TARGET_64BIT && TARGET_GNU2_TLS"
15674   "#"
15675   ""
15676   [(set (match_dup 0) (match_dup 4))]
15677 {
15678   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15679   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15680 })
15681
15682 ;;
15683 \f
15684 ;; These patterns match the binary 387 instructions for addM3, subM3,
15685 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15686 ;; SFmode.  The first is the normal insn, the second the same insn but
15687 ;; with one operand a conversion, and the third the same insn but with
15688 ;; the other operand a conversion.  The conversion may be SFmode or
15689 ;; SImode if the target mode DFmode, but only SImode if the target mode
15690 ;; is SFmode.
15691
15692 ;; Gcc is slightly more smart about handling normal two address instructions
15693 ;; so use special patterns for add and mull.
15694
15695 (define_insn "*fop_sf_comm_mixed"
15696   [(set (match_operand:SF 0 "register_operand" "=f,x")
15697         (match_operator:SF 3 "binary_fp_operator"
15698                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15699                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15700   "TARGET_MIX_SSE_I387
15701    && COMMUTATIVE_ARITH_P (operands[3])
15702    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15703   "* return output_387_binary_op (insn, operands);"
15704   [(set (attr "type")
15705         (if_then_else (eq_attr "alternative" "1")
15706            (if_then_else (match_operand:SF 3 "mult_operator" "")
15707               (const_string "ssemul")
15708               (const_string "sseadd"))
15709            (if_then_else (match_operand:SF 3 "mult_operator" "")
15710               (const_string "fmul")
15711               (const_string "fop"))))
15712    (set_attr "mode" "SF")])
15713
15714 (define_insn "*fop_sf_comm_sse"
15715   [(set (match_operand:SF 0 "register_operand" "=x")
15716         (match_operator:SF 3 "binary_fp_operator"
15717                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15718                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15719   "TARGET_SSE_MATH
15720    && COMMUTATIVE_ARITH_P (operands[3])
15721    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15722   "* return output_387_binary_op (insn, operands);"
15723   [(set (attr "type")
15724         (if_then_else (match_operand:SF 3 "mult_operator" "")
15725            (const_string "ssemul")
15726            (const_string "sseadd")))
15727    (set_attr "mode" "SF")])
15728
15729 (define_insn "*fop_sf_comm_i387"
15730   [(set (match_operand:SF 0 "register_operand" "=f")
15731         (match_operator:SF 3 "binary_fp_operator"
15732                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15733                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15734   "TARGET_80387
15735    && COMMUTATIVE_ARITH_P (operands[3])
15736    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15737   "* return output_387_binary_op (insn, operands);"
15738   [(set (attr "type")
15739         (if_then_else (match_operand:SF 3 "mult_operator" "")
15740            (const_string "fmul")
15741            (const_string "fop")))
15742    (set_attr "mode" "SF")])
15743
15744 (define_insn "*fop_sf_1_mixed"
15745   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15746         (match_operator:SF 3 "binary_fp_operator"
15747                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15748                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15749   "TARGET_MIX_SSE_I387
15750    && !COMMUTATIVE_ARITH_P (operands[3])
15751    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15752   "* return output_387_binary_op (insn, operands);"
15753   [(set (attr "type")
15754         (cond [(and (eq_attr "alternative" "2")
15755                     (match_operand:SF 3 "mult_operator" ""))
15756                  (const_string "ssemul")
15757                (and (eq_attr "alternative" "2")
15758                     (match_operand:SF 3 "div_operator" ""))
15759                  (const_string "ssediv")
15760                (eq_attr "alternative" "2")
15761                  (const_string "sseadd")
15762                (match_operand:SF 3 "mult_operator" "")
15763                  (const_string "fmul")
15764                (match_operand:SF 3 "div_operator" "")
15765                  (const_string "fdiv")
15766               ]
15767               (const_string "fop")))
15768    (set_attr "mode" "SF")])
15769
15770 (define_insn "*fop_sf_1_sse"
15771   [(set (match_operand:SF 0 "register_operand" "=x")
15772         (match_operator:SF 3 "binary_fp_operator"
15773                         [(match_operand:SF 1 "register_operand" "0")
15774                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15775   "TARGET_SSE_MATH
15776    && !COMMUTATIVE_ARITH_P (operands[3])"
15777   "* return output_387_binary_op (insn, operands);"
15778   [(set (attr "type")
15779         (cond [(match_operand:SF 3 "mult_operator" "")
15780                  (const_string "ssemul")
15781                (match_operand:SF 3 "div_operator" "")
15782                  (const_string "ssediv")
15783               ]
15784               (const_string "sseadd")))
15785    (set_attr "mode" "SF")])
15786
15787 ;; This pattern is not fully shadowed by the pattern above.
15788 (define_insn "*fop_sf_1_i387"
15789   [(set (match_operand:SF 0 "register_operand" "=f,f")
15790         (match_operator:SF 3 "binary_fp_operator"
15791                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15792                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15793   "TARGET_80387 && !TARGET_SSE_MATH
15794    && !COMMUTATIVE_ARITH_P (operands[3])
15795    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15796   "* return output_387_binary_op (insn, operands);"
15797   [(set (attr "type")
15798         (cond [(match_operand:SF 3 "mult_operator" "")
15799                  (const_string "fmul")
15800                (match_operand:SF 3 "div_operator" "")
15801                  (const_string "fdiv")
15802               ]
15803               (const_string "fop")))
15804    (set_attr "mode" "SF")])
15805
15806 ;; ??? Add SSE splitters for these!
15807 (define_insn "*fop_sf_2<mode>_i387"
15808   [(set (match_operand:SF 0 "register_operand" "=f,f")
15809         (match_operator:SF 3 "binary_fp_operator"
15810           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15811            (match_operand:SF 2 "register_operand" "0,0")]))]
15812   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15813   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15814   [(set (attr "type")
15815         (cond [(match_operand:SF 3 "mult_operator" "")
15816                  (const_string "fmul")
15817                (match_operand:SF 3 "div_operator" "")
15818                  (const_string "fdiv")
15819               ]
15820               (const_string "fop")))
15821    (set_attr "fp_int_src" "true")
15822    (set_attr "mode" "<MODE>")])
15823
15824 (define_insn "*fop_sf_3<mode>_i387"
15825   [(set (match_operand:SF 0 "register_operand" "=f,f")
15826         (match_operator:SF 3 "binary_fp_operator"
15827           [(match_operand:SF 1 "register_operand" "0,0")
15828            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15829   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15830   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15831   [(set (attr "type")
15832         (cond [(match_operand:SF 3 "mult_operator" "")
15833                  (const_string "fmul")
15834                (match_operand:SF 3 "div_operator" "")
15835                  (const_string "fdiv")
15836               ]
15837               (const_string "fop")))
15838    (set_attr "fp_int_src" "true")
15839    (set_attr "mode" "<MODE>")])
15840
15841 (define_insn "*fop_df_comm_mixed"
15842   [(set (match_operand:DF 0 "register_operand" "=f,x")
15843         (match_operator:DF 3 "binary_fp_operator"
15844           [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15845            (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15846   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15847    && COMMUTATIVE_ARITH_P (operands[3])
15848    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15849   "* return output_387_binary_op (insn, operands);"
15850   [(set (attr "type")
15851         (if_then_else (eq_attr "alternative" "1")
15852            (if_then_else (match_operand:DF 3 "mult_operator" "")
15853               (const_string "ssemul")
15854               (const_string "sseadd"))
15855            (if_then_else (match_operand:DF 3 "mult_operator" "")
15856               (const_string "fmul")
15857               (const_string "fop"))))
15858    (set_attr "mode" "DF")])
15859
15860 (define_insn "*fop_df_comm_sse"
15861   [(set (match_operand:DF 0 "register_operand" "=x")
15862         (match_operator:DF 3 "binary_fp_operator"
15863           [(match_operand:DF 1 "nonimmediate_operand" "%0")
15864            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15865   "TARGET_SSE2 && TARGET_SSE_MATH
15866    && COMMUTATIVE_ARITH_P (operands[3])
15867    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15868   "* return output_387_binary_op (insn, operands);"
15869   [(set (attr "type")
15870         (if_then_else (match_operand:DF 3 "mult_operator" "")
15871            (const_string "ssemul")
15872            (const_string "sseadd")))
15873    (set_attr "mode" "DF")])
15874
15875 (define_insn "*fop_df_comm_i387"
15876   [(set (match_operand:DF 0 "register_operand" "=f")
15877         (match_operator:DF 3 "binary_fp_operator"
15878                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15879                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15880   "TARGET_80387
15881    && COMMUTATIVE_ARITH_P (operands[3])
15882    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15883   "* return output_387_binary_op (insn, operands);"
15884   [(set (attr "type")
15885         (if_then_else (match_operand:DF 3 "mult_operator" "")
15886            (const_string "fmul")
15887            (const_string "fop")))
15888    (set_attr "mode" "DF")])
15889
15890 (define_insn "*fop_df_1_mixed"
15891   [(set (match_operand:DF 0 "register_operand" "=f,f,x")
15892         (match_operator:DF 3 "binary_fp_operator"
15893           [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15894            (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
15895   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15896    && !COMMUTATIVE_ARITH_P (operands[3])
15897    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15898   "* return output_387_binary_op (insn, operands);"
15899   [(set (attr "type")
15900         (cond [(and (eq_attr "alternative" "2")
15901                     (match_operand:DF 3 "mult_operator" ""))
15902                  (const_string "ssemul")
15903                (and (eq_attr "alternative" "2")
15904                     (match_operand:DF 3 "div_operator" ""))
15905                  (const_string "ssediv")
15906                (eq_attr "alternative" "2")
15907                  (const_string "sseadd")
15908                (match_operand:DF 3 "mult_operator" "")
15909                  (const_string "fmul")
15910                (match_operand:DF 3 "div_operator" "")
15911                  (const_string "fdiv")
15912               ]
15913               (const_string "fop")))
15914    (set_attr "mode" "DF")])
15915
15916 (define_insn "*fop_df_1_sse"
15917   [(set (match_operand:DF 0 "register_operand" "=x")
15918         (match_operator:DF 3 "binary_fp_operator"
15919           [(match_operand:DF 1 "register_operand" "0")
15920            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15921   "TARGET_SSE2 && TARGET_SSE_MATH
15922    && !COMMUTATIVE_ARITH_P (operands[3])"
15923   "* return output_387_binary_op (insn, operands);"
15924   [(set_attr "mode" "DF")
15925    (set (attr "type")
15926         (cond [(match_operand:DF 3 "mult_operator" "")
15927                  (const_string "ssemul")
15928                (match_operand:DF 3 "div_operator" "")
15929                  (const_string "ssediv")
15930               ]
15931               (const_string "sseadd")))])
15932
15933 ;; This pattern is not fully shadowed by the pattern above.
15934 (define_insn "*fop_df_1_i387"
15935   [(set (match_operand:DF 0 "register_operand" "=f,f")
15936         (match_operator:DF 3 "binary_fp_operator"
15937                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15938                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15939   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15940    && !COMMUTATIVE_ARITH_P (operands[3])
15941    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15942   "* return output_387_binary_op (insn, operands);"
15943   [(set (attr "type")
15944         (cond [(match_operand:DF 3 "mult_operator" "")
15945                  (const_string "fmul")
15946                (match_operand:DF 3 "div_operator" "")
15947                  (const_string "fdiv")
15948               ]
15949               (const_string "fop")))
15950    (set_attr "mode" "DF")])
15951
15952 ;; ??? Add SSE splitters for these!
15953 (define_insn "*fop_df_2<mode>_i387"
15954   [(set (match_operand:DF 0 "register_operand" "=f,f")
15955         (match_operator:DF 3 "binary_fp_operator"
15956            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15957             (match_operand:DF 2 "register_operand" "0,0")]))]
15958   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15959    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15960   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15961   [(set (attr "type")
15962         (cond [(match_operand:DF 3 "mult_operator" "")
15963                  (const_string "fmul")
15964                (match_operand:DF 3 "div_operator" "")
15965                  (const_string "fdiv")
15966               ]
15967               (const_string "fop")))
15968    (set_attr "fp_int_src" "true")
15969    (set_attr "mode" "<MODE>")])
15970
15971 (define_insn "*fop_df_3<mode>_i387"
15972   [(set (match_operand:DF 0 "register_operand" "=f,f")
15973         (match_operator:DF 3 "binary_fp_operator"
15974            [(match_operand:DF 1 "register_operand" "0,0")
15975             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15976   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15977    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15978   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15979   [(set (attr "type")
15980         (cond [(match_operand:DF 3 "mult_operator" "")
15981                  (const_string "fmul")
15982                (match_operand:DF 3 "div_operator" "")
15983                  (const_string "fdiv")
15984               ]
15985               (const_string "fop")))
15986    (set_attr "fp_int_src" "true")
15987    (set_attr "mode" "<MODE>")])
15988
15989 (define_insn "*fop_df_4_i387"
15990   [(set (match_operand:DF 0 "register_operand" "=f,f")
15991         (match_operator:DF 3 "binary_fp_operator"
15992            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15993             (match_operand:DF 2 "register_operand" "0,f")]))]
15994   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15995    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15996   "* return output_387_binary_op (insn, operands);"
15997   [(set (attr "type")
15998         (cond [(match_operand:DF 3 "mult_operator" "")
15999                  (const_string "fmul")
16000                (match_operand:DF 3 "div_operator" "")
16001                  (const_string "fdiv")
16002               ]
16003               (const_string "fop")))
16004    (set_attr "mode" "SF")])
16005
16006 (define_insn "*fop_df_5_i387"
16007   [(set (match_operand:DF 0 "register_operand" "=f,f")
16008         (match_operator:DF 3 "binary_fp_operator"
16009           [(match_operand:DF 1 "register_operand" "0,f")
16010            (float_extend:DF
16011             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16012   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16013   "* return output_387_binary_op (insn, operands);"
16014   [(set (attr "type")
16015         (cond [(match_operand:DF 3 "mult_operator" "")
16016                  (const_string "fmul")
16017                (match_operand:DF 3 "div_operator" "")
16018                  (const_string "fdiv")
16019               ]
16020               (const_string "fop")))
16021    (set_attr "mode" "SF")])
16022
16023 (define_insn "*fop_df_6_i387"
16024   [(set (match_operand:DF 0 "register_operand" "=f,f")
16025         (match_operator:DF 3 "binary_fp_operator"
16026           [(float_extend:DF
16027             (match_operand:SF 1 "register_operand" "0,f"))
16028            (float_extend:DF
16029             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16030   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16031   "* return output_387_binary_op (insn, operands);"
16032   [(set (attr "type")
16033         (cond [(match_operand:DF 3 "mult_operator" "")
16034                  (const_string "fmul")
16035                (match_operand:DF 3 "div_operator" "")
16036                  (const_string "fdiv")
16037               ]
16038               (const_string "fop")))
16039    (set_attr "mode" "SF")])
16040
16041 (define_insn "*fop_xf_comm_i387"
16042   [(set (match_operand:XF 0 "register_operand" "=f")
16043         (match_operator:XF 3 "binary_fp_operator"
16044                         [(match_operand:XF 1 "register_operand" "%0")
16045                          (match_operand:XF 2 "register_operand" "f")]))]
16046   "TARGET_80387
16047    && COMMUTATIVE_ARITH_P (operands[3])"
16048   "* return output_387_binary_op (insn, operands);"
16049   [(set (attr "type")
16050         (if_then_else (match_operand:XF 3 "mult_operator" "")
16051            (const_string "fmul")
16052            (const_string "fop")))
16053    (set_attr "mode" "XF")])
16054
16055 (define_insn "*fop_xf_1_i387"
16056   [(set (match_operand:XF 0 "register_operand" "=f,f")
16057         (match_operator:XF 3 "binary_fp_operator"
16058                         [(match_operand:XF 1 "register_operand" "0,f")
16059                          (match_operand:XF 2 "register_operand" "f,0")]))]
16060   "TARGET_80387
16061    && !COMMUTATIVE_ARITH_P (operands[3])"
16062   "* return output_387_binary_op (insn, operands);"
16063   [(set (attr "type")
16064         (cond [(match_operand:XF 3 "mult_operator" "")
16065                  (const_string "fmul")
16066                (match_operand:XF 3 "div_operator" "")
16067                  (const_string "fdiv")
16068               ]
16069               (const_string "fop")))
16070    (set_attr "mode" "XF")])
16071
16072 (define_insn "*fop_xf_2<mode>_i387"
16073   [(set (match_operand:XF 0 "register_operand" "=f,f")
16074         (match_operator:XF 3 "binary_fp_operator"
16075            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16076             (match_operand:XF 2 "register_operand" "0,0")]))]
16077   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16078   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16079   [(set (attr "type")
16080         (cond [(match_operand:XF 3 "mult_operator" "")
16081                  (const_string "fmul")
16082                (match_operand:XF 3 "div_operator" "")
16083                  (const_string "fdiv")
16084               ]
16085               (const_string "fop")))
16086    (set_attr "fp_int_src" "true")
16087    (set_attr "mode" "<MODE>")])
16088
16089 (define_insn "*fop_xf_3<mode>_i387"
16090   [(set (match_operand:XF 0 "register_operand" "=f,f")
16091         (match_operator:XF 3 "binary_fp_operator"
16092           [(match_operand:XF 1 "register_operand" "0,0")
16093            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16094   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16095   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16096   [(set (attr "type")
16097         (cond [(match_operand:XF 3 "mult_operator" "")
16098                  (const_string "fmul")
16099                (match_operand:XF 3 "div_operator" "")
16100                  (const_string "fdiv")
16101               ]
16102               (const_string "fop")))
16103    (set_attr "fp_int_src" "true")
16104    (set_attr "mode" "<MODE>")])
16105
16106 (define_insn "*fop_xf_4_i387"
16107   [(set (match_operand:XF 0 "register_operand" "=f,f")
16108         (match_operator:XF 3 "binary_fp_operator"
16109            [(float_extend:XF
16110               (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
16111             (match_operand:XF 2 "register_operand" "0,f")]))]
16112   "TARGET_80387"
16113   "* return output_387_binary_op (insn, operands);"
16114   [(set (attr "type")
16115         (cond [(match_operand:XF 3 "mult_operator" "")
16116                  (const_string "fmul")
16117                (match_operand:XF 3 "div_operator" "")
16118                  (const_string "fdiv")
16119               ]
16120               (const_string "fop")))
16121    (set_attr "mode" "SF")])
16122
16123 (define_insn "*fop_xf_5_i387"
16124   [(set (match_operand:XF 0 "register_operand" "=f,f")
16125         (match_operator:XF 3 "binary_fp_operator"
16126           [(match_operand:XF 1 "register_operand" "0,f")
16127            (float_extend:XF
16128              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
16129   "TARGET_80387"
16130   "* return output_387_binary_op (insn, operands);"
16131   [(set (attr "type")
16132         (cond [(match_operand:XF 3 "mult_operator" "")
16133                  (const_string "fmul")
16134                (match_operand:XF 3 "div_operator" "")
16135                  (const_string "fdiv")
16136               ]
16137               (const_string "fop")))
16138    (set_attr "mode" "SF")])
16139
16140 (define_insn "*fop_xf_6_i387"
16141   [(set (match_operand:XF 0 "register_operand" "=f,f")
16142         (match_operator:XF 3 "binary_fp_operator"
16143           [(float_extend:XF
16144              (match_operand:X87MODEF12 1 "register_operand" "0,f"))
16145            (float_extend:XF
16146              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
16147   "TARGET_80387"
16148   "* return output_387_binary_op (insn, operands);"
16149   [(set (attr "type")
16150         (cond [(match_operand:XF 3 "mult_operator" "")
16151                  (const_string "fmul")
16152                (match_operand:XF 3 "div_operator" "")
16153                  (const_string "fdiv")
16154               ]
16155               (const_string "fop")))
16156    (set_attr "mode" "SF")])
16157
16158 (define_split
16159   [(set (match_operand 0 "register_operand" "")
16160         (match_operator 3 "binary_fp_operator"
16161            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16162             (match_operand 2 "register_operand" "")]))]
16163   "TARGET_80387 && reload_completed
16164    && FLOAT_MODE_P (GET_MODE (operands[0]))"
16165   [(const_int 0)]
16166 {
16167   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16168   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16169   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16170                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16171                                           GET_MODE (operands[3]),
16172                                           operands[4],
16173                                           operands[2])));
16174   ix86_free_from_memory (GET_MODE (operands[1]));
16175   DONE;
16176 })
16177
16178 (define_split
16179   [(set (match_operand 0 "register_operand" "")
16180         (match_operator 3 "binary_fp_operator"
16181            [(match_operand 1 "register_operand" "")
16182             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16183   "TARGET_80387 && reload_completed
16184    && FLOAT_MODE_P (GET_MODE (operands[0]))"
16185   [(const_int 0)]
16186 {
16187   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16188   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16189   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16190                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16191                                           GET_MODE (operands[3]),
16192                                           operands[1],
16193                                           operands[4])));
16194   ix86_free_from_memory (GET_MODE (operands[2]));
16195   DONE;
16196 })
16197 \f
16198 ;; FPU special functions.
16199
16200 ;; This pattern implements a no-op XFmode truncation for
16201 ;; all fancy i386 XFmode math functions.
16202
16203 (define_insn "truncxf<mode>2_i387_noop_unspec"
16204   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16205         (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
16206         UNSPEC_TRUNC_NOOP))]
16207   "TARGET_USE_FANCY_MATH_387"
16208   "* return output_387_reg_move (insn, operands);"
16209   [(set_attr "type" "fmov")
16210    (set_attr "mode" "<MODE>")])
16211
16212 (define_insn "sqrtxf2"
16213   [(set (match_operand:XF 0 "register_operand" "=f")
16214         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16215   "TARGET_USE_FANCY_MATH_387"
16216   "fsqrt"
16217   [(set_attr "type" "fpspc")
16218    (set_attr "mode" "XF")
16219    (set_attr "athlon_decode" "direct")
16220    (set_attr "amdfam10_decode" "direct")])
16221
16222 (define_insn "sqrt_extend<mode>xf2_i387"
16223   [(set (match_operand:XF 0 "register_operand" "=f")
16224         (sqrt:XF
16225           (float_extend:XF
16226             (match_operand:X87MODEF12 1 "register_operand" "0"))))]
16227   "TARGET_USE_FANCY_MATH_387"
16228   "fsqrt"
16229   [(set_attr "type" "fpspc")
16230    (set_attr "mode" "XF")
16231    (set_attr "athlon_decode" "direct")   
16232    (set_attr "amdfam10_decode" "direct")])
16233
16234 (define_insn "*sqrt<mode>2_sse"
16235   [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
16236         (sqrt:SSEMODEF
16237           (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
16238   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16239   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16240   [(set_attr "type" "sse")
16241    (set_attr "mode" "<MODE>")
16242    (set_attr "athlon_decode" "*")
16243    (set_attr "amdfam10_decode" "*")])
16244
16245 (define_expand "sqrt<mode>2"
16246   [(set (match_operand:X87MODEF12 0 "register_operand" "")
16247         (sqrt:X87MODEF12
16248           (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
16249   "TARGET_USE_FANCY_MATH_387
16250    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16251 {
16252   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16253     {
16254       rtx op0 = gen_reg_rtx (XFmode);
16255       rtx op1 = force_reg (<MODE>mode, operands[1]);
16256
16257       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16258       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16259       DONE;
16260    }
16261 })
16262
16263 (define_insn "fpremxf4_i387"
16264   [(set (match_operand:XF 0 "register_operand" "=f")
16265         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16266                     (match_operand:XF 3 "register_operand" "1")]
16267                    UNSPEC_FPREM_F))
16268    (set (match_operand:XF 1 "register_operand" "=u")
16269         (unspec:XF [(match_dup 2) (match_dup 3)]
16270                    UNSPEC_FPREM_U))
16271    (set (reg:CCFP FPSR_REG)
16272         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
16273   "TARGET_USE_FANCY_MATH_387"
16274   "fprem"
16275   [(set_attr "type" "fpspc")
16276    (set_attr "mode" "XF")])
16277
16278 (define_expand "fmodxf3"
16279   [(use (match_operand:XF 0 "register_operand" ""))
16280    (use (match_operand:XF 1 "register_operand" ""))
16281    (use (match_operand:XF 2 "register_operand" ""))]
16282   "TARGET_USE_FANCY_MATH_387"
16283 {
16284   rtx label = gen_label_rtx ();
16285
16286   emit_label (label);
16287
16288   emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
16289                                 operands[1], operands[2]));
16290   ix86_emit_fp_unordered_jump (label);
16291
16292   emit_move_insn (operands[0], operands[1]);
16293   DONE;
16294 })
16295
16296 (define_expand "fmod<mode>3"
16297   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16298    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16299    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16300   "TARGET_USE_FANCY_MATH_387"
16301 {
16302   rtx label = gen_label_rtx ();
16303
16304   rtx op1 = gen_reg_rtx (XFmode);
16305   rtx op2 = gen_reg_rtx (XFmode);
16306
16307   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16308   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16309
16310   emit_label (label);
16311   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16312   ix86_emit_fp_unordered_jump (label);
16313
16314   /* Truncate the result properly for strict SSE math.  */
16315   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16316       && !TARGET_MIX_SSE_I387)
16317     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16318   else
16319     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16320
16321   DONE;
16322 })
16323
16324 (define_insn "fprem1xf4_i387"
16325   [(set (match_operand:XF 0 "register_operand" "=f")
16326         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16327                     (match_operand:XF 3 "register_operand" "1")]
16328                    UNSPEC_FPREM1_F))
16329    (set (match_operand:XF 1 "register_operand" "=u")
16330         (unspec:XF [(match_dup 2) (match_dup 3)]
16331                    UNSPEC_FPREM1_U))
16332    (set (reg:CCFP FPSR_REG)
16333         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
16334   "TARGET_USE_FANCY_MATH_387"
16335   "fprem1"
16336   [(set_attr "type" "fpspc")
16337    (set_attr "mode" "XF")])
16338
16339 (define_expand "remainderxf3"
16340   [(use (match_operand:XF 0 "register_operand" ""))
16341    (use (match_operand:XF 1 "register_operand" ""))
16342    (use (match_operand:XF 2 "register_operand" ""))]
16343   "TARGET_USE_FANCY_MATH_387"
16344 {
16345   rtx label = gen_label_rtx ();
16346
16347   emit_label (label);
16348
16349   emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
16350                                  operands[1], operands[2]));
16351   ix86_emit_fp_unordered_jump (label);
16352
16353   emit_move_insn (operands[0], operands[1]);
16354   DONE;
16355 })
16356
16357 (define_expand "remainder<mode>3"
16358   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16359    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16360    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16361   "TARGET_USE_FANCY_MATH_387"
16362 {
16363   rtx label = gen_label_rtx ();
16364
16365   rtx op1 = gen_reg_rtx (XFmode);
16366   rtx op2 = gen_reg_rtx (XFmode);
16367
16368   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16369   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16370
16371   emit_label (label);
16372
16373   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16374   ix86_emit_fp_unordered_jump (label);
16375
16376   /* Truncate the result properly for strict SSE math.  */
16377   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16378       && !TARGET_MIX_SSE_I387)
16379     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16380   else
16381     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16382
16383   DONE;
16384 })
16385
16386 (define_insn "*sinxf2_i387"
16387   [(set (match_operand:XF 0 "register_operand" "=f")
16388         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16389   "TARGET_USE_FANCY_MATH_387
16390    && flag_unsafe_math_optimizations"
16391   "fsin"
16392   [(set_attr "type" "fpspc")
16393    (set_attr "mode" "XF")])
16394
16395 (define_insn "*sin_extend<mode>xf2_i387"
16396   [(set (match_operand:XF 0 "register_operand" "=f")
16397         (unspec:XF [(float_extend:XF
16398                       (match_operand:X87MODEF12 1 "register_operand" "0"))]
16399                    UNSPEC_SIN))]
16400   "TARGET_USE_FANCY_MATH_387
16401    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16402        || TARGET_MIX_SSE_I387)
16403    && flag_unsafe_math_optimizations"
16404   "fsin"
16405   [(set_attr "type" "fpspc")
16406    (set_attr "mode" "XF")])
16407
16408 (define_insn "*cosxf2_i387"
16409   [(set (match_operand:XF 0 "register_operand" "=f")
16410         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16411   "TARGET_USE_FANCY_MATH_387
16412    && flag_unsafe_math_optimizations"
16413   "fcos"
16414   [(set_attr "type" "fpspc")
16415    (set_attr "mode" "XF")])
16416
16417 (define_insn "*cos_extend<mode>xf2_i387"
16418   [(set (match_operand:XF 0 "register_operand" "=f")
16419         (unspec:XF [(float_extend:XF
16420                       (match_operand:X87MODEF12 1 "register_operand" "0"))]
16421                    UNSPEC_COS))]
16422   "TARGET_USE_FANCY_MATH_387
16423    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16424        || TARGET_MIX_SSE_I387)
16425    && flag_unsafe_math_optimizations"
16426   "fcos"
16427   [(set_attr "type" "fpspc")
16428    (set_attr "mode" "XF")])
16429
16430 ;; When sincos pattern is defined, sin and cos builtin functions will be
16431 ;; expanded to sincos pattern with one of its outputs left unused.
16432 ;; CSE pass will figure out if two sincos patterns can be combined,
16433 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16434 ;; depending on the unused output.
16435
16436 (define_insn "sincosxf3"
16437   [(set (match_operand:XF 0 "register_operand" "=f")
16438         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16439                    UNSPEC_SINCOS_COS))
16440    (set (match_operand:XF 1 "register_operand" "=u")
16441         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16442   "TARGET_USE_FANCY_MATH_387
16443    && flag_unsafe_math_optimizations"
16444   "fsincos"
16445   [(set_attr "type" "fpspc")
16446    (set_attr "mode" "XF")])
16447
16448 (define_split
16449   [(set (match_operand:XF 0 "register_operand" "")
16450         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16451                    UNSPEC_SINCOS_COS))
16452    (set (match_operand:XF 1 "register_operand" "")
16453         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16454   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16455    && !reload_completed && !reload_in_progress"
16456   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16457   "")
16458
16459 (define_split
16460   [(set (match_operand:XF 0 "register_operand" "")
16461         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16462                    UNSPEC_SINCOS_COS))
16463    (set (match_operand:XF 1 "register_operand" "")
16464         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16465   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16466    && !reload_completed && !reload_in_progress"
16467   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16468   "")
16469
16470 (define_insn "sincos_extend<mode>xf3_i387"
16471   [(set (match_operand:XF 0 "register_operand" "=f")
16472         (unspec:XF [(float_extend:XF
16473                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16474                    UNSPEC_SINCOS_COS))
16475    (set (match_operand:XF 1 "register_operand" "=u")
16476         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16477   "TARGET_USE_FANCY_MATH_387
16478    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16479        || TARGET_MIX_SSE_I387)
16480    && flag_unsafe_math_optimizations"
16481   "fsincos"
16482   [(set_attr "type" "fpspc")
16483    (set_attr "mode" "XF")])
16484
16485 (define_split
16486   [(set (match_operand:XF 0 "register_operand" "")
16487         (unspec:XF [(float_extend:XF
16488                       (match_operand:X87MODEF12 2 "register_operand" ""))]
16489                    UNSPEC_SINCOS_COS))
16490    (set (match_operand:XF 1 "register_operand" "")
16491         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16492   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16493    && !reload_completed && !reload_in_progress"
16494   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16495   "")
16496
16497 (define_split
16498   [(set (match_operand:XF 0 "register_operand" "")
16499         (unspec:XF [(float_extend:XF
16500                       (match_operand:X87MODEF12 2 "register_operand" ""))]
16501                    UNSPEC_SINCOS_COS))
16502    (set (match_operand:XF 1 "register_operand" "")
16503         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16504   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16505    && !reload_completed && !reload_in_progress"
16506   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16507   "")
16508
16509 (define_expand "sincos<mode>3"
16510   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16511    (use (match_operand:X87MODEF12 1 "register_operand" ""))
16512    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16513   "TARGET_USE_FANCY_MATH_387
16514    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16515        || TARGET_MIX_SSE_I387)
16516    && flag_unsafe_math_optimizations"
16517 {
16518   rtx op0 = gen_reg_rtx (XFmode);
16519   rtx op1 = gen_reg_rtx (XFmode);
16520
16521   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16522   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16523   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16524   DONE;
16525 })
16526
16527 (define_insn "fptanxf4_i387"
16528   [(set (match_operand:XF 0 "register_operand" "=f")
16529         (match_operand:XF 3 "const_double_operand" "F"))
16530    (set (match_operand:XF 1 "register_operand" "=u")
16531         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16532                    UNSPEC_TAN))]
16533   "TARGET_USE_FANCY_MATH_387
16534    && flag_unsafe_math_optimizations
16535    && standard_80387_constant_p (operands[3]) == 2"
16536   "fptan"
16537   [(set_attr "type" "fpspc")
16538    (set_attr "mode" "XF")])
16539
16540 (define_insn "fptan_extend<mode>xf4_i387"
16541   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16542         (match_operand:X87MODEF12 3 "const_double_operand" "F"))
16543    (set (match_operand:XF 1 "register_operand" "=u")
16544         (unspec:XF [(float_extend:XF
16545                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16546                    UNSPEC_TAN))]
16547   "TARGET_USE_FANCY_MATH_387
16548    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16549        || TARGET_MIX_SSE_I387)
16550    && flag_unsafe_math_optimizations
16551    && standard_80387_constant_p (operands[3]) == 2"
16552   "fptan"
16553   [(set_attr "type" "fpspc")
16554    (set_attr "mode" "XF")])
16555
16556 (define_expand "tanxf2"
16557   [(use (match_operand:XF 0 "register_operand" ""))
16558    (use (match_operand:XF 1 "register_operand" ""))]
16559   "TARGET_USE_FANCY_MATH_387
16560    && flag_unsafe_math_optimizations"
16561 {
16562   rtx one = gen_reg_rtx (XFmode);
16563   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16564
16565   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16566   DONE;
16567 })
16568
16569 (define_expand "tan<mode>2"
16570   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16571    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16572   "TARGET_USE_FANCY_MATH_387
16573    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16574        || TARGET_MIX_SSE_I387)
16575    && flag_unsafe_math_optimizations"
16576 {
16577   rtx op0 = gen_reg_rtx (XFmode);
16578
16579   rtx one = gen_reg_rtx (<MODE>mode);
16580   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16581
16582   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16583                                              operands[1], op2));
16584   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16585   DONE;
16586 })
16587
16588 (define_insn "*fpatanxf3_i387"
16589   [(set (match_operand:XF 0 "register_operand" "=f")
16590         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16591                     (match_operand:XF 2 "register_operand" "u")]
16592                    UNSPEC_FPATAN))
16593    (clobber (match_scratch:XF 3 "=2"))]
16594   "TARGET_USE_FANCY_MATH_387
16595    && flag_unsafe_math_optimizations"
16596   "fpatan"
16597   [(set_attr "type" "fpspc")
16598    (set_attr "mode" "XF")])
16599
16600 (define_insn "fpatan_extend<mode>xf3_i387"
16601   [(set (match_operand:XF 0 "register_operand" "=f")
16602         (unspec:XF [(float_extend:XF
16603                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16604                     (float_extend:XF
16605                       (match_operand:X87MODEF12 2 "register_operand" "u"))]
16606                    UNSPEC_FPATAN))
16607    (clobber (match_scratch:XF 3 "=2"))]
16608   "TARGET_USE_FANCY_MATH_387
16609    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16610        || TARGET_MIX_SSE_I387)
16611    && flag_unsafe_math_optimizations"
16612   "fpatan"
16613   [(set_attr "type" "fpspc")
16614    (set_attr "mode" "XF")])
16615
16616 (define_expand "atan2xf3"
16617   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16618                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
16619                                (match_operand:XF 1 "register_operand" "")]
16620                               UNSPEC_FPATAN))
16621               (clobber (match_scratch:XF 3 ""))])]
16622   "TARGET_USE_FANCY_MATH_387
16623    && flag_unsafe_math_optimizations"
16624   "")
16625
16626 (define_expand "atan2<mode>3"
16627   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16628    (use (match_operand:X87MODEF12 1 "register_operand" ""))
16629    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16630   "TARGET_USE_FANCY_MATH_387
16631    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16632        || TARGET_MIX_SSE_I387)
16633    && flag_unsafe_math_optimizations"
16634 {
16635   rtx op0 = gen_reg_rtx (XFmode);
16636
16637   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16638   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16639   DONE;
16640 })
16641
16642 (define_expand "atanxf2"
16643   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16644                    (unspec:XF [(match_dup 2)
16645                                (match_operand:XF 1 "register_operand" "")]
16646                               UNSPEC_FPATAN))
16647               (clobber (match_scratch:XF 3 ""))])]
16648   "TARGET_USE_FANCY_MATH_387
16649    && flag_unsafe_math_optimizations"
16650 {
16651   operands[2] = gen_reg_rtx (XFmode);
16652   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16653 })
16654
16655 (define_expand "atan<mode>2"
16656   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16657    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16658   "TARGET_USE_FANCY_MATH_387
16659    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16660        || TARGET_MIX_SSE_I387)
16661    && flag_unsafe_math_optimizations"
16662 {
16663   rtx op0 = gen_reg_rtx (XFmode);
16664
16665   rtx op2 = gen_reg_rtx (<MODE>mode);
16666   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
16667
16668   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16669   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16670   DONE;
16671 })
16672
16673 (define_expand "asinxf2"
16674   [(set (match_dup 2)
16675         (mult:XF (match_operand:XF 1 "register_operand" "")
16676                  (match_dup 1)))
16677    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16678    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16679    (parallel [(set (match_operand:XF 0 "register_operand" "")
16680                    (unspec:XF [(match_dup 5) (match_dup 1)]
16681                               UNSPEC_FPATAN))
16682               (clobber (match_scratch:XF 6 ""))])]
16683   "TARGET_USE_FANCY_MATH_387
16684    && flag_unsafe_math_optimizations && !optimize_size"
16685 {
16686   int i;
16687
16688   for (i = 2; i < 6; i++)
16689     operands[i] = gen_reg_rtx (XFmode);
16690
16691   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16692 })
16693
16694 (define_expand "asin<mode>2"
16695   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16696    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16697  "TARGET_USE_FANCY_MATH_387
16698    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16699        || TARGET_MIX_SSE_I387)
16700    && flag_unsafe_math_optimizations && !optimize_size"
16701 {
16702   rtx op0 = gen_reg_rtx (XFmode);
16703   rtx op1 = gen_reg_rtx (XFmode);
16704
16705   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16706   emit_insn (gen_asinxf2 (op0, op1));
16707   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16708   DONE;
16709 })
16710
16711 (define_expand "acosxf2"
16712   [(set (match_dup 2)
16713         (mult:XF (match_operand:XF 1 "register_operand" "")
16714                  (match_dup 1)))
16715    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16716    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16717    (parallel [(set (match_operand:XF 0 "register_operand" "")
16718                    (unspec:XF [(match_dup 1) (match_dup 5)]
16719                               UNSPEC_FPATAN))
16720               (clobber (match_scratch:XF 6 ""))])]
16721   "TARGET_USE_FANCY_MATH_387
16722    && flag_unsafe_math_optimizations && !optimize_size"
16723 {
16724   int i;
16725
16726   for (i = 2; i < 6; i++)
16727     operands[i] = gen_reg_rtx (XFmode);
16728
16729   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16730 })
16731
16732 (define_expand "acos<mode>2"
16733   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16734    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16735  "TARGET_USE_FANCY_MATH_387
16736    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16737        || TARGET_MIX_SSE_I387)
16738    && flag_unsafe_math_optimizations && !optimize_size"
16739 {
16740   rtx op0 = gen_reg_rtx (XFmode);
16741   rtx op1 = gen_reg_rtx (XFmode);
16742
16743   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16744   emit_insn (gen_acosxf2 (op0, op1));
16745   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16746   DONE;
16747 })
16748
16749 (define_insn "fyl2xxf3_i387"
16750   [(set (match_operand:XF 0 "register_operand" "=f")
16751         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16752                     (match_operand:XF 2 "register_operand" "u")]
16753                    UNSPEC_FYL2X))
16754    (clobber (match_scratch:XF 3 "=2"))]
16755   "TARGET_USE_FANCY_MATH_387
16756    && flag_unsafe_math_optimizations"
16757   "fyl2x"
16758   [(set_attr "type" "fpspc")
16759    (set_attr "mode" "XF")])
16760
16761 (define_insn "fyl2x_extend<mode>xf3_i387"
16762   [(set (match_operand:XF 0 "register_operand" "=f")
16763         (unspec:XF [(float_extend:XF
16764                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16765                     (match_operand:XF 2 "register_operand" "u")]
16766                    UNSPEC_FYL2X))
16767    (clobber (match_scratch:XF 3 "=2"))]
16768   "TARGET_USE_FANCY_MATH_387
16769    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16770        || TARGET_MIX_SSE_I387)
16771    && flag_unsafe_math_optimizations"
16772   "fyl2x"
16773   [(set_attr "type" "fpspc")
16774    (set_attr "mode" "XF")])
16775
16776 (define_expand "logxf2"
16777   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16778                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16779                                (match_dup 2)] UNSPEC_FYL2X))
16780               (clobber (match_scratch:XF 3 ""))])]
16781   "TARGET_USE_FANCY_MATH_387
16782    && flag_unsafe_math_optimizations"
16783 {
16784   operands[2] = gen_reg_rtx (XFmode);
16785   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16786 })
16787
16788 (define_expand "log<mode>2"
16789   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16790    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16791   "TARGET_USE_FANCY_MATH_387
16792    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16793        || TARGET_MIX_SSE_I387)
16794    && flag_unsafe_math_optimizations"
16795 {
16796   rtx op0 = gen_reg_rtx (XFmode);
16797
16798   rtx op2 = gen_reg_rtx (XFmode);
16799   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16800
16801   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16802   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16803   DONE;
16804 })
16805
16806 (define_expand "log10xf2"
16807   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16808                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16809                                (match_dup 2)] UNSPEC_FYL2X))
16810               (clobber (match_scratch:XF 3 ""))])]
16811   "TARGET_USE_FANCY_MATH_387
16812    && flag_unsafe_math_optimizations"
16813 {
16814   operands[2] = gen_reg_rtx (XFmode);
16815   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16816 })
16817
16818 (define_expand "log10<mode>2"
16819   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16820    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16821   "TARGET_USE_FANCY_MATH_387
16822    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16823        || TARGET_MIX_SSE_I387)
16824    && flag_unsafe_math_optimizations"
16825 {
16826   rtx op0 = gen_reg_rtx (XFmode);
16827
16828   rtx op2 = gen_reg_rtx (XFmode);
16829   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16830
16831   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16832   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16833   DONE;
16834 })
16835
16836 (define_expand "log2xf2"
16837   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16838                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16839                                (match_dup 2)] UNSPEC_FYL2X))
16840               (clobber (match_scratch:XF 3 ""))])]
16841   "TARGET_USE_FANCY_MATH_387
16842    && flag_unsafe_math_optimizations"
16843 {
16844   operands[2] = gen_reg_rtx (XFmode);
16845   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16846 })
16847
16848 (define_expand "log2<mode>2"
16849   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16850    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16851   "TARGET_USE_FANCY_MATH_387
16852    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16853        || TARGET_MIX_SSE_I387)
16854    && flag_unsafe_math_optimizations"
16855 {
16856   rtx op0 = gen_reg_rtx (XFmode);
16857
16858   rtx op2 = gen_reg_rtx (XFmode);
16859   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16860
16861   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16862   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16863   DONE;
16864 })
16865
16866 (define_insn "fyl2xp1xf3_i387"
16867   [(set (match_operand:XF 0 "register_operand" "=f")
16868         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16869                     (match_operand:XF 2 "register_operand" "u")]
16870                    UNSPEC_FYL2XP1))
16871    (clobber (match_scratch:XF 3 "=2"))]
16872   "TARGET_USE_FANCY_MATH_387
16873    && flag_unsafe_math_optimizations"
16874   "fyl2xp1"
16875   [(set_attr "type" "fpspc")
16876    (set_attr "mode" "XF")])
16877
16878 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16879   [(set (match_operand:XF 0 "register_operand" "=f")
16880         (unspec:XF [(float_extend:XF
16881                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16882                     (match_operand:XF 2 "register_operand" "u")]
16883                    UNSPEC_FYL2XP1))
16884    (clobber (match_scratch:XF 3 "=2"))]
16885   "TARGET_USE_FANCY_MATH_387
16886    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16887        || TARGET_MIX_SSE_I387)
16888    && flag_unsafe_math_optimizations"
16889   "fyl2xp1"
16890   [(set_attr "type" "fpspc")
16891    (set_attr "mode" "XF")])
16892
16893 (define_expand "log1pxf2"
16894   [(use (match_operand:XF 0 "register_operand" ""))
16895    (use (match_operand:XF 1 "register_operand" ""))]
16896   "TARGET_USE_FANCY_MATH_387
16897    && flag_unsafe_math_optimizations && !optimize_size"
16898 {
16899   ix86_emit_i387_log1p (operands[0], operands[1]);
16900   DONE;
16901 })
16902
16903 (define_expand "log1p<mode>2"
16904   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16905    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16906   "TARGET_USE_FANCY_MATH_387
16907    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16908        || TARGET_MIX_SSE_I387)
16909    && flag_unsafe_math_optimizations && !optimize_size"
16910 {
16911   rtx op0 = gen_reg_rtx (XFmode);
16912
16913   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16914
16915   ix86_emit_i387_log1p (op0, operands[1]);
16916   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16917   DONE;
16918 })
16919
16920 (define_insn "fxtractxf3_i387"
16921   [(set (match_operand:XF 0 "register_operand" "=f")
16922         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16923                    UNSPEC_XTRACT_FRACT))
16924    (set (match_operand:XF 1 "register_operand" "=u")
16925         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16926   "TARGET_USE_FANCY_MATH_387
16927    && flag_unsafe_math_optimizations"
16928   "fxtract"
16929   [(set_attr "type" "fpspc")
16930    (set_attr "mode" "XF")])
16931
16932 (define_insn "fxtract_extend<mode>xf3_i387"
16933   [(set (match_operand:XF 0 "register_operand" "=f")
16934         (unspec:XF [(float_extend:XF
16935                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16936                    UNSPEC_XTRACT_FRACT))
16937    (set (match_operand:XF 1 "register_operand" "=u")
16938         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16939   "TARGET_USE_FANCY_MATH_387
16940    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16941        || TARGET_MIX_SSE_I387)
16942    && flag_unsafe_math_optimizations"
16943   "fxtract"
16944   [(set_attr "type" "fpspc")
16945    (set_attr "mode" "XF")])
16946
16947 (define_expand "logbxf2"
16948   [(parallel [(set (match_dup 2)
16949                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16950                               UNSPEC_XTRACT_FRACT))
16951               (set (match_operand:XF 0 "register_operand" "")
16952                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16953   "TARGET_USE_FANCY_MATH_387
16954    && flag_unsafe_math_optimizations"
16955 {
16956   operands[2] = gen_reg_rtx (XFmode);
16957 })
16958
16959 (define_expand "logb<mode>2"
16960   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16961    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16962   "TARGET_USE_FANCY_MATH_387
16963    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16964        || TARGET_MIX_SSE_I387)
16965    && flag_unsafe_math_optimizations"
16966 {
16967   rtx op0 = gen_reg_rtx (XFmode);
16968   rtx op1 = gen_reg_rtx (XFmode);
16969
16970   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16971   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16972   DONE;
16973 })
16974
16975 (define_expand "ilogbxf2"
16976   [(use (match_operand:SI 0 "register_operand" ""))
16977    (use (match_operand:XF 1 "register_operand" ""))]
16978   "TARGET_USE_FANCY_MATH_387
16979    && flag_unsafe_math_optimizations && !optimize_size"
16980 {
16981   rtx op0 = gen_reg_rtx (XFmode);
16982   rtx op1 = gen_reg_rtx (XFmode);
16983
16984   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16985   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16986   DONE;
16987 })
16988
16989 (define_expand "ilogb<mode>2"
16990   [(use (match_operand:SI 0 "register_operand" ""))
16991    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16992   "TARGET_USE_FANCY_MATH_387
16993    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16994        || TARGET_MIX_SSE_I387)
16995    && flag_unsafe_math_optimizations && !optimize_size"
16996 {
16997   rtx op0 = gen_reg_rtx (XFmode);
16998   rtx op1 = gen_reg_rtx (XFmode);
16999
17000   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17001   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17002   DONE;
17003 })
17004
17005 (define_insn "*f2xm1xf2_i387"
17006   [(set (match_operand:XF 0 "register_operand" "=f")
17007         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17008                    UNSPEC_F2XM1))]
17009   "TARGET_USE_FANCY_MATH_387
17010    && flag_unsafe_math_optimizations"
17011   "f2xm1"
17012   [(set_attr "type" "fpspc")
17013    (set_attr "mode" "XF")])
17014
17015 (define_insn "*fscalexf4_i387"
17016   [(set (match_operand:XF 0 "register_operand" "=f")
17017         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17018                     (match_operand:XF 3 "register_operand" "1")]
17019                    UNSPEC_FSCALE_FRACT))
17020    (set (match_operand:XF 1 "register_operand" "=u")
17021         (unspec:XF [(match_dup 2) (match_dup 3)]
17022                    UNSPEC_FSCALE_EXP))]
17023   "TARGET_USE_FANCY_MATH_387
17024    && flag_unsafe_math_optimizations"
17025   "fscale"
17026   [(set_attr "type" "fpspc")
17027    (set_attr "mode" "XF")])
17028
17029 (define_expand "expNcorexf3"
17030   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17031                                (match_operand:XF 2 "register_operand" "")))
17032    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17033    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17034    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17035    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17036    (parallel [(set (match_operand:XF 0 "register_operand" "")
17037                    (unspec:XF [(match_dup 8) (match_dup 4)]
17038                               UNSPEC_FSCALE_FRACT))
17039               (set (match_dup 9)
17040                    (unspec:XF [(match_dup 8) (match_dup 4)]
17041                               UNSPEC_FSCALE_EXP))])]
17042   "TARGET_USE_FANCY_MATH_387
17043    && flag_unsafe_math_optimizations && !optimize_size"
17044 {
17045   int i;
17046
17047   for (i = 3; i < 10; i++)
17048     operands[i] = gen_reg_rtx (XFmode);
17049
17050   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17051 })
17052
17053 (define_expand "expxf2"
17054   [(use (match_operand:XF 0 "register_operand" ""))
17055    (use (match_operand:XF 1 "register_operand" ""))]
17056   "TARGET_USE_FANCY_MATH_387
17057    && flag_unsafe_math_optimizations && !optimize_size"
17058 {
17059   rtx op2 = gen_reg_rtx (XFmode);
17060   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17061
17062   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17063   DONE;
17064 })
17065
17066 (define_expand "exp<mode>2"
17067   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17068    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17069  "TARGET_USE_FANCY_MATH_387
17070    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17071        || TARGET_MIX_SSE_I387)
17072    && flag_unsafe_math_optimizations && !optimize_size"
17073 {
17074   rtx op0 = gen_reg_rtx (XFmode);
17075   rtx op1 = gen_reg_rtx (XFmode);
17076
17077   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17078   emit_insn (gen_expxf2 (op0, op1));
17079   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17080   DONE;
17081 })
17082
17083 (define_expand "exp10xf2"
17084   [(use (match_operand:XF 0 "register_operand" ""))
17085    (use (match_operand:XF 1 "register_operand" ""))]
17086   "TARGET_USE_FANCY_MATH_387
17087    && flag_unsafe_math_optimizations && !optimize_size"
17088 {
17089   rtx op2 = gen_reg_rtx (XFmode);
17090   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17091
17092   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17093   DONE;
17094 })
17095
17096 (define_expand "exp10<mode>2"
17097   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17098    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17099  "TARGET_USE_FANCY_MATH_387
17100    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17101        || TARGET_MIX_SSE_I387)
17102    && flag_unsafe_math_optimizations && !optimize_size"
17103 {
17104   rtx op0 = gen_reg_rtx (XFmode);
17105   rtx op1 = gen_reg_rtx (XFmode);
17106
17107   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17108   emit_insn (gen_exp10xf2 (op0, op1));
17109   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17110   DONE;
17111 })
17112
17113 (define_expand "exp2xf2"
17114   [(use (match_operand:XF 0 "register_operand" ""))
17115    (use (match_operand:XF 1 "register_operand" ""))]
17116   "TARGET_USE_FANCY_MATH_387
17117    && flag_unsafe_math_optimizations && !optimize_size"
17118 {
17119   rtx op2 = gen_reg_rtx (XFmode);
17120   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17121
17122   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17123   DONE;
17124 })
17125
17126 (define_expand "exp2<mode>2"
17127   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17128    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17129  "TARGET_USE_FANCY_MATH_387
17130    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17131        || TARGET_MIX_SSE_I387)
17132    && flag_unsafe_math_optimizations && !optimize_size"
17133 {
17134   rtx op0 = gen_reg_rtx (XFmode);
17135   rtx op1 = gen_reg_rtx (XFmode);
17136
17137   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17138   emit_insn (gen_exp2xf2 (op0, op1));
17139   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17140   DONE;
17141 })
17142
17143 (define_expand "expm1xf2"
17144   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17145                                (match_dup 2)))
17146    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17147    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17148    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17149    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17150    (parallel [(set (match_dup 7)
17151                    (unspec:XF [(match_dup 6) (match_dup 4)]
17152                               UNSPEC_FSCALE_FRACT))
17153               (set (match_dup 8)
17154                    (unspec:XF [(match_dup 6) (match_dup 4)]
17155                               UNSPEC_FSCALE_EXP))])
17156    (parallel [(set (match_dup 10)
17157                    (unspec:XF [(match_dup 9) (match_dup 8)]
17158                               UNSPEC_FSCALE_FRACT))
17159               (set (match_dup 11)
17160                    (unspec:XF [(match_dup 9) (match_dup 8)]
17161                               UNSPEC_FSCALE_EXP))])
17162    (set (match_dup 12) (minus:XF (match_dup 10)
17163                                  (float_extend:XF (match_dup 13))))
17164    (set (match_operand:XF 0 "register_operand" "")
17165         (plus:XF (match_dup 12) (match_dup 7)))]
17166   "TARGET_USE_FANCY_MATH_387
17167    && flag_unsafe_math_optimizations && !optimize_size"
17168 {
17169   int i;
17170
17171   for (i = 2; i < 13; i++)
17172     operands[i] = gen_reg_rtx (XFmode);
17173
17174   operands[13]
17175     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17176
17177   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17178 })
17179
17180 (define_expand "expm1<mode>2"
17181   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17182    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17183  "TARGET_USE_FANCY_MATH_387
17184    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17185        || TARGET_MIX_SSE_I387)
17186    && flag_unsafe_math_optimizations && !optimize_size"
17187 {
17188   rtx op0 = gen_reg_rtx (XFmode);
17189   rtx op1 = gen_reg_rtx (XFmode);
17190
17191   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17192   emit_insn (gen_expm1xf2 (op0, op1));
17193   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17194   DONE;
17195 })
17196
17197 (define_expand "ldexpxf3"
17198   [(set (match_dup 3)
17199         (float:XF (match_operand:SI 2 "register_operand" "")))
17200    (parallel [(set (match_operand:XF 0 " register_operand" "")
17201                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17202                                (match_dup 3)]
17203                               UNSPEC_FSCALE_FRACT))
17204               (set (match_dup 4)
17205                    (unspec:XF [(match_dup 1) (match_dup 3)]
17206                               UNSPEC_FSCALE_EXP))])]
17207   "TARGET_USE_FANCY_MATH_387
17208    && flag_unsafe_math_optimizations && !optimize_size"
17209 {
17210   operands[3] = gen_reg_rtx (XFmode);
17211   operands[4] = gen_reg_rtx (XFmode);
17212 })
17213
17214 (define_expand "ldexp<mode>3"
17215   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17216    (use (match_operand:X87MODEF12 1 "general_operand" ""))
17217    (use (match_operand:SI 2 "register_operand" ""))]
17218  "TARGET_USE_FANCY_MATH_387
17219    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17220        || TARGET_MIX_SSE_I387)
17221    && flag_unsafe_math_optimizations && !optimize_size"
17222 {
17223   rtx op0 = gen_reg_rtx (XFmode);
17224   rtx op1 = gen_reg_rtx (XFmode);
17225
17226   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17227   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17228   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17229   DONE;
17230 })
17231
17232 (define_expand "scalbxf3"
17233   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17234                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17235                                (match_operand:XF 2 "register_operand" "")]
17236                               UNSPEC_FSCALE_FRACT))
17237               (set (match_dup 3)
17238                    (unspec:XF [(match_dup 1) (match_dup 2)]
17239                               UNSPEC_FSCALE_EXP))])]
17240   "TARGET_USE_FANCY_MATH_387
17241    && flag_unsafe_math_optimizations && !optimize_size"
17242 {
17243   operands[3] = gen_reg_rtx (XFmode);
17244 })
17245
17246 (define_expand "scalb<mode>3"
17247   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17248    (use (match_operand:X87MODEF12 1 "general_operand" ""))
17249    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
17250  "TARGET_USE_FANCY_MATH_387
17251    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17252        || TARGET_MIX_SSE_I387)
17253    && flag_unsafe_math_optimizations && !optimize_size"
17254 {
17255   rtx op0 = gen_reg_rtx (XFmode);
17256   rtx op1 = gen_reg_rtx (XFmode);
17257   rtx op2 = gen_reg_rtx (XFmode);
17258
17259   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17260   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17261   emit_insn (gen_scalbxf3 (op0, op1, op2));
17262   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17263   DONE;
17264 })
17265 \f
17266
17267 (define_insn "frndintxf2"
17268   [(set (match_operand:XF 0 "register_operand" "=f")
17269         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17270          UNSPEC_FRNDINT))]
17271   "TARGET_USE_FANCY_MATH_387
17272    && flag_unsafe_math_optimizations"
17273   "frndint"
17274   [(set_attr "type" "fpspc")
17275    (set_attr "mode" "XF")])
17276
17277 (define_expand "rintdf2"
17278   [(use (match_operand:DF 0 "register_operand" ""))
17279    (use (match_operand:DF 1 "register_operand" ""))]
17280   "(TARGET_USE_FANCY_MATH_387
17281     && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17282     && flag_unsafe_math_optimizations)
17283    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17284        && !flag_trapping_math
17285        && !optimize_size)"
17286 {
17287   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17288       && !flag_trapping_math
17289       && !optimize_size)
17290     ix86_expand_rint (operand0, operand1);
17291   else
17292     {
17293       rtx op0 = gen_reg_rtx (XFmode);
17294       rtx op1 = gen_reg_rtx (XFmode);
17295
17296       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17297       emit_insn (gen_frndintxf2 (op0, op1));
17298
17299       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17300     }
17301   DONE;
17302 })
17303
17304 (define_expand "rintsf2"
17305   [(use (match_operand:SF 0 "register_operand" ""))
17306    (use (match_operand:SF 1 "register_operand" ""))]
17307   "(TARGET_USE_FANCY_MATH_387
17308     && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17309     && flag_unsafe_math_optimizations)
17310    || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17311        && !flag_trapping_math
17312        && !optimize_size)"
17313 {
17314   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17315       && !flag_trapping_math
17316       && !optimize_size)
17317     ix86_expand_rint (operand0, operand1);
17318   else
17319     {
17320       rtx op0 = gen_reg_rtx (XFmode);
17321       rtx op1 = gen_reg_rtx (XFmode);
17322
17323       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17324       emit_insn (gen_frndintxf2 (op0, op1));
17325
17326       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17327     }
17328   DONE;
17329 })
17330
17331 (define_expand "rintxf2"
17332   [(use (match_operand:XF 0 "register_operand" ""))
17333    (use (match_operand:XF 1 "register_operand" ""))]
17334   "TARGET_USE_FANCY_MATH_387
17335    && flag_unsafe_math_optimizations && !optimize_size"
17336 {
17337   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17338   DONE;
17339 })
17340
17341 (define_expand "roundsf2"
17342   [(match_operand:SF 0 "register_operand" "")
17343    (match_operand:SF 1 "nonimmediate_operand" "")]
17344   "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17345    && !flag_trapping_math && !flag_rounding_math
17346    && !optimize_size"
17347 {
17348   ix86_expand_round (operand0, operand1);
17349   DONE;
17350 })
17351
17352 (define_expand "rounddf2"
17353   [(match_operand:DF 0 "register_operand" "")
17354    (match_operand:DF 1 "nonimmediate_operand" "")]
17355   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17356    && !flag_trapping_math && !flag_rounding_math
17357    && !optimize_size"
17358 {
17359   if (TARGET_64BIT)
17360     ix86_expand_round (operand0, operand1);
17361   else
17362     ix86_expand_rounddf_32 (operand0, operand1);
17363   DONE;
17364 })
17365
17366 (define_insn_and_split "*fistdi2_1"
17367   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17368         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17369          UNSPEC_FIST))]
17370   "TARGET_USE_FANCY_MATH_387
17371    && !(reload_completed || reload_in_progress)"
17372   "#"
17373   "&& 1"
17374   [(const_int 0)]
17375 {
17376   if (memory_operand (operands[0], VOIDmode))
17377     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17378   else
17379     {
17380       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17381       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17382                                          operands[2]));
17383     }
17384   DONE;
17385 }
17386   [(set_attr "type" "fpspc")
17387    (set_attr "mode" "DI")])
17388
17389 (define_insn "fistdi2"
17390   [(set (match_operand:DI 0 "memory_operand" "=m")
17391         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17392          UNSPEC_FIST))
17393    (clobber (match_scratch:XF 2 "=&1f"))]
17394   "TARGET_USE_FANCY_MATH_387"
17395   "* return output_fix_trunc (insn, operands, 0);"
17396   [(set_attr "type" "fpspc")
17397    (set_attr "mode" "DI")])
17398
17399 (define_insn "fistdi2_with_temp"
17400   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17401         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17402          UNSPEC_FIST))
17403    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17404    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17405   "TARGET_USE_FANCY_MATH_387"
17406   "#"
17407   [(set_attr "type" "fpspc")
17408    (set_attr "mode" "DI")])
17409
17410 (define_split
17411   [(set (match_operand:DI 0 "register_operand" "")
17412         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17413          UNSPEC_FIST))
17414    (clobber (match_operand:DI 2 "memory_operand" ""))
17415    (clobber (match_scratch 3 ""))]
17416   "reload_completed"
17417   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17418               (clobber (match_dup 3))])
17419    (set (match_dup 0) (match_dup 2))]
17420   "")
17421
17422 (define_split
17423   [(set (match_operand:DI 0 "memory_operand" "")
17424         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17425          UNSPEC_FIST))
17426    (clobber (match_operand:DI 2 "memory_operand" ""))
17427    (clobber (match_scratch 3 ""))]
17428   "reload_completed"
17429   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17430               (clobber (match_dup 3))])]
17431   "")
17432
17433 (define_insn_and_split "*fist<mode>2_1"
17434   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17435         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17436          UNSPEC_FIST))]
17437   "TARGET_USE_FANCY_MATH_387
17438    && !(reload_completed || reload_in_progress)"
17439   "#"
17440   "&& 1"
17441   [(const_int 0)]
17442 {
17443   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17444   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17445                                         operands[2]));
17446   DONE;
17447 }
17448   [(set_attr "type" "fpspc")
17449    (set_attr "mode" "<MODE>")])
17450
17451 (define_insn "fist<mode>2"
17452   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17453         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17454          UNSPEC_FIST))]
17455   "TARGET_USE_FANCY_MATH_387"
17456   "* return output_fix_trunc (insn, operands, 0);"
17457   [(set_attr "type" "fpspc")
17458    (set_attr "mode" "<MODE>")])
17459
17460 (define_insn "fist<mode>2_with_temp"
17461   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17462         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17463          UNSPEC_FIST))
17464    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17465   "TARGET_USE_FANCY_MATH_387"
17466   "#"
17467   [(set_attr "type" "fpspc")
17468    (set_attr "mode" "<MODE>")])
17469
17470 (define_split
17471   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17472         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17473          UNSPEC_FIST))
17474    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17475   "reload_completed"
17476   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17477                        UNSPEC_FIST))
17478    (set (match_dup 0) (match_dup 2))]
17479   "")
17480
17481 (define_split
17482   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17483         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17484          UNSPEC_FIST))
17485    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17486   "reload_completed"
17487   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17488                        UNSPEC_FIST))]
17489   "")
17490
17491 (define_expand "lrintxf<mode>2"
17492   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17493      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17494       UNSPEC_FIST))]
17495   "TARGET_USE_FANCY_MATH_387"
17496   "")
17497
17498 (define_expand "lrint<mode>di2"
17499   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17500      (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
17501       UNSPEC_FIX_NOTRUNC))]
17502   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
17503   "")
17504
17505 (define_expand "lrint<mode>si2"
17506   [(set (match_operand:SI 0 "nonimmediate_operand" "")
17507      (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
17508       UNSPEC_FIX_NOTRUNC))]
17509   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17510   "")
17511
17512 (define_expand "lround<mode>di2"
17513   [(match_operand:DI 0 "nonimmediate_operand" "")
17514    (match_operand:SSEMODEF 1 "register_operand" "")]
17515   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17516    && !flag_trapping_math && !flag_rounding_math
17517    && !optimize_size"
17518 {
17519   ix86_expand_lround (operand0, operand1);
17520   DONE;
17521 })
17522
17523 (define_expand "lround<mode>si2"
17524   [(match_operand:SI 0 "nonimmediate_operand" "")
17525    (match_operand:SSEMODEF 1 "register_operand" "")]
17526   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17527    && !flag_trapping_math && !flag_rounding_math
17528    && !optimize_size"
17529 {
17530   ix86_expand_lround (operand0, operand1);
17531   DONE;
17532 })
17533
17534 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17535 (define_insn_and_split "frndintxf2_floor"
17536   [(set (match_operand:XF 0 "register_operand" "=f")
17537         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17538          UNSPEC_FRNDINT_FLOOR))
17539    (clobber (reg:CC FLAGS_REG))]
17540   "TARGET_USE_FANCY_MATH_387
17541    && flag_unsafe_math_optimizations
17542    && !(reload_completed || reload_in_progress)"
17543   "#"
17544   "&& 1"
17545   [(const_int 0)]
17546 {
17547   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17548
17549   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17550   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17551
17552   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17553                                         operands[2], operands[3]));
17554   DONE;
17555 }
17556   [(set_attr "type" "frndint")
17557    (set_attr "i387_cw" "floor")
17558    (set_attr "mode" "XF")])
17559
17560 (define_insn "frndintxf2_floor_i387"
17561   [(set (match_operand:XF 0 "register_operand" "=f")
17562         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17563          UNSPEC_FRNDINT_FLOOR))
17564    (use (match_operand:HI 2 "memory_operand" "m"))
17565    (use (match_operand:HI 3 "memory_operand" "m"))]
17566   "TARGET_USE_FANCY_MATH_387
17567    && flag_unsafe_math_optimizations"
17568   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17569   [(set_attr "type" "frndint")
17570    (set_attr "i387_cw" "floor")
17571    (set_attr "mode" "XF")])
17572
17573 (define_expand "floorxf2"
17574   [(use (match_operand:XF 0 "register_operand" ""))
17575    (use (match_operand:XF 1 "register_operand" ""))]
17576   "TARGET_USE_FANCY_MATH_387
17577    && flag_unsafe_math_optimizations && !optimize_size"
17578 {
17579   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17580   DONE;
17581 })
17582
17583 (define_expand "floordf2"
17584   [(use (match_operand:DF 0 "register_operand" ""))
17585    (use (match_operand:DF 1 "register_operand" ""))]
17586   "((TARGET_USE_FANCY_MATH_387
17587      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17588      && flag_unsafe_math_optimizations)
17589     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17590         && !flag_trapping_math))
17591    && !optimize_size"
17592 {
17593   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17594       && !flag_trapping_math)
17595     {
17596       if (TARGET_64BIT)
17597         ix86_expand_floorceil (operand0, operand1, true);
17598       else
17599         ix86_expand_floorceildf_32 (operand0, operand1, true);
17600     }
17601   else
17602     {
17603       rtx op0 = gen_reg_rtx (XFmode);
17604       rtx op1 = gen_reg_rtx (XFmode);
17605
17606       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17607       emit_insn (gen_frndintxf2_floor (op0, op1));
17608
17609       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17610     }
17611   DONE;
17612 })
17613
17614 (define_expand "floorsf2"
17615   [(use (match_operand:SF 0 "register_operand" ""))
17616    (use (match_operand:SF 1 "register_operand" ""))]
17617   "((TARGET_USE_FANCY_MATH_387
17618      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17619      && flag_unsafe_math_optimizations)
17620     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17621         && !flag_trapping_math))
17622    && !optimize_size"
17623 {
17624   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17625       && !flag_trapping_math)
17626     ix86_expand_floorceil (operand0, operand1, true);
17627   else
17628     {
17629       rtx op0 = gen_reg_rtx (XFmode);
17630       rtx op1 = gen_reg_rtx (XFmode);
17631
17632       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17633       emit_insn (gen_frndintxf2_floor (op0, op1));
17634
17635       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17636     }
17637   DONE;
17638 })
17639
17640 (define_insn_and_split "*fist<mode>2_floor_1"
17641   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17642         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17643          UNSPEC_FIST_FLOOR))
17644    (clobber (reg:CC FLAGS_REG))]
17645   "TARGET_USE_FANCY_MATH_387
17646    && flag_unsafe_math_optimizations
17647    && !(reload_completed || reload_in_progress)"
17648   "#"
17649   "&& 1"
17650   [(const_int 0)]
17651 {
17652   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17653
17654   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17655   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17656   if (memory_operand (operands[0], VOIDmode))
17657     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17658                                       operands[2], operands[3]));
17659   else
17660     {
17661       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17662       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17663                                                   operands[2], operands[3],
17664                                                   operands[4]));
17665     }
17666   DONE;
17667 }
17668   [(set_attr "type" "fistp")
17669    (set_attr "i387_cw" "floor")
17670    (set_attr "mode" "<MODE>")])
17671
17672 (define_insn "fistdi2_floor"
17673   [(set (match_operand:DI 0 "memory_operand" "=m")
17674         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17675          UNSPEC_FIST_FLOOR))
17676    (use (match_operand:HI 2 "memory_operand" "m"))
17677    (use (match_operand:HI 3 "memory_operand" "m"))
17678    (clobber (match_scratch:XF 4 "=&1f"))]
17679   "TARGET_USE_FANCY_MATH_387
17680    && flag_unsafe_math_optimizations"
17681   "* return output_fix_trunc (insn, operands, 0);"
17682   [(set_attr "type" "fistp")
17683    (set_attr "i387_cw" "floor")
17684    (set_attr "mode" "DI")])
17685
17686 (define_insn "fistdi2_floor_with_temp"
17687   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17688         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17689          UNSPEC_FIST_FLOOR))
17690    (use (match_operand:HI 2 "memory_operand" "m,m"))
17691    (use (match_operand:HI 3 "memory_operand" "m,m"))
17692    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17693    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17694   "TARGET_USE_FANCY_MATH_387
17695    && flag_unsafe_math_optimizations"
17696   "#"
17697   [(set_attr "type" "fistp")
17698    (set_attr "i387_cw" "floor")
17699    (set_attr "mode" "DI")])
17700
17701 (define_split
17702   [(set (match_operand:DI 0 "register_operand" "")
17703         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17704          UNSPEC_FIST_FLOOR))
17705    (use (match_operand:HI 2 "memory_operand" ""))
17706    (use (match_operand:HI 3 "memory_operand" ""))
17707    (clobber (match_operand:DI 4 "memory_operand" ""))
17708    (clobber (match_scratch 5 ""))]
17709   "reload_completed"
17710   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17711               (use (match_dup 2))
17712               (use (match_dup 3))
17713               (clobber (match_dup 5))])
17714    (set (match_dup 0) (match_dup 4))]
17715   "")
17716
17717 (define_split
17718   [(set (match_operand:DI 0 "memory_operand" "")
17719         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17720          UNSPEC_FIST_FLOOR))
17721    (use (match_operand:HI 2 "memory_operand" ""))
17722    (use (match_operand:HI 3 "memory_operand" ""))
17723    (clobber (match_operand:DI 4 "memory_operand" ""))
17724    (clobber (match_scratch 5 ""))]
17725   "reload_completed"
17726   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17727               (use (match_dup 2))
17728               (use (match_dup 3))
17729               (clobber (match_dup 5))])]
17730   "")
17731
17732 (define_insn "fist<mode>2_floor"
17733   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17734         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17735          UNSPEC_FIST_FLOOR))
17736    (use (match_operand:HI 2 "memory_operand" "m"))
17737    (use (match_operand:HI 3 "memory_operand" "m"))]
17738   "TARGET_USE_FANCY_MATH_387
17739    && flag_unsafe_math_optimizations"
17740   "* return output_fix_trunc (insn, operands, 0);"
17741   [(set_attr "type" "fistp")
17742    (set_attr "i387_cw" "floor")
17743    (set_attr "mode" "<MODE>")])
17744
17745 (define_insn "fist<mode>2_floor_with_temp"
17746   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17747         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17748          UNSPEC_FIST_FLOOR))
17749    (use (match_operand:HI 2 "memory_operand" "m,m"))
17750    (use (match_operand:HI 3 "memory_operand" "m,m"))
17751    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17752   "TARGET_USE_FANCY_MATH_387
17753    && flag_unsafe_math_optimizations"
17754   "#"
17755   [(set_attr "type" "fistp")
17756    (set_attr "i387_cw" "floor")
17757    (set_attr "mode" "<MODE>")])
17758
17759 (define_split
17760   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17761         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17762          UNSPEC_FIST_FLOOR))
17763    (use (match_operand:HI 2 "memory_operand" ""))
17764    (use (match_operand:HI 3 "memory_operand" ""))
17765    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17766   "reload_completed"
17767   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17768                                   UNSPEC_FIST_FLOOR))
17769               (use (match_dup 2))
17770               (use (match_dup 3))])
17771    (set (match_dup 0) (match_dup 4))]
17772   "")
17773
17774 (define_split
17775   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17776         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17777          UNSPEC_FIST_FLOOR))
17778    (use (match_operand:HI 2 "memory_operand" ""))
17779    (use (match_operand:HI 3 "memory_operand" ""))
17780    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17781   "reload_completed"
17782   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17783                                   UNSPEC_FIST_FLOOR))
17784               (use (match_dup 2))
17785               (use (match_dup 3))])]
17786   "")
17787
17788 (define_expand "lfloorxf<mode>2"
17789   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17790                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17791                     UNSPEC_FIST_FLOOR))
17792               (clobber (reg:CC FLAGS_REG))])]
17793   "TARGET_USE_FANCY_MATH_387
17794    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17795    && flag_unsafe_math_optimizations"
17796   "")
17797
17798 (define_expand "lfloor<mode>di2"
17799   [(match_operand:DI 0 "nonimmediate_operand" "")
17800    (match_operand:SSEMODEF 1 "register_operand" "")]
17801   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17802    && !flag_trapping_math
17803    && !optimize_size"
17804 {
17805   ix86_expand_lfloorceil (operand0, operand1, true);
17806   DONE;
17807 })
17808
17809 (define_expand "lfloor<mode>si2"
17810   [(match_operand:SI 0 "nonimmediate_operand" "")
17811    (match_operand:SSEMODEF 1 "register_operand" "")]
17812   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17813    && !flag_trapping_math
17814    && (!optimize_size || !TARGET_64BIT)"
17815 {
17816   ix86_expand_lfloorceil (operand0, operand1, true);
17817   DONE;
17818 })
17819
17820 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17821 (define_insn_and_split "frndintxf2_ceil"
17822   [(set (match_operand:XF 0 "register_operand" "=f")
17823         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17824          UNSPEC_FRNDINT_CEIL))
17825    (clobber (reg:CC FLAGS_REG))]
17826   "TARGET_USE_FANCY_MATH_387
17827    && flag_unsafe_math_optimizations
17828    && !(reload_completed || reload_in_progress)"
17829   "#"
17830   "&& 1"
17831   [(const_int 0)]
17832 {
17833   ix86_optimize_mode_switching[I387_CEIL] = 1;
17834
17835   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17836   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17837
17838   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17839                                        operands[2], operands[3]));
17840   DONE;
17841 }
17842   [(set_attr "type" "frndint")
17843    (set_attr "i387_cw" "ceil")
17844    (set_attr "mode" "XF")])
17845
17846 (define_insn "frndintxf2_ceil_i387"
17847   [(set (match_operand:XF 0 "register_operand" "=f")
17848         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17849          UNSPEC_FRNDINT_CEIL))
17850    (use (match_operand:HI 2 "memory_operand" "m"))
17851    (use (match_operand:HI 3 "memory_operand" "m"))]
17852   "TARGET_USE_FANCY_MATH_387
17853    && flag_unsafe_math_optimizations"
17854   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17855   [(set_attr "type" "frndint")
17856    (set_attr "i387_cw" "ceil")
17857    (set_attr "mode" "XF")])
17858
17859 (define_expand "ceilxf2"
17860   [(use (match_operand:XF 0 "register_operand" ""))
17861    (use (match_operand:XF 1 "register_operand" ""))]
17862   "TARGET_USE_FANCY_MATH_387
17863    && flag_unsafe_math_optimizations && !optimize_size"
17864 {
17865   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17866   DONE;
17867 })
17868
17869 (define_expand "ceildf2"
17870   [(use (match_operand:DF 0 "register_operand" ""))
17871    (use (match_operand:DF 1 "register_operand" ""))]
17872   "((TARGET_USE_FANCY_MATH_387
17873      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17874      && flag_unsafe_math_optimizations)
17875     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17876         && !flag_trapping_math))
17877    && !optimize_size"
17878 {
17879   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17880       && !flag_trapping_math)
17881     {
17882       if (TARGET_64BIT)
17883         ix86_expand_floorceil (operand0, operand1, false);
17884       else
17885         ix86_expand_floorceildf_32 (operand0, operand1, false);
17886     }
17887   else
17888     {
17889       rtx op0 = gen_reg_rtx (XFmode);
17890       rtx op1 = gen_reg_rtx (XFmode);
17891
17892       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17893       emit_insn (gen_frndintxf2_ceil (op0, op1));
17894
17895       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17896     }
17897   DONE;
17898 })
17899
17900 (define_expand "ceilsf2"
17901   [(use (match_operand:SF 0 "register_operand" ""))
17902    (use (match_operand:SF 1 "register_operand" ""))]
17903   "((TARGET_USE_FANCY_MATH_387
17904      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17905      && flag_unsafe_math_optimizations)
17906     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17907         && !flag_trapping_math))
17908    && !optimize_size"
17909 {
17910   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17911       && !flag_trapping_math)
17912     ix86_expand_floorceil (operand0, operand1, false);
17913   else
17914     {
17915       rtx op0 = gen_reg_rtx (XFmode);
17916       rtx op1 = gen_reg_rtx (XFmode);
17917
17918       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17919       emit_insn (gen_frndintxf2_ceil (op0, op1));
17920
17921       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17922     }
17923   DONE;
17924 })
17925
17926 (define_insn_and_split "*fist<mode>2_ceil_1"
17927   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17928         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17929          UNSPEC_FIST_CEIL))
17930    (clobber (reg:CC FLAGS_REG))]
17931   "TARGET_USE_FANCY_MATH_387
17932    && flag_unsafe_math_optimizations
17933    && !(reload_completed || reload_in_progress)"
17934   "#"
17935   "&& 1"
17936   [(const_int 0)]
17937 {
17938   ix86_optimize_mode_switching[I387_CEIL] = 1;
17939
17940   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17941   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17942   if (memory_operand (operands[0], VOIDmode))
17943     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17944                                      operands[2], operands[3]));
17945   else
17946     {
17947       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17948       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17949                                                  operands[2], operands[3],
17950                                                  operands[4]));
17951     }
17952   DONE;
17953 }
17954   [(set_attr "type" "fistp")
17955    (set_attr "i387_cw" "ceil")
17956    (set_attr "mode" "<MODE>")])
17957
17958 (define_insn "fistdi2_ceil"
17959   [(set (match_operand:DI 0 "memory_operand" "=m")
17960         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17961          UNSPEC_FIST_CEIL))
17962    (use (match_operand:HI 2 "memory_operand" "m"))
17963    (use (match_operand:HI 3 "memory_operand" "m"))
17964    (clobber (match_scratch:XF 4 "=&1f"))]
17965   "TARGET_USE_FANCY_MATH_387
17966    && flag_unsafe_math_optimizations"
17967   "* return output_fix_trunc (insn, operands, 0);"
17968   [(set_attr "type" "fistp")
17969    (set_attr "i387_cw" "ceil")
17970    (set_attr "mode" "DI")])
17971
17972 (define_insn "fistdi2_ceil_with_temp"
17973   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17974         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17975          UNSPEC_FIST_CEIL))
17976    (use (match_operand:HI 2 "memory_operand" "m,m"))
17977    (use (match_operand:HI 3 "memory_operand" "m,m"))
17978    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17979    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17980   "TARGET_USE_FANCY_MATH_387
17981    && flag_unsafe_math_optimizations"
17982   "#"
17983   [(set_attr "type" "fistp")
17984    (set_attr "i387_cw" "ceil")
17985    (set_attr "mode" "DI")])
17986
17987 (define_split
17988   [(set (match_operand:DI 0 "register_operand" "")
17989         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17990          UNSPEC_FIST_CEIL))
17991    (use (match_operand:HI 2 "memory_operand" ""))
17992    (use (match_operand:HI 3 "memory_operand" ""))
17993    (clobber (match_operand:DI 4 "memory_operand" ""))
17994    (clobber (match_scratch 5 ""))]
17995   "reload_completed"
17996   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17997               (use (match_dup 2))
17998               (use (match_dup 3))
17999               (clobber (match_dup 5))])
18000    (set (match_dup 0) (match_dup 4))]
18001   "")
18002
18003 (define_split
18004   [(set (match_operand:DI 0 "memory_operand" "")
18005         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18006          UNSPEC_FIST_CEIL))
18007    (use (match_operand:HI 2 "memory_operand" ""))
18008    (use (match_operand:HI 3 "memory_operand" ""))
18009    (clobber (match_operand:DI 4 "memory_operand" ""))
18010    (clobber (match_scratch 5 ""))]
18011   "reload_completed"
18012   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18013               (use (match_dup 2))
18014               (use (match_dup 3))
18015               (clobber (match_dup 5))])]
18016   "")
18017
18018 (define_insn "fist<mode>2_ceil"
18019   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18020         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18021          UNSPEC_FIST_CEIL))
18022    (use (match_operand:HI 2 "memory_operand" "m"))
18023    (use (match_operand:HI 3 "memory_operand" "m"))]
18024   "TARGET_USE_FANCY_MATH_387
18025    && flag_unsafe_math_optimizations"
18026   "* return output_fix_trunc (insn, operands, 0);"
18027   [(set_attr "type" "fistp")
18028    (set_attr "i387_cw" "ceil")
18029    (set_attr "mode" "<MODE>")])
18030
18031 (define_insn "fist<mode>2_ceil_with_temp"
18032   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18033         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18034          UNSPEC_FIST_CEIL))
18035    (use (match_operand:HI 2 "memory_operand" "m,m"))
18036    (use (match_operand:HI 3 "memory_operand" "m,m"))
18037    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18038   "TARGET_USE_FANCY_MATH_387
18039    && flag_unsafe_math_optimizations"
18040   "#"
18041   [(set_attr "type" "fistp")
18042    (set_attr "i387_cw" "ceil")
18043    (set_attr "mode" "<MODE>")])
18044
18045 (define_split
18046   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18047         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18048          UNSPEC_FIST_CEIL))
18049    (use (match_operand:HI 2 "memory_operand" ""))
18050    (use (match_operand:HI 3 "memory_operand" ""))
18051    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18052   "reload_completed"
18053   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18054                                   UNSPEC_FIST_CEIL))
18055               (use (match_dup 2))
18056               (use (match_dup 3))])
18057    (set (match_dup 0) (match_dup 4))]
18058   "")
18059
18060 (define_split
18061   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18062         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18063          UNSPEC_FIST_CEIL))
18064    (use (match_operand:HI 2 "memory_operand" ""))
18065    (use (match_operand:HI 3 "memory_operand" ""))
18066    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18067   "reload_completed"
18068   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18069                                   UNSPEC_FIST_CEIL))
18070               (use (match_dup 2))
18071               (use (match_dup 3))])]
18072   "")
18073
18074 (define_expand "lceilxf<mode>2"
18075   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18076                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18077                     UNSPEC_FIST_CEIL))
18078               (clobber (reg:CC FLAGS_REG))])]
18079   "TARGET_USE_FANCY_MATH_387
18080    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18081    && flag_unsafe_math_optimizations"
18082   "")
18083
18084 (define_expand "lceil<mode>di2"
18085   [(match_operand:DI 0 "nonimmediate_operand" "")
18086    (match_operand:SSEMODEF 1 "register_operand" "")]
18087   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18088    && !flag_trapping_math"
18089 {
18090   ix86_expand_lfloorceil (operand0, operand1, false);
18091   DONE;
18092 })
18093
18094 (define_expand "lceil<mode>si2"
18095   [(match_operand:SI 0 "nonimmediate_operand" "")
18096    (match_operand:SSEMODEF 1 "register_operand" "")]
18097   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18098    && !flag_trapping_math"
18099 {
18100   ix86_expand_lfloorceil (operand0, operand1, false);
18101   DONE;
18102 })
18103
18104 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18105 (define_insn_and_split "frndintxf2_trunc"
18106   [(set (match_operand:XF 0 "register_operand" "=f")
18107         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18108          UNSPEC_FRNDINT_TRUNC))
18109    (clobber (reg:CC FLAGS_REG))]
18110   "TARGET_USE_FANCY_MATH_387
18111    && flag_unsafe_math_optimizations
18112    && !(reload_completed || reload_in_progress)"
18113   "#"
18114   "&& 1"
18115   [(const_int 0)]
18116 {
18117   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18118
18119   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18120   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18121
18122   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18123                                         operands[2], operands[3]));
18124   DONE;
18125 }
18126   [(set_attr "type" "frndint")
18127    (set_attr "i387_cw" "trunc")
18128    (set_attr "mode" "XF")])
18129
18130 (define_insn "frndintxf2_trunc_i387"
18131   [(set (match_operand:XF 0 "register_operand" "=f")
18132         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18133          UNSPEC_FRNDINT_TRUNC))
18134    (use (match_operand:HI 2 "memory_operand" "m"))
18135    (use (match_operand:HI 3 "memory_operand" "m"))]
18136   "TARGET_USE_FANCY_MATH_387
18137    && flag_unsafe_math_optimizations"
18138   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18139   [(set_attr "type" "frndint")
18140    (set_attr "i387_cw" "trunc")
18141    (set_attr "mode" "XF")])
18142
18143 (define_expand "btruncxf2"
18144   [(use (match_operand:XF 0 "register_operand" ""))
18145    (use (match_operand:XF 1 "register_operand" ""))]
18146   "TARGET_USE_FANCY_MATH_387
18147    && flag_unsafe_math_optimizations && !optimize_size"
18148 {
18149   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18150   DONE;
18151 })
18152
18153 (define_expand "btruncdf2"
18154   [(use (match_operand:DF 0 "register_operand" ""))
18155    (use (match_operand:DF 1 "register_operand" ""))]
18156   "((TARGET_USE_FANCY_MATH_387
18157      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18158      && flag_unsafe_math_optimizations)
18159     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18160         && !flag_trapping_math))
18161    && !optimize_size"
18162 {
18163   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18164       && !flag_trapping_math)
18165     {
18166       if (TARGET_64BIT)
18167         ix86_expand_trunc (operand0, operand1);
18168       else
18169         ix86_expand_truncdf_32 (operand0, operand1);
18170     }
18171   else
18172     {
18173       rtx op0 = gen_reg_rtx (XFmode);
18174       rtx op1 = gen_reg_rtx (XFmode);
18175
18176       emit_insn (gen_extenddfxf2 (op1, operands[1]));
18177       emit_insn (gen_frndintxf2_trunc (op0, op1));
18178
18179       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18180     }
18181   DONE;
18182 })
18183
18184 (define_expand "btruncsf2"
18185   [(use (match_operand:SF 0 "register_operand" ""))
18186    (use (match_operand:SF 1 "register_operand" ""))]
18187   "((TARGET_USE_FANCY_MATH_387
18188      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18189      && flag_unsafe_math_optimizations)
18190     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18191         && !flag_trapping_math))
18192    && !optimize_size"
18193 {
18194   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18195       && !flag_trapping_math)
18196     ix86_expand_trunc (operand0, operand1);
18197   else
18198     {
18199       rtx op0 = gen_reg_rtx (XFmode);
18200       rtx op1 = gen_reg_rtx (XFmode);
18201
18202       emit_insn (gen_extendsfxf2 (op1, operands[1]));
18203       emit_insn (gen_frndintxf2_trunc (op0, op1));
18204
18205       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18206     }
18207   DONE;
18208 })
18209
18210 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18211 (define_insn_and_split "frndintxf2_mask_pm"
18212   [(set (match_operand:XF 0 "register_operand" "=f")
18213         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18214          UNSPEC_FRNDINT_MASK_PM))
18215    (clobber (reg:CC FLAGS_REG))]
18216   "TARGET_USE_FANCY_MATH_387
18217    && flag_unsafe_math_optimizations
18218    && !(reload_completed || reload_in_progress)"
18219   "#"
18220   "&& 1"
18221   [(const_int 0)]
18222 {
18223   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18224
18225   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18226   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18227
18228   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18229                                           operands[2], operands[3]));
18230   DONE;
18231 }
18232   [(set_attr "type" "frndint")
18233    (set_attr "i387_cw" "mask_pm")
18234    (set_attr "mode" "XF")])
18235
18236 (define_insn "frndintxf2_mask_pm_i387"
18237   [(set (match_operand:XF 0 "register_operand" "=f")
18238         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18239          UNSPEC_FRNDINT_MASK_PM))
18240    (use (match_operand:HI 2 "memory_operand" "m"))
18241    (use (match_operand:HI 3 "memory_operand" "m"))]
18242   "TARGET_USE_FANCY_MATH_387
18243    && flag_unsafe_math_optimizations"
18244   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18245   [(set_attr "type" "frndint")
18246    (set_attr "i387_cw" "mask_pm")
18247    (set_attr "mode" "XF")])
18248
18249 (define_expand "nearbyintxf2"
18250   [(use (match_operand:XF 0 "register_operand" ""))
18251    (use (match_operand:XF 1 "register_operand" ""))]
18252   "TARGET_USE_FANCY_MATH_387
18253    && flag_unsafe_math_optimizations"
18254 {
18255   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18256
18257   DONE;
18258 })
18259
18260 (define_expand "nearbyintdf2"
18261   [(use (match_operand:DF 0 "register_operand" ""))
18262    (use (match_operand:DF 1 "register_operand" ""))]
18263   "TARGET_USE_FANCY_MATH_387
18264    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18265    && flag_unsafe_math_optimizations"
18266 {
18267   rtx op0 = gen_reg_rtx (XFmode);
18268   rtx op1 = gen_reg_rtx (XFmode);
18269
18270   emit_insn (gen_extenddfxf2 (op1, operands[1]));
18271   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18272
18273   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18274   DONE;
18275 })
18276
18277 (define_expand "nearbyintsf2"
18278   [(use (match_operand:SF 0 "register_operand" ""))
18279    (use (match_operand:SF 1 "register_operand" ""))]
18280   "TARGET_USE_FANCY_MATH_387
18281    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18282    && flag_unsafe_math_optimizations"
18283 {
18284   rtx op0 = gen_reg_rtx (XFmode);
18285   rtx op1 = gen_reg_rtx (XFmode);
18286
18287   emit_insn (gen_extendsfxf2 (op1, operands[1]));
18288   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18289
18290   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18291   DONE;
18292 })
18293
18294 (define_insn "fxam<mode>2_i387"
18295   [(set (match_operand:HI 0 "register_operand" "=a")
18296         (unspec:HI
18297           [(match_operand:X87MODEF 1 "register_operand" "f")]
18298           UNSPEC_FXAM))]
18299   "TARGET_USE_FANCY_MATH_387"
18300   "fxam\n\tfnstsw\t%0"
18301   [(set_attr "type" "multi")
18302    (set_attr "unit" "i387")
18303    (set_attr "mode" "<MODE>")])
18304
18305 (define_expand "isinf<mode>2"
18306   [(use (match_operand:SI 0 "register_operand" ""))
18307    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18308   "TARGET_USE_FANCY_MATH_387
18309   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18310       || TARGET_MIX_SSE_I387)"
18311 {
18312   rtx mask = GEN_INT (0x45);
18313   rtx val = GEN_INT (0x05);
18314
18315   rtx cond;
18316
18317   rtx scratch = gen_reg_rtx (HImode);
18318   rtx res = gen_reg_rtx (QImode);
18319
18320   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18321   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18322   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18323   cond = gen_rtx_fmt_ee (EQ, QImode,
18324                          gen_rtx_REG (CCmode, FLAGS_REG),
18325                          const0_rtx);
18326   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18327   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18328   DONE;
18329 })
18330
18331 \f
18332 ;; Block operation instructions
18333
18334 (define_expand "movmemsi"
18335   [(use (match_operand:BLK 0 "memory_operand" ""))
18336    (use (match_operand:BLK 1 "memory_operand" ""))
18337    (use (match_operand:SI 2 "nonmemory_operand" ""))
18338    (use (match_operand:SI 3 "const_int_operand" ""))
18339    (use (match_operand:SI 4 "const_int_operand" ""))
18340    (use (match_operand:SI 5 "const_int_operand" ""))]
18341   ""
18342 {
18343  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18344                          operands[4], operands[5]))
18345    DONE;
18346  else
18347    FAIL;
18348 })
18349
18350 (define_expand "movmemdi"
18351   [(use (match_operand:BLK 0 "memory_operand" ""))
18352    (use (match_operand:BLK 1 "memory_operand" ""))
18353    (use (match_operand:DI 2 "nonmemory_operand" ""))
18354    (use (match_operand:DI 3 "const_int_operand" ""))
18355    (use (match_operand:SI 4 "const_int_operand" ""))
18356    (use (match_operand:SI 5 "const_int_operand" ""))]
18357   "TARGET_64BIT"
18358 {
18359  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18360                          operands[4], operands[5]))
18361    DONE;
18362  else
18363    FAIL;
18364 })
18365
18366 ;; Most CPUs don't like single string operations
18367 ;; Handle this case here to simplify previous expander.
18368
18369 (define_expand "strmov"
18370   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18371    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18372    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18373               (clobber (reg:CC FLAGS_REG))])
18374    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18375               (clobber (reg:CC FLAGS_REG))])]
18376   ""
18377 {
18378   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18379
18380   /* If .md ever supports :P for Pmode, these can be directly
18381      in the pattern above.  */
18382   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18383   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18384
18385   if (TARGET_SINGLE_STRINGOP || optimize_size)
18386     {
18387       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18388                                       operands[2], operands[3],
18389                                       operands[5], operands[6]));
18390       DONE;
18391     }
18392
18393   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18394 })
18395
18396 (define_expand "strmov_singleop"
18397   [(parallel [(set (match_operand 1 "memory_operand" "")
18398                    (match_operand 3 "memory_operand" ""))
18399               (set (match_operand 0 "register_operand" "")
18400                    (match_operand 4 "" ""))
18401               (set (match_operand 2 "register_operand" "")
18402                    (match_operand 5 "" ""))])]
18403   "TARGET_SINGLE_STRINGOP || optimize_size"
18404   "")
18405
18406 (define_insn "*strmovdi_rex_1"
18407   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18408         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18409    (set (match_operand:DI 0 "register_operand" "=D")
18410         (plus:DI (match_dup 2)
18411                  (const_int 8)))
18412    (set (match_operand:DI 1 "register_operand" "=S")
18413         (plus:DI (match_dup 3)
18414                  (const_int 8)))]
18415   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18416   "movsq"
18417   [(set_attr "type" "str")
18418    (set_attr "mode" "DI")
18419    (set_attr "memory" "both")])
18420
18421 (define_insn "*strmovsi_1"
18422   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18423         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18424    (set (match_operand:SI 0 "register_operand" "=D")
18425         (plus:SI (match_dup 2)
18426                  (const_int 4)))
18427    (set (match_operand:SI 1 "register_operand" "=S")
18428         (plus:SI (match_dup 3)
18429                  (const_int 4)))]
18430   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18431   "{movsl|movsd}"
18432   [(set_attr "type" "str")
18433    (set_attr "mode" "SI")
18434    (set_attr "memory" "both")])
18435
18436 (define_insn "*strmovsi_rex_1"
18437   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18438         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18439    (set (match_operand:DI 0 "register_operand" "=D")
18440         (plus:DI (match_dup 2)
18441                  (const_int 4)))
18442    (set (match_operand:DI 1 "register_operand" "=S")
18443         (plus:DI (match_dup 3)
18444                  (const_int 4)))]
18445   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18446   "{movsl|movsd}"
18447   [(set_attr "type" "str")
18448    (set_attr "mode" "SI")
18449    (set_attr "memory" "both")])
18450
18451 (define_insn "*strmovhi_1"
18452   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18453         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18454    (set (match_operand:SI 0 "register_operand" "=D")
18455         (plus:SI (match_dup 2)
18456                  (const_int 2)))
18457    (set (match_operand:SI 1 "register_operand" "=S")
18458         (plus:SI (match_dup 3)
18459                  (const_int 2)))]
18460   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18461   "movsw"
18462   [(set_attr "type" "str")
18463    (set_attr "memory" "both")
18464    (set_attr "mode" "HI")])
18465
18466 (define_insn "*strmovhi_rex_1"
18467   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18468         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18469    (set (match_operand:DI 0 "register_operand" "=D")
18470         (plus:DI (match_dup 2)
18471                  (const_int 2)))
18472    (set (match_operand:DI 1 "register_operand" "=S")
18473         (plus:DI (match_dup 3)
18474                  (const_int 2)))]
18475   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18476   "movsw"
18477   [(set_attr "type" "str")
18478    (set_attr "memory" "both")
18479    (set_attr "mode" "HI")])
18480
18481 (define_insn "*strmovqi_1"
18482   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18483         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18484    (set (match_operand:SI 0 "register_operand" "=D")
18485         (plus:SI (match_dup 2)
18486                  (const_int 1)))
18487    (set (match_operand:SI 1 "register_operand" "=S")
18488         (plus:SI (match_dup 3)
18489                  (const_int 1)))]
18490   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18491   "movsb"
18492   [(set_attr "type" "str")
18493    (set_attr "memory" "both")
18494    (set_attr "mode" "QI")])
18495
18496 (define_insn "*strmovqi_rex_1"
18497   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18498         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18499    (set (match_operand:DI 0 "register_operand" "=D")
18500         (plus:DI (match_dup 2)
18501                  (const_int 1)))
18502    (set (match_operand:DI 1 "register_operand" "=S")
18503         (plus:DI (match_dup 3)
18504                  (const_int 1)))]
18505   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18506   "movsb"
18507   [(set_attr "type" "str")
18508    (set_attr "memory" "both")
18509    (set_attr "mode" "QI")])
18510
18511 (define_expand "rep_mov"
18512   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18513               (set (match_operand 0 "register_operand" "")
18514                    (match_operand 5 "" ""))
18515               (set (match_operand 2 "register_operand" "")
18516                    (match_operand 6 "" ""))
18517               (set (match_operand 1 "memory_operand" "")
18518                    (match_operand 3 "memory_operand" ""))
18519               (use (match_dup 4))])]
18520   ""
18521   "")
18522
18523 (define_insn "*rep_movdi_rex64"
18524   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18525    (set (match_operand:DI 0 "register_operand" "=D")
18526         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18527                             (const_int 3))
18528                  (match_operand:DI 3 "register_operand" "0")))
18529    (set (match_operand:DI 1 "register_operand" "=S")
18530         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18531                  (match_operand:DI 4 "register_operand" "1")))
18532    (set (mem:BLK (match_dup 3))
18533         (mem:BLK (match_dup 4)))
18534    (use (match_dup 5))]
18535   "TARGET_64BIT"
18536   "{rep\;movsq|rep movsq}"
18537   [(set_attr "type" "str")
18538    (set_attr "prefix_rep" "1")
18539    (set_attr "memory" "both")
18540    (set_attr "mode" "DI")])
18541
18542 (define_insn "*rep_movsi"
18543   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18544    (set (match_operand:SI 0 "register_operand" "=D")
18545         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18546                             (const_int 2))
18547                  (match_operand:SI 3 "register_operand" "0")))
18548    (set (match_operand:SI 1 "register_operand" "=S")
18549         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18550                  (match_operand:SI 4 "register_operand" "1")))
18551    (set (mem:BLK (match_dup 3))
18552         (mem:BLK (match_dup 4)))
18553    (use (match_dup 5))]
18554   "!TARGET_64BIT"
18555   "{rep\;movsl|rep movsd}"
18556   [(set_attr "type" "str")
18557    (set_attr "prefix_rep" "1")
18558    (set_attr "memory" "both")
18559    (set_attr "mode" "SI")])
18560
18561 (define_insn "*rep_movsi_rex64"
18562   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18563    (set (match_operand:DI 0 "register_operand" "=D")
18564         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18565                             (const_int 2))
18566                  (match_operand:DI 3 "register_operand" "0")))
18567    (set (match_operand:DI 1 "register_operand" "=S")
18568         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18569                  (match_operand:DI 4 "register_operand" "1")))
18570    (set (mem:BLK (match_dup 3))
18571         (mem:BLK (match_dup 4)))
18572    (use (match_dup 5))]
18573   "TARGET_64BIT"
18574   "{rep\;movsl|rep movsd}"
18575   [(set_attr "type" "str")
18576    (set_attr "prefix_rep" "1")
18577    (set_attr "memory" "both")
18578    (set_attr "mode" "SI")])
18579
18580 (define_insn "*rep_movqi"
18581   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18582    (set (match_operand:SI 0 "register_operand" "=D")
18583         (plus:SI (match_operand:SI 3 "register_operand" "0")
18584                  (match_operand:SI 5 "register_operand" "2")))
18585    (set (match_operand:SI 1 "register_operand" "=S")
18586         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18587    (set (mem:BLK (match_dup 3))
18588         (mem:BLK (match_dup 4)))
18589    (use (match_dup 5))]
18590   "!TARGET_64BIT"
18591   "{rep\;movsb|rep movsb}"
18592   [(set_attr "type" "str")
18593    (set_attr "prefix_rep" "1")
18594    (set_attr "memory" "both")
18595    (set_attr "mode" "SI")])
18596
18597 (define_insn "*rep_movqi_rex64"
18598   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18599    (set (match_operand:DI 0 "register_operand" "=D")
18600         (plus:DI (match_operand:DI 3 "register_operand" "0")
18601                  (match_operand:DI 5 "register_operand" "2")))
18602    (set (match_operand:DI 1 "register_operand" "=S")
18603         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18604    (set (mem:BLK (match_dup 3))
18605         (mem:BLK (match_dup 4)))
18606    (use (match_dup 5))]
18607   "TARGET_64BIT"
18608   "{rep\;movsb|rep movsb}"
18609   [(set_attr "type" "str")
18610    (set_attr "prefix_rep" "1")
18611    (set_attr "memory" "both")
18612    (set_attr "mode" "SI")])
18613
18614 (define_expand "setmemsi"
18615    [(use (match_operand:BLK 0 "memory_operand" ""))
18616     (use (match_operand:SI 1 "nonmemory_operand" ""))
18617     (use (match_operand 2 "const_int_operand" ""))
18618     (use (match_operand 3 "const_int_operand" ""))
18619     (use (match_operand:SI 4 "const_int_operand" ""))
18620     (use (match_operand:SI 5 "const_int_operand" ""))]
18621   ""
18622 {
18623  if (ix86_expand_setmem (operands[0], operands[1],
18624                          operands[2], operands[3],
18625                          operands[4], operands[5]))
18626    DONE;
18627  else
18628    FAIL;
18629 })
18630
18631 (define_expand "setmemdi"
18632    [(use (match_operand:BLK 0 "memory_operand" ""))
18633     (use (match_operand:DI 1 "nonmemory_operand" ""))
18634     (use (match_operand 2 "const_int_operand" ""))
18635     (use (match_operand 3 "const_int_operand" ""))
18636     (use (match_operand 4 "const_int_operand" ""))
18637     (use (match_operand 5 "const_int_operand" ""))]
18638   "TARGET_64BIT"
18639 {
18640  if (ix86_expand_setmem (operands[0], operands[1],
18641                          operands[2], operands[3],
18642                          operands[4], operands[5]))
18643    DONE;
18644  else
18645    FAIL;
18646 })
18647
18648 ;; Most CPUs don't like single string operations
18649 ;; Handle this case here to simplify previous expander.
18650
18651 (define_expand "strset"
18652   [(set (match_operand 1 "memory_operand" "")
18653         (match_operand 2 "register_operand" ""))
18654    (parallel [(set (match_operand 0 "register_operand" "")
18655                    (match_dup 3))
18656               (clobber (reg:CC FLAGS_REG))])]
18657   ""
18658 {
18659   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18660     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18661
18662   /* If .md ever supports :P for Pmode, this can be directly
18663      in the pattern above.  */
18664   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18665                               GEN_INT (GET_MODE_SIZE (GET_MODE
18666                                                       (operands[2]))));
18667   if (TARGET_SINGLE_STRINGOP || optimize_size)
18668     {
18669       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18670                                       operands[3]));
18671       DONE;
18672     }
18673 })
18674
18675 (define_expand "strset_singleop"
18676   [(parallel [(set (match_operand 1 "memory_operand" "")
18677                    (match_operand 2 "register_operand" ""))
18678               (set (match_operand 0 "register_operand" "")
18679                    (match_operand 3 "" ""))])]
18680   "TARGET_SINGLE_STRINGOP || optimize_size"
18681   "")
18682
18683 (define_insn "*strsetdi_rex_1"
18684   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18685         (match_operand:DI 2 "register_operand" "a"))
18686    (set (match_operand:DI 0 "register_operand" "=D")
18687         (plus:DI (match_dup 1)
18688                  (const_int 8)))]
18689   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18690   "stosq"
18691   [(set_attr "type" "str")
18692    (set_attr "memory" "store")
18693    (set_attr "mode" "DI")])
18694
18695 (define_insn "*strsetsi_1"
18696   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18697         (match_operand:SI 2 "register_operand" "a"))
18698    (set (match_operand:SI 0 "register_operand" "=D")
18699         (plus:SI (match_dup 1)
18700                  (const_int 4)))]
18701   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18702   "{stosl|stosd}"
18703   [(set_attr "type" "str")
18704    (set_attr "memory" "store")
18705    (set_attr "mode" "SI")])
18706
18707 (define_insn "*strsetsi_rex_1"
18708   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18709         (match_operand:SI 2 "register_operand" "a"))
18710    (set (match_operand:DI 0 "register_operand" "=D")
18711         (plus:DI (match_dup 1)
18712                  (const_int 4)))]
18713   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18714   "{stosl|stosd}"
18715   [(set_attr "type" "str")
18716    (set_attr "memory" "store")
18717    (set_attr "mode" "SI")])
18718
18719 (define_insn "*strsethi_1"
18720   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18721         (match_operand:HI 2 "register_operand" "a"))
18722    (set (match_operand:SI 0 "register_operand" "=D")
18723         (plus:SI (match_dup 1)
18724                  (const_int 2)))]
18725   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18726   "stosw"
18727   [(set_attr "type" "str")
18728    (set_attr "memory" "store")
18729    (set_attr "mode" "HI")])
18730
18731 (define_insn "*strsethi_rex_1"
18732   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18733         (match_operand:HI 2 "register_operand" "a"))
18734    (set (match_operand:DI 0 "register_operand" "=D")
18735         (plus:DI (match_dup 1)
18736                  (const_int 2)))]
18737   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18738   "stosw"
18739   [(set_attr "type" "str")
18740    (set_attr "memory" "store")
18741    (set_attr "mode" "HI")])
18742
18743 (define_insn "*strsetqi_1"
18744   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18745         (match_operand:QI 2 "register_operand" "a"))
18746    (set (match_operand:SI 0 "register_operand" "=D")
18747         (plus:SI (match_dup 1)
18748                  (const_int 1)))]
18749   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18750   "stosb"
18751   [(set_attr "type" "str")
18752    (set_attr "memory" "store")
18753    (set_attr "mode" "QI")])
18754
18755 (define_insn "*strsetqi_rex_1"
18756   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18757         (match_operand:QI 2 "register_operand" "a"))
18758    (set (match_operand:DI 0 "register_operand" "=D")
18759         (plus:DI (match_dup 1)
18760                  (const_int 1)))]
18761   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18762   "stosb"
18763   [(set_attr "type" "str")
18764    (set_attr "memory" "store")
18765    (set_attr "mode" "QI")])
18766
18767 (define_expand "rep_stos"
18768   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18769               (set (match_operand 0 "register_operand" "")
18770                    (match_operand 4 "" ""))
18771               (set (match_operand 2 "memory_operand" "") (const_int 0))
18772               (use (match_operand 3 "register_operand" ""))
18773               (use (match_dup 1))])]
18774   ""
18775   "")
18776
18777 (define_insn "*rep_stosdi_rex64"
18778   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18779    (set (match_operand:DI 0 "register_operand" "=D")
18780         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18781                             (const_int 3))
18782                  (match_operand:DI 3 "register_operand" "0")))
18783    (set (mem:BLK (match_dup 3))
18784         (const_int 0))
18785    (use (match_operand:DI 2 "register_operand" "a"))
18786    (use (match_dup 4))]
18787   "TARGET_64BIT"
18788   "{rep\;stosq|rep stosq}"
18789   [(set_attr "type" "str")
18790    (set_attr "prefix_rep" "1")
18791    (set_attr "memory" "store")
18792    (set_attr "mode" "DI")])
18793
18794 (define_insn "*rep_stossi"
18795   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18796    (set (match_operand:SI 0 "register_operand" "=D")
18797         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18798                             (const_int 2))
18799                  (match_operand:SI 3 "register_operand" "0")))
18800    (set (mem:BLK (match_dup 3))
18801         (const_int 0))
18802    (use (match_operand:SI 2 "register_operand" "a"))
18803    (use (match_dup 4))]
18804   "!TARGET_64BIT"
18805   "{rep\;stosl|rep stosd}"
18806   [(set_attr "type" "str")
18807    (set_attr "prefix_rep" "1")
18808    (set_attr "memory" "store")
18809    (set_attr "mode" "SI")])
18810
18811 (define_insn "*rep_stossi_rex64"
18812   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18813    (set (match_operand:DI 0 "register_operand" "=D")
18814         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18815                             (const_int 2))
18816                  (match_operand:DI 3 "register_operand" "0")))
18817    (set (mem:BLK (match_dup 3))
18818         (const_int 0))
18819    (use (match_operand:SI 2 "register_operand" "a"))
18820    (use (match_dup 4))]
18821   "TARGET_64BIT"
18822   "{rep\;stosl|rep stosd}"
18823   [(set_attr "type" "str")
18824    (set_attr "prefix_rep" "1")
18825    (set_attr "memory" "store")
18826    (set_attr "mode" "SI")])
18827
18828 (define_insn "*rep_stosqi"
18829   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18830    (set (match_operand:SI 0 "register_operand" "=D")
18831         (plus:SI (match_operand:SI 3 "register_operand" "0")
18832                  (match_operand:SI 4 "register_operand" "1")))
18833    (set (mem:BLK (match_dup 3))
18834         (const_int 0))
18835    (use (match_operand:QI 2 "register_operand" "a"))
18836    (use (match_dup 4))]
18837   "!TARGET_64BIT"
18838   "{rep\;stosb|rep stosb}"
18839   [(set_attr "type" "str")
18840    (set_attr "prefix_rep" "1")
18841    (set_attr "memory" "store")
18842    (set_attr "mode" "QI")])
18843
18844 (define_insn "*rep_stosqi_rex64"
18845   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18846    (set (match_operand:DI 0 "register_operand" "=D")
18847         (plus:DI (match_operand:DI 3 "register_operand" "0")
18848                  (match_operand:DI 4 "register_operand" "1")))
18849    (set (mem:BLK (match_dup 3))
18850         (const_int 0))
18851    (use (match_operand:QI 2 "register_operand" "a"))
18852    (use (match_dup 4))]
18853   "TARGET_64BIT"
18854   "{rep\;stosb|rep stosb}"
18855   [(set_attr "type" "str")
18856    (set_attr "prefix_rep" "1")
18857    (set_attr "memory" "store")
18858    (set_attr "mode" "QI")])
18859
18860 (define_expand "cmpstrnsi"
18861   [(set (match_operand:SI 0 "register_operand" "")
18862         (compare:SI (match_operand:BLK 1 "general_operand" "")
18863                     (match_operand:BLK 2 "general_operand" "")))
18864    (use (match_operand 3 "general_operand" ""))
18865    (use (match_operand 4 "immediate_operand" ""))]
18866   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18867 {
18868   rtx addr1, addr2, out, outlow, count, countreg, align;
18869
18870   /* Can't use this if the user has appropriated esi or edi.  */
18871   if (global_regs[4] || global_regs[5])
18872     FAIL;
18873
18874   out = operands[0];
18875   if (!REG_P (out))
18876     out = gen_reg_rtx (SImode);
18877
18878   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18879   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18880   if (addr1 != XEXP (operands[1], 0))
18881     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18882   if (addr2 != XEXP (operands[2], 0))
18883     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18884
18885   count = operands[3];
18886   countreg = ix86_zero_extend_to_Pmode (count);
18887
18888   /* %%% Iff we are testing strict equality, we can use known alignment
18889      to good advantage.  This may be possible with combine, particularly
18890      once cc0 is dead.  */
18891   align = operands[4];
18892
18893   if (CONST_INT_P (count))
18894     {
18895       if (INTVAL (count) == 0)
18896         {
18897           emit_move_insn (operands[0], const0_rtx);
18898           DONE;
18899         }
18900       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18901                                      operands[1], operands[2]));
18902     }
18903   else
18904     {
18905       if (TARGET_64BIT)
18906         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18907       else
18908         emit_insn (gen_cmpsi_1 (countreg, countreg));
18909       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18910                                   operands[1], operands[2]));
18911     }
18912
18913   outlow = gen_lowpart (QImode, out);
18914   emit_insn (gen_cmpintqi (outlow));
18915   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18916
18917   if (operands[0] != out)
18918     emit_move_insn (operands[0], out);
18919
18920   DONE;
18921 })
18922
18923 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18924
18925 (define_expand "cmpintqi"
18926   [(set (match_dup 1)
18927         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18928    (set (match_dup 2)
18929         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18930    (parallel [(set (match_operand:QI 0 "register_operand" "")
18931                    (minus:QI (match_dup 1)
18932                              (match_dup 2)))
18933               (clobber (reg:CC FLAGS_REG))])]
18934   ""
18935   "operands[1] = gen_reg_rtx (QImode);
18936    operands[2] = gen_reg_rtx (QImode);")
18937
18938 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18939 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18940
18941 (define_expand "cmpstrnqi_nz_1"
18942   [(parallel [(set (reg:CC FLAGS_REG)
18943                    (compare:CC (match_operand 4 "memory_operand" "")
18944                                (match_operand 5 "memory_operand" "")))
18945               (use (match_operand 2 "register_operand" ""))
18946               (use (match_operand:SI 3 "immediate_operand" ""))
18947               (clobber (match_operand 0 "register_operand" ""))
18948               (clobber (match_operand 1 "register_operand" ""))
18949               (clobber (match_dup 2))])]
18950   ""
18951   "")
18952
18953 (define_insn "*cmpstrnqi_nz_1"
18954   [(set (reg:CC FLAGS_REG)
18955         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18956                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18957    (use (match_operand:SI 6 "register_operand" "2"))
18958    (use (match_operand:SI 3 "immediate_operand" "i"))
18959    (clobber (match_operand:SI 0 "register_operand" "=S"))
18960    (clobber (match_operand:SI 1 "register_operand" "=D"))
18961    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18962   "!TARGET_64BIT"
18963   "repz{\;| }cmpsb"
18964   [(set_attr "type" "str")
18965    (set_attr "mode" "QI")
18966    (set_attr "prefix_rep" "1")])
18967
18968 (define_insn "*cmpstrnqi_nz_rex_1"
18969   [(set (reg:CC FLAGS_REG)
18970         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18971                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18972    (use (match_operand:DI 6 "register_operand" "2"))
18973    (use (match_operand:SI 3 "immediate_operand" "i"))
18974    (clobber (match_operand:DI 0 "register_operand" "=S"))
18975    (clobber (match_operand:DI 1 "register_operand" "=D"))
18976    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18977   "TARGET_64BIT"
18978   "repz{\;| }cmpsb"
18979   [(set_attr "type" "str")
18980    (set_attr "mode" "QI")
18981    (set_attr "prefix_rep" "1")])
18982
18983 ;; The same, but the count is not known to not be zero.
18984
18985 (define_expand "cmpstrnqi_1"
18986   [(parallel [(set (reg:CC FLAGS_REG)
18987                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18988                                      (const_int 0))
18989                   (compare:CC (match_operand 4 "memory_operand" "")
18990                               (match_operand 5 "memory_operand" ""))
18991                   (const_int 0)))
18992               (use (match_operand:SI 3 "immediate_operand" ""))
18993               (use (reg:CC FLAGS_REG))
18994               (clobber (match_operand 0 "register_operand" ""))
18995               (clobber (match_operand 1 "register_operand" ""))
18996               (clobber (match_dup 2))])]
18997   ""
18998   "")
18999
19000 (define_insn "*cmpstrnqi_1"
19001   [(set (reg:CC FLAGS_REG)
19002         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19003                              (const_int 0))
19004           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19005                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19006           (const_int 0)))
19007    (use (match_operand:SI 3 "immediate_operand" "i"))
19008    (use (reg:CC FLAGS_REG))
19009    (clobber (match_operand:SI 0 "register_operand" "=S"))
19010    (clobber (match_operand:SI 1 "register_operand" "=D"))
19011    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19012   "!TARGET_64BIT"
19013   "repz{\;| }cmpsb"
19014   [(set_attr "type" "str")
19015    (set_attr "mode" "QI")
19016    (set_attr "prefix_rep" "1")])
19017
19018 (define_insn "*cmpstrnqi_rex_1"
19019   [(set (reg:CC FLAGS_REG)
19020         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19021                              (const_int 0))
19022           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19023                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19024           (const_int 0)))
19025    (use (match_operand:SI 3 "immediate_operand" "i"))
19026    (use (reg:CC FLAGS_REG))
19027    (clobber (match_operand:DI 0 "register_operand" "=S"))
19028    (clobber (match_operand:DI 1 "register_operand" "=D"))
19029    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19030   "TARGET_64BIT"
19031   "repz{\;| }cmpsb"
19032   [(set_attr "type" "str")
19033    (set_attr "mode" "QI")
19034    (set_attr "prefix_rep" "1")])
19035
19036 (define_expand "strlensi"
19037   [(set (match_operand:SI 0 "register_operand" "")
19038         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19039                     (match_operand:QI 2 "immediate_operand" "")
19040                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19041   ""
19042 {
19043  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19044    DONE;
19045  else
19046    FAIL;
19047 })
19048
19049 (define_expand "strlendi"
19050   [(set (match_operand:DI 0 "register_operand" "")
19051         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19052                     (match_operand:QI 2 "immediate_operand" "")
19053                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19054   ""
19055 {
19056  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19057    DONE;
19058  else
19059    FAIL;
19060 })
19061
19062 (define_expand "strlenqi_1"
19063   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19064               (clobber (match_operand 1 "register_operand" ""))
19065               (clobber (reg:CC FLAGS_REG))])]
19066   ""
19067   "")
19068
19069 (define_insn "*strlenqi_1"
19070   [(set (match_operand:SI 0 "register_operand" "=&c")
19071         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19072                     (match_operand:QI 2 "register_operand" "a")
19073                     (match_operand:SI 3 "immediate_operand" "i")
19074                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19075    (clobber (match_operand:SI 1 "register_operand" "=D"))
19076    (clobber (reg:CC FLAGS_REG))]
19077   "!TARGET_64BIT"
19078   "repnz{\;| }scasb"
19079   [(set_attr "type" "str")
19080    (set_attr "mode" "QI")
19081    (set_attr "prefix_rep" "1")])
19082
19083 (define_insn "*strlenqi_rex_1"
19084   [(set (match_operand:DI 0 "register_operand" "=&c")
19085         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19086                     (match_operand:QI 2 "register_operand" "a")
19087                     (match_operand:DI 3 "immediate_operand" "i")
19088                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19089    (clobber (match_operand:DI 1 "register_operand" "=D"))
19090    (clobber (reg:CC FLAGS_REG))]
19091   "TARGET_64BIT"
19092   "repnz{\;| }scasb"
19093   [(set_attr "type" "str")
19094    (set_attr "mode" "QI")
19095    (set_attr "prefix_rep" "1")])
19096
19097 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19098 ;; handled in combine, but it is not currently up to the task.
19099 ;; When used for their truth value, the cmpstrn* expanders generate
19100 ;; code like this:
19101 ;;
19102 ;;   repz cmpsb
19103 ;;   seta       %al
19104 ;;   setb       %dl
19105 ;;   cmpb       %al, %dl
19106 ;;   jcc        label
19107 ;;
19108 ;; The intermediate three instructions are unnecessary.
19109
19110 ;; This one handles cmpstrn*_nz_1...
19111 (define_peephole2
19112   [(parallel[
19113      (set (reg:CC FLAGS_REG)
19114           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19115                       (mem:BLK (match_operand 5 "register_operand" ""))))
19116      (use (match_operand 6 "register_operand" ""))
19117      (use (match_operand:SI 3 "immediate_operand" ""))
19118      (clobber (match_operand 0 "register_operand" ""))
19119      (clobber (match_operand 1 "register_operand" ""))
19120      (clobber (match_operand 2 "register_operand" ""))])
19121    (set (match_operand:QI 7 "register_operand" "")
19122         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19123    (set (match_operand:QI 8 "register_operand" "")
19124         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19125    (set (reg FLAGS_REG)
19126         (compare (match_dup 7) (match_dup 8)))
19127   ]
19128   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19129   [(parallel[
19130      (set (reg:CC FLAGS_REG)
19131           (compare:CC (mem:BLK (match_dup 4))
19132                       (mem:BLK (match_dup 5))))
19133      (use (match_dup 6))
19134      (use (match_dup 3))
19135      (clobber (match_dup 0))
19136      (clobber (match_dup 1))
19137      (clobber (match_dup 2))])]
19138   "")
19139
19140 ;; ...and this one handles cmpstrn*_1.
19141 (define_peephole2
19142   [(parallel[
19143      (set (reg:CC FLAGS_REG)
19144           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19145                                (const_int 0))
19146             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19147                         (mem:BLK (match_operand 5 "register_operand" "")))
19148             (const_int 0)))
19149      (use (match_operand:SI 3 "immediate_operand" ""))
19150      (use (reg:CC FLAGS_REG))
19151      (clobber (match_operand 0 "register_operand" ""))
19152      (clobber (match_operand 1 "register_operand" ""))
19153      (clobber (match_operand 2 "register_operand" ""))])
19154    (set (match_operand:QI 7 "register_operand" "")
19155         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19156    (set (match_operand:QI 8 "register_operand" "")
19157         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19158    (set (reg FLAGS_REG)
19159         (compare (match_dup 7) (match_dup 8)))
19160   ]
19161   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19162   [(parallel[
19163      (set (reg:CC FLAGS_REG)
19164           (if_then_else:CC (ne (match_dup 6)
19165                                (const_int 0))
19166             (compare:CC (mem:BLK (match_dup 4))
19167                         (mem:BLK (match_dup 5)))
19168             (const_int 0)))
19169      (use (match_dup 3))
19170      (use (reg:CC FLAGS_REG))
19171      (clobber (match_dup 0))
19172      (clobber (match_dup 1))
19173      (clobber (match_dup 2))])]
19174   "")
19175
19176
19177 \f
19178 ;; Conditional move instructions.
19179
19180 (define_expand "movdicc"
19181   [(set (match_operand:DI 0 "register_operand" "")
19182         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19183                          (match_operand:DI 2 "general_operand" "")
19184                          (match_operand:DI 3 "general_operand" "")))]
19185   "TARGET_64BIT"
19186   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19187
19188 (define_insn "x86_movdicc_0_m1_rex64"
19189   [(set (match_operand:DI 0 "register_operand" "=r")
19190         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19191           (const_int -1)
19192           (const_int 0)))
19193    (clobber (reg:CC FLAGS_REG))]
19194   "TARGET_64BIT"
19195   "sbb{q}\t%0, %0"
19196   ; Since we don't have the proper number of operands for an alu insn,
19197   ; fill in all the blanks.
19198   [(set_attr "type" "alu")
19199    (set_attr "pent_pair" "pu")
19200    (set_attr "memory" "none")
19201    (set_attr "imm_disp" "false")
19202    (set_attr "mode" "DI")
19203    (set_attr "length_immediate" "0")])
19204
19205 (define_insn "*movdicc_c_rex64"
19206   [(set (match_operand:DI 0 "register_operand" "=r,r")
19207         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19208                                 [(reg FLAGS_REG) (const_int 0)])
19209                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19210                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19211   "TARGET_64BIT && TARGET_CMOVE
19212    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19213   "@
19214    cmov%O2%C1\t{%2, %0|%0, %2}
19215    cmov%O2%c1\t{%3, %0|%0, %3}"
19216   [(set_attr "type" "icmov")
19217    (set_attr "mode" "DI")])
19218
19219 (define_expand "movsicc"
19220   [(set (match_operand:SI 0 "register_operand" "")
19221         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19222                          (match_operand:SI 2 "general_operand" "")
19223                          (match_operand:SI 3 "general_operand" "")))]
19224   ""
19225   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19226
19227 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19228 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19229 ;; So just document what we're doing explicitly.
19230
19231 (define_insn "x86_movsicc_0_m1"
19232   [(set (match_operand:SI 0 "register_operand" "=r")
19233         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19234           (const_int -1)
19235           (const_int 0)))
19236    (clobber (reg:CC FLAGS_REG))]
19237   ""
19238   "sbb{l}\t%0, %0"
19239   ; Since we don't have the proper number of operands for an alu insn,
19240   ; fill in all the blanks.
19241   [(set_attr "type" "alu")
19242    (set_attr "pent_pair" "pu")
19243    (set_attr "memory" "none")
19244    (set_attr "imm_disp" "false")
19245    (set_attr "mode" "SI")
19246    (set_attr "length_immediate" "0")])
19247
19248 (define_insn "*movsicc_noc"
19249   [(set (match_operand:SI 0 "register_operand" "=r,r")
19250         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19251                                 [(reg FLAGS_REG) (const_int 0)])
19252                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19253                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19254   "TARGET_CMOVE
19255    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19256   "@
19257    cmov%O2%C1\t{%2, %0|%0, %2}
19258    cmov%O2%c1\t{%3, %0|%0, %3}"
19259   [(set_attr "type" "icmov")
19260    (set_attr "mode" "SI")])
19261
19262 (define_expand "movhicc"
19263   [(set (match_operand:HI 0 "register_operand" "")
19264         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19265                          (match_operand:HI 2 "general_operand" "")
19266                          (match_operand:HI 3 "general_operand" "")))]
19267   "TARGET_HIMODE_MATH"
19268   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19269
19270 (define_insn "*movhicc_noc"
19271   [(set (match_operand:HI 0 "register_operand" "=r,r")
19272         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19273                                 [(reg FLAGS_REG) (const_int 0)])
19274                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19275                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19276   "TARGET_CMOVE
19277    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19278   "@
19279    cmov%O2%C1\t{%2, %0|%0, %2}
19280    cmov%O2%c1\t{%3, %0|%0, %3}"
19281   [(set_attr "type" "icmov")
19282    (set_attr "mode" "HI")])
19283
19284 (define_expand "movqicc"
19285   [(set (match_operand:QI 0 "register_operand" "")
19286         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19287                          (match_operand:QI 2 "general_operand" "")
19288                          (match_operand:QI 3 "general_operand" "")))]
19289   "TARGET_QIMODE_MATH"
19290   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19291
19292 (define_insn_and_split "*movqicc_noc"
19293   [(set (match_operand:QI 0 "register_operand" "=r,r")
19294         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19295                                 [(match_operand 4 "flags_reg_operand" "")
19296                                  (const_int 0)])
19297                       (match_operand:QI 2 "register_operand" "r,0")
19298                       (match_operand:QI 3 "register_operand" "0,r")))]
19299   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19300   "#"
19301   "&& reload_completed"
19302   [(set (match_dup 0)
19303         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19304                       (match_dup 2)
19305                       (match_dup 3)))]
19306   "operands[0] = gen_lowpart (SImode, operands[0]);
19307    operands[2] = gen_lowpart (SImode, operands[2]);
19308    operands[3] = gen_lowpart (SImode, operands[3]);"
19309   [(set_attr "type" "icmov")
19310    (set_attr "mode" "SI")])
19311
19312 (define_expand "movsfcc"
19313   [(set (match_operand:SF 0 "register_operand" "")
19314         (if_then_else:SF (match_operand 1 "comparison_operator" "")
19315                          (match_operand:SF 2 "register_operand" "")
19316                          (match_operand:SF 3 "register_operand" "")))]
19317   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19318   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19319
19320 (define_insn "*movsfcc_1_387"
19321   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19322         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19323                                 [(reg FLAGS_REG) (const_int 0)])
19324                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19325                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19326   "TARGET_80387 && TARGET_CMOVE
19327    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19328   "@
19329    fcmov%F1\t{%2, %0|%0, %2}
19330    fcmov%f1\t{%3, %0|%0, %3}
19331    cmov%O2%C1\t{%2, %0|%0, %2}
19332    cmov%O2%c1\t{%3, %0|%0, %3}"
19333   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19334    (set_attr "mode" "SF,SF,SI,SI")])
19335
19336 (define_expand "movdfcc"
19337   [(set (match_operand:DF 0 "register_operand" "")
19338         (if_then_else:DF (match_operand 1 "comparison_operator" "")
19339                          (match_operand:DF 2 "register_operand" "")
19340                          (match_operand:DF 3 "register_operand" "")))]
19341   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19342   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19343
19344 (define_insn "*movdfcc_1"
19345   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19346         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19347                                 [(reg FLAGS_REG) (const_int 0)])
19348                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19349                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19350   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19351    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19352   "@
19353    fcmov%F1\t{%2, %0|%0, %2}
19354    fcmov%f1\t{%3, %0|%0, %3}
19355    #
19356    #"
19357   [(set_attr "type" "fcmov,fcmov,multi,multi")
19358    (set_attr "mode" "DF")])
19359
19360 (define_insn "*movdfcc_1_rex64"
19361   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19362         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19363                                 [(reg FLAGS_REG) (const_int 0)])
19364                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19365                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19366   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19367    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19368   "@
19369    fcmov%F1\t{%2, %0|%0, %2}
19370    fcmov%f1\t{%3, %0|%0, %3}
19371    cmov%O2%C1\t{%2, %0|%0, %2}
19372    cmov%O2%c1\t{%3, %0|%0, %3}"
19373   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19374    (set_attr "mode" "DF")])
19375
19376 (define_split
19377   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19378         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19379                                 [(match_operand 4 "flags_reg_operand" "")
19380                                  (const_int 0)])
19381                       (match_operand:DF 2 "nonimmediate_operand" "")
19382                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19383   "!TARGET_64BIT && reload_completed"
19384   [(set (match_dup 2)
19385         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19386                       (match_dup 5)
19387                       (match_dup 7)))
19388    (set (match_dup 3)
19389         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19390                       (match_dup 6)
19391                       (match_dup 8)))]
19392   "split_di (operands+2, 1, operands+5, operands+6);
19393    split_di (operands+3, 1, operands+7, operands+8);
19394    split_di (operands, 1, operands+2, operands+3);")
19395
19396 (define_expand "movxfcc"
19397   [(set (match_operand:XF 0 "register_operand" "")
19398         (if_then_else:XF (match_operand 1 "comparison_operator" "")
19399                          (match_operand:XF 2 "register_operand" "")
19400                          (match_operand:XF 3 "register_operand" "")))]
19401   "TARGET_80387 && TARGET_CMOVE"
19402   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19403
19404 (define_insn "*movxfcc_1"
19405   [(set (match_operand:XF 0 "register_operand" "=f,f")
19406         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19407                                 [(reg FLAGS_REG) (const_int 0)])
19408                       (match_operand:XF 2 "register_operand" "f,0")
19409                       (match_operand:XF 3 "register_operand" "0,f")))]
19410   "TARGET_80387 && TARGET_CMOVE"
19411   "@
19412    fcmov%F1\t{%2, %0|%0, %2}
19413    fcmov%f1\t{%3, %0|%0, %3}"
19414   [(set_attr "type" "fcmov")
19415    (set_attr "mode" "XF")])
19416
19417 ;; These versions of the min/max patterns are intentionally ignorant of
19418 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19419 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19420 ;; are undefined in this condition, we're certain this is correct.
19421
19422 (define_insn "sminsf3"
19423   [(set (match_operand:SF 0 "register_operand" "=x")
19424         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19425                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19426   "TARGET_SSE_MATH"
19427   "minss\t{%2, %0|%0, %2}"
19428   [(set_attr "type" "sseadd")
19429    (set_attr "mode" "SF")])
19430
19431 (define_insn "smaxsf3"
19432   [(set (match_operand:SF 0 "register_operand" "=x")
19433         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19434                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19435   "TARGET_SSE_MATH"
19436   "maxss\t{%2, %0|%0, %2}"
19437   [(set_attr "type" "sseadd")
19438    (set_attr "mode" "SF")])
19439
19440 (define_insn "smindf3"
19441   [(set (match_operand:DF 0 "register_operand" "=x")
19442         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19443                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19444   "TARGET_SSE2 && TARGET_SSE_MATH"
19445   "minsd\t{%2, %0|%0, %2}"
19446   [(set_attr "type" "sseadd")
19447    (set_attr "mode" "DF")])
19448
19449 (define_insn "smaxdf3"
19450   [(set (match_operand:DF 0 "register_operand" "=x")
19451         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19452                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19453   "TARGET_SSE2 && TARGET_SSE_MATH"
19454   "maxsd\t{%2, %0|%0, %2}"
19455   [(set_attr "type" "sseadd")
19456    (set_attr "mode" "DF")])
19457
19458 ;; These versions of the min/max patterns implement exactly the operations
19459 ;;   min = (op1 < op2 ? op1 : op2)
19460 ;;   max = (!(op1 < op2) ? op1 : op2)
19461 ;; Their operands are not commutative, and thus they may be used in the
19462 ;; presence of -0.0 and NaN.
19463
19464 (define_insn "*ieee_sminsf3"
19465   [(set (match_operand:SF 0 "register_operand" "=x")
19466         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19467                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19468                    UNSPEC_IEEE_MIN))]
19469   "TARGET_SSE_MATH"
19470   "minss\t{%2, %0|%0, %2}"
19471   [(set_attr "type" "sseadd")
19472    (set_attr "mode" "SF")])
19473
19474 (define_insn "*ieee_smaxsf3"
19475   [(set (match_operand:SF 0 "register_operand" "=x")
19476         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19477                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19478                    UNSPEC_IEEE_MAX))]
19479   "TARGET_SSE_MATH"
19480   "maxss\t{%2, %0|%0, %2}"
19481   [(set_attr "type" "sseadd")
19482    (set_attr "mode" "SF")])
19483
19484 (define_insn "*ieee_smindf3"
19485   [(set (match_operand:DF 0 "register_operand" "=x")
19486         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19487                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19488                    UNSPEC_IEEE_MIN))]
19489   "TARGET_SSE2 && TARGET_SSE_MATH"
19490   "minsd\t{%2, %0|%0, %2}"
19491   [(set_attr "type" "sseadd")
19492    (set_attr "mode" "DF")])
19493
19494 (define_insn "*ieee_smaxdf3"
19495   [(set (match_operand:DF 0 "register_operand" "=x")
19496         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19497                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19498                    UNSPEC_IEEE_MAX))]
19499   "TARGET_SSE2 && TARGET_SSE_MATH"
19500   "maxsd\t{%2, %0|%0, %2}"
19501   [(set_attr "type" "sseadd")
19502    (set_attr "mode" "DF")])
19503
19504 ;; Make two stack loads independent:
19505 ;;   fld aa              fld aa
19506 ;;   fld %st(0)     ->   fld bb
19507 ;;   fmul bb             fmul %st(1), %st
19508 ;;
19509 ;; Actually we only match the last two instructions for simplicity.
19510 (define_peephole2
19511   [(set (match_operand 0 "fp_register_operand" "")
19512         (match_operand 1 "fp_register_operand" ""))
19513    (set (match_dup 0)
19514         (match_operator 2 "binary_fp_operator"
19515            [(match_dup 0)
19516             (match_operand 3 "memory_operand" "")]))]
19517   "REGNO (operands[0]) != REGNO (operands[1])"
19518   [(set (match_dup 0) (match_dup 3))
19519    (set (match_dup 0) (match_dup 4))]
19520
19521   ;; The % modifier is not operational anymore in peephole2's, so we have to
19522   ;; swap the operands manually in the case of addition and multiplication.
19523   "if (COMMUTATIVE_ARITH_P (operands[2]))
19524      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19525                                  operands[0], operands[1]);
19526    else
19527      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19528                                  operands[1], operands[0]);")
19529
19530 ;; Conditional addition patterns
19531 (define_expand "addqicc"
19532   [(match_operand:QI 0 "register_operand" "")
19533    (match_operand 1 "comparison_operator" "")
19534    (match_operand:QI 2 "register_operand" "")
19535    (match_operand:QI 3 "const_int_operand" "")]
19536   ""
19537   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19538
19539 (define_expand "addhicc"
19540   [(match_operand:HI 0 "register_operand" "")
19541    (match_operand 1 "comparison_operator" "")
19542    (match_operand:HI 2 "register_operand" "")
19543    (match_operand:HI 3 "const_int_operand" "")]
19544   ""
19545   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19546
19547 (define_expand "addsicc"
19548   [(match_operand:SI 0 "register_operand" "")
19549    (match_operand 1 "comparison_operator" "")
19550    (match_operand:SI 2 "register_operand" "")
19551    (match_operand:SI 3 "const_int_operand" "")]
19552   ""
19553   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19554
19555 (define_expand "adddicc"
19556   [(match_operand:DI 0 "register_operand" "")
19557    (match_operand 1 "comparison_operator" "")
19558    (match_operand:DI 2 "register_operand" "")
19559    (match_operand:DI 3 "const_int_operand" "")]
19560   "TARGET_64BIT"
19561   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19562
19563 \f
19564 ;; Misc patterns (?)
19565
19566 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19567 ;; Otherwise there will be nothing to keep
19568 ;;
19569 ;; [(set (reg ebp) (reg esp))]
19570 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19571 ;;  (clobber (eflags)]
19572 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19573 ;;
19574 ;; in proper program order.
19575 (define_insn "pro_epilogue_adjust_stack_1"
19576   [(set (match_operand:SI 0 "register_operand" "=r,r")
19577         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19578                  (match_operand:SI 2 "immediate_operand" "i,i")))
19579    (clobber (reg:CC FLAGS_REG))
19580    (clobber (mem:BLK (scratch)))]
19581   "!TARGET_64BIT"
19582 {
19583   switch (get_attr_type (insn))
19584     {
19585     case TYPE_IMOV:
19586       return "mov{l}\t{%1, %0|%0, %1}";
19587
19588     case TYPE_ALU:
19589       if (CONST_INT_P (operands[2])
19590           && (INTVAL (operands[2]) == 128
19591               || (INTVAL (operands[2]) < 0
19592                   && INTVAL (operands[2]) != -128)))
19593         {
19594           operands[2] = GEN_INT (-INTVAL (operands[2]));
19595           return "sub{l}\t{%2, %0|%0, %2}";
19596         }
19597       return "add{l}\t{%2, %0|%0, %2}";
19598
19599     case TYPE_LEA:
19600       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19601       return "lea{l}\t{%a2, %0|%0, %a2}";
19602
19603     default:
19604       gcc_unreachable ();
19605     }
19606 }
19607   [(set (attr "type")
19608         (cond [(eq_attr "alternative" "0")
19609                  (const_string "alu")
19610                (match_operand:SI 2 "const0_operand" "")
19611                  (const_string "imov")
19612               ]
19613               (const_string "lea")))
19614    (set_attr "mode" "SI")])
19615
19616 (define_insn "pro_epilogue_adjust_stack_rex64"
19617   [(set (match_operand:DI 0 "register_operand" "=r,r")
19618         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19619                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19620    (clobber (reg:CC FLAGS_REG))
19621    (clobber (mem:BLK (scratch)))]
19622   "TARGET_64BIT"
19623 {
19624   switch (get_attr_type (insn))
19625     {
19626     case TYPE_IMOV:
19627       return "mov{q}\t{%1, %0|%0, %1}";
19628
19629     case TYPE_ALU:
19630       if (CONST_INT_P (operands[2])
19631           /* Avoid overflows.  */
19632           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19633           && (INTVAL (operands[2]) == 128
19634               || (INTVAL (operands[2]) < 0
19635                   && INTVAL (operands[2]) != -128)))
19636         {
19637           operands[2] = GEN_INT (-INTVAL (operands[2]));
19638           return "sub{q}\t{%2, %0|%0, %2}";
19639         }
19640       return "add{q}\t{%2, %0|%0, %2}";
19641
19642     case TYPE_LEA:
19643       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19644       return "lea{q}\t{%a2, %0|%0, %a2}";
19645
19646     default:
19647       gcc_unreachable ();
19648     }
19649 }
19650   [(set (attr "type")
19651         (cond [(eq_attr "alternative" "0")
19652                  (const_string "alu")
19653                (match_operand:DI 2 "const0_operand" "")
19654                  (const_string "imov")
19655               ]
19656               (const_string "lea")))
19657    (set_attr "mode" "DI")])
19658
19659 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19660   [(set (match_operand:DI 0 "register_operand" "=r,r")
19661         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19662                  (match_operand:DI 3 "immediate_operand" "i,i")))
19663    (use (match_operand:DI 2 "register_operand" "r,r"))
19664    (clobber (reg:CC FLAGS_REG))
19665    (clobber (mem:BLK (scratch)))]
19666   "TARGET_64BIT"
19667 {
19668   switch (get_attr_type (insn))
19669     {
19670     case TYPE_ALU:
19671       return "add{q}\t{%2, %0|%0, %2}";
19672
19673     case TYPE_LEA:
19674       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19675       return "lea{q}\t{%a2, %0|%0, %a2}";
19676
19677     default:
19678       gcc_unreachable ();
19679     }
19680 }
19681   [(set_attr "type" "alu,lea")
19682    (set_attr "mode" "DI")])
19683
19684 (define_expand "allocate_stack_worker"
19685   [(match_operand:SI 0 "register_operand" "")]
19686   "TARGET_STACK_PROBE"
19687 {
19688   if (reload_completed)
19689     {
19690       if (TARGET_64BIT)
19691         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19692       else
19693         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19694     }
19695   else
19696     {
19697       if (TARGET_64BIT)
19698         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19699       else
19700         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19701     }
19702   DONE;
19703 })
19704
19705 (define_insn "allocate_stack_worker_1"
19706   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19707     UNSPECV_STACK_PROBE)
19708    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19709    (clobber (match_scratch:SI 1 "=0"))
19710    (clobber (reg:CC FLAGS_REG))]
19711   "!TARGET_64BIT && TARGET_STACK_PROBE"
19712   "call\t__alloca"
19713   [(set_attr "type" "multi")
19714    (set_attr "length" "5")])
19715
19716 (define_expand "allocate_stack_worker_postreload"
19717   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19718                                     UNSPECV_STACK_PROBE)
19719               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19720               (clobber (match_dup 0))
19721               (clobber (reg:CC FLAGS_REG))])]
19722   ""
19723   "")
19724
19725 (define_insn "allocate_stack_worker_rex64"
19726   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19727     UNSPECV_STACK_PROBE)
19728    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19729    (clobber (match_scratch:DI 1 "=0"))
19730    (clobber (reg:CC FLAGS_REG))]
19731   "TARGET_64BIT && TARGET_STACK_PROBE"
19732   "call\t__alloca"
19733   [(set_attr "type" "multi")
19734    (set_attr "length" "5")])
19735
19736 (define_expand "allocate_stack_worker_rex64_postreload"
19737   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19738                                     UNSPECV_STACK_PROBE)
19739               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19740               (clobber (match_dup 0))
19741               (clobber (reg:CC FLAGS_REG))])]
19742   ""
19743   "")
19744
19745 (define_expand "allocate_stack"
19746   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19747                    (minus:SI (reg:SI SP_REG)
19748                              (match_operand:SI 1 "general_operand" "")))
19749               (clobber (reg:CC FLAGS_REG))])
19750    (parallel [(set (reg:SI SP_REG)
19751                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
19752               (clobber (reg:CC FLAGS_REG))])]
19753   "TARGET_STACK_PROBE"
19754 {
19755 #ifdef CHECK_STACK_LIMIT
19756   if (CONST_INT_P (operands[1])
19757       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19758     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19759                            operands[1]));
19760   else
19761 #endif
19762     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19763                                                             operands[1])));
19764
19765   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19766   DONE;
19767 })
19768
19769 (define_expand "builtin_setjmp_receiver"
19770   [(label_ref (match_operand 0 "" ""))]
19771   "!TARGET_64BIT && flag_pic"
19772 {
19773   if (TARGET_MACHO)
19774     {
19775       rtx xops[3];
19776       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19777       rtx label_rtx = gen_label_rtx ();
19778       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19779       xops[0] = xops[1] = picreg;
19780       xops[2] = gen_rtx_CONST (SImode,
19781                   gen_rtx_MINUS (SImode,
19782                     gen_rtx_LABEL_REF (SImode, label_rtx),
19783                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19784       ix86_expand_binary_operator (MINUS, SImode, xops);
19785     }
19786   else
19787     emit_insn (gen_set_got (pic_offset_table_rtx));
19788   DONE;
19789 })
19790 \f
19791 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19792
19793 (define_split
19794   [(set (match_operand 0 "register_operand" "")
19795         (match_operator 3 "promotable_binary_operator"
19796            [(match_operand 1 "register_operand" "")
19797             (match_operand 2 "aligned_operand" "")]))
19798    (clobber (reg:CC FLAGS_REG))]
19799   "! TARGET_PARTIAL_REG_STALL && reload_completed
19800    && ((GET_MODE (operands[0]) == HImode
19801         && ((!optimize_size && !TARGET_FAST_PREFIX)
19802             /* ??? next two lines just !satisfies_constraint_K (...) */
19803             || !CONST_INT_P (operands[2])
19804             || satisfies_constraint_K (operands[2])))
19805        || (GET_MODE (operands[0]) == QImode
19806            && (TARGET_PROMOTE_QImode || optimize_size)))"
19807   [(parallel [(set (match_dup 0)
19808                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19809               (clobber (reg:CC FLAGS_REG))])]
19810   "operands[0] = gen_lowpart (SImode, operands[0]);
19811    operands[1] = gen_lowpart (SImode, operands[1]);
19812    if (GET_CODE (operands[3]) != ASHIFT)
19813      operands[2] = gen_lowpart (SImode, operands[2]);
19814    PUT_MODE (operands[3], SImode);")
19815
19816 ; Promote the QImode tests, as i386 has encoding of the AND
19817 ; instruction with 32-bit sign-extended immediate and thus the
19818 ; instruction size is unchanged, except in the %eax case for
19819 ; which it is increased by one byte, hence the ! optimize_size.
19820 (define_split
19821   [(set (match_operand 0 "flags_reg_operand" "")
19822         (match_operator 2 "compare_operator"
19823           [(and (match_operand 3 "aligned_operand" "")
19824                 (match_operand 4 "const_int_operand" ""))
19825            (const_int 0)]))
19826    (set (match_operand 1 "register_operand" "")
19827         (and (match_dup 3) (match_dup 4)))]
19828   "! TARGET_PARTIAL_REG_STALL && reload_completed
19829    /* Ensure that the operand will remain sign-extended immediate.  */
19830    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19831    && ! optimize_size
19832    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19833        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19834   [(parallel [(set (match_dup 0)
19835                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19836                                     (const_int 0)]))
19837               (set (match_dup 1)
19838                    (and:SI (match_dup 3) (match_dup 4)))])]
19839 {
19840   operands[4]
19841     = gen_int_mode (INTVAL (operands[4])
19842                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19843   operands[1] = gen_lowpart (SImode, operands[1]);
19844   operands[3] = gen_lowpart (SImode, operands[3]);
19845 })
19846
19847 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19848 ; the TEST instruction with 32-bit sign-extended immediate and thus
19849 ; the instruction size would at least double, which is not what we
19850 ; want even with ! optimize_size.
19851 (define_split
19852   [(set (match_operand 0 "flags_reg_operand" "")
19853         (match_operator 1 "compare_operator"
19854           [(and (match_operand:HI 2 "aligned_operand" "")
19855                 (match_operand:HI 3 "const_int_operand" ""))
19856            (const_int 0)]))]
19857   "! TARGET_PARTIAL_REG_STALL && reload_completed
19858    /* Ensure that the operand will remain sign-extended immediate.  */
19859    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19860    && ! TARGET_FAST_PREFIX
19861    && ! optimize_size"
19862   [(set (match_dup 0)
19863         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19864                          (const_int 0)]))]
19865 {
19866   operands[3]
19867     = gen_int_mode (INTVAL (operands[3])
19868                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19869   operands[2] = gen_lowpart (SImode, operands[2]);
19870 })
19871
19872 (define_split
19873   [(set (match_operand 0 "register_operand" "")
19874         (neg (match_operand 1 "register_operand" "")))
19875    (clobber (reg:CC FLAGS_REG))]
19876   "! TARGET_PARTIAL_REG_STALL && reload_completed
19877    && (GET_MODE (operands[0]) == HImode
19878        || (GET_MODE (operands[0]) == QImode
19879            && (TARGET_PROMOTE_QImode || optimize_size)))"
19880   [(parallel [(set (match_dup 0)
19881                    (neg:SI (match_dup 1)))
19882               (clobber (reg:CC FLAGS_REG))])]
19883   "operands[0] = gen_lowpart (SImode, operands[0]);
19884    operands[1] = gen_lowpart (SImode, operands[1]);")
19885
19886 (define_split
19887   [(set (match_operand 0 "register_operand" "")
19888         (not (match_operand 1 "register_operand" "")))]
19889   "! TARGET_PARTIAL_REG_STALL && reload_completed
19890    && (GET_MODE (operands[0]) == HImode
19891        || (GET_MODE (operands[0]) == QImode
19892            && (TARGET_PROMOTE_QImode || optimize_size)))"
19893   [(set (match_dup 0)
19894         (not:SI (match_dup 1)))]
19895   "operands[0] = gen_lowpart (SImode, operands[0]);
19896    operands[1] = gen_lowpart (SImode, operands[1]);")
19897
19898 (define_split
19899   [(set (match_operand 0 "register_operand" "")
19900         (if_then_else (match_operator 1 "comparison_operator"
19901                                 [(reg FLAGS_REG) (const_int 0)])
19902                       (match_operand 2 "register_operand" "")
19903                       (match_operand 3 "register_operand" "")))]
19904   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19905    && (GET_MODE (operands[0]) == HImode
19906        || (GET_MODE (operands[0]) == QImode
19907            && (TARGET_PROMOTE_QImode || optimize_size)))"
19908   [(set (match_dup 0)
19909         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19910   "operands[0] = gen_lowpart (SImode, operands[0]);
19911    operands[2] = gen_lowpart (SImode, operands[2]);
19912    operands[3] = gen_lowpart (SImode, operands[3]);")
19913
19914 \f
19915 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19916 ;; transform a complex memory operation into two memory to register operations.
19917
19918 ;; Don't push memory operands
19919 (define_peephole2
19920   [(set (match_operand:SI 0 "push_operand" "")
19921         (match_operand:SI 1 "memory_operand" ""))
19922    (match_scratch:SI 2 "r")]
19923   "!optimize_size && !TARGET_PUSH_MEMORY
19924    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19925   [(set (match_dup 2) (match_dup 1))
19926    (set (match_dup 0) (match_dup 2))]
19927   "")
19928
19929 (define_peephole2
19930   [(set (match_operand:DI 0 "push_operand" "")
19931         (match_operand:DI 1 "memory_operand" ""))
19932    (match_scratch:DI 2 "r")]
19933   "!optimize_size && !TARGET_PUSH_MEMORY
19934    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19935   [(set (match_dup 2) (match_dup 1))
19936    (set (match_dup 0) (match_dup 2))]
19937   "")
19938
19939 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19940 ;; SImode pushes.
19941 (define_peephole2
19942   [(set (match_operand:SF 0 "push_operand" "")
19943         (match_operand:SF 1 "memory_operand" ""))
19944    (match_scratch:SF 2 "r")]
19945   "!optimize_size && !TARGET_PUSH_MEMORY
19946    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19947   [(set (match_dup 2) (match_dup 1))
19948    (set (match_dup 0) (match_dup 2))]
19949   "")
19950
19951 (define_peephole2
19952   [(set (match_operand:HI 0 "push_operand" "")
19953         (match_operand:HI 1 "memory_operand" ""))
19954    (match_scratch:HI 2 "r")]
19955   "!optimize_size && !TARGET_PUSH_MEMORY
19956    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19957   [(set (match_dup 2) (match_dup 1))
19958    (set (match_dup 0) (match_dup 2))]
19959   "")
19960
19961 (define_peephole2
19962   [(set (match_operand:QI 0 "push_operand" "")
19963         (match_operand:QI 1 "memory_operand" ""))
19964    (match_scratch:QI 2 "q")]
19965   "!optimize_size && !TARGET_PUSH_MEMORY
19966    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19967   [(set (match_dup 2) (match_dup 1))
19968    (set (match_dup 0) (match_dup 2))]
19969   "")
19970
19971 ;; Don't move an immediate directly to memory when the instruction
19972 ;; gets too big.
19973 (define_peephole2
19974   [(match_scratch:SI 1 "r")
19975    (set (match_operand:SI 0 "memory_operand" "")
19976         (const_int 0))]
19977   "! optimize_size
19978    && ! TARGET_USE_MOV0
19979    && TARGET_SPLIT_LONG_MOVES
19980    && get_attr_length (insn) >= ix86_cost->large_insn
19981    && peep2_regno_dead_p (0, FLAGS_REG)"
19982   [(parallel [(set (match_dup 1) (const_int 0))
19983               (clobber (reg:CC FLAGS_REG))])
19984    (set (match_dup 0) (match_dup 1))]
19985   "")
19986
19987 (define_peephole2
19988   [(match_scratch:HI 1 "r")
19989    (set (match_operand:HI 0 "memory_operand" "")
19990         (const_int 0))]
19991   "! optimize_size
19992    && ! TARGET_USE_MOV0
19993    && TARGET_SPLIT_LONG_MOVES
19994    && get_attr_length (insn) >= ix86_cost->large_insn
19995    && peep2_regno_dead_p (0, FLAGS_REG)"
19996   [(parallel [(set (match_dup 2) (const_int 0))
19997               (clobber (reg:CC FLAGS_REG))])
19998    (set (match_dup 0) (match_dup 1))]
19999   "operands[2] = gen_lowpart (SImode, operands[1]);")
20000
20001 (define_peephole2
20002   [(match_scratch:QI 1 "q")
20003    (set (match_operand:QI 0 "memory_operand" "")
20004         (const_int 0))]
20005   "! optimize_size
20006    && ! TARGET_USE_MOV0
20007    && TARGET_SPLIT_LONG_MOVES
20008    && get_attr_length (insn) >= ix86_cost->large_insn
20009    && peep2_regno_dead_p (0, FLAGS_REG)"
20010   [(parallel [(set (match_dup 2) (const_int 0))
20011               (clobber (reg:CC FLAGS_REG))])
20012    (set (match_dup 0) (match_dup 1))]
20013   "operands[2] = gen_lowpart (SImode, operands[1]);")
20014
20015 (define_peephole2
20016   [(match_scratch:SI 2 "r")
20017    (set (match_operand:SI 0 "memory_operand" "")
20018         (match_operand:SI 1 "immediate_operand" ""))]
20019   "! optimize_size
20020    && get_attr_length (insn) >= ix86_cost->large_insn
20021    && TARGET_SPLIT_LONG_MOVES"
20022   [(set (match_dup 2) (match_dup 1))
20023    (set (match_dup 0) (match_dup 2))]
20024   "")
20025
20026 (define_peephole2
20027   [(match_scratch:HI 2 "r")
20028    (set (match_operand:HI 0 "memory_operand" "")
20029         (match_operand:HI 1 "immediate_operand" ""))]
20030   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
20031   && TARGET_SPLIT_LONG_MOVES"
20032   [(set (match_dup 2) (match_dup 1))
20033    (set (match_dup 0) (match_dup 2))]
20034   "")
20035
20036 (define_peephole2
20037   [(match_scratch:QI 2 "q")
20038    (set (match_operand:QI 0 "memory_operand" "")
20039         (match_operand:QI 1 "immediate_operand" ""))]
20040   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
20041   && TARGET_SPLIT_LONG_MOVES"
20042   [(set (match_dup 2) (match_dup 1))
20043    (set (match_dup 0) (match_dup 2))]
20044   "")
20045
20046 ;; Don't compare memory with zero, load and use a test instead.
20047 (define_peephole2
20048   [(set (match_operand 0 "flags_reg_operand" "")
20049         (match_operator 1 "compare_operator"
20050           [(match_operand:SI 2 "memory_operand" "")
20051            (const_int 0)]))
20052    (match_scratch:SI 3 "r")]
20053   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
20054   [(set (match_dup 3) (match_dup 2))
20055    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20056   "")
20057
20058 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20059 ;; Don't split NOTs with a displacement operand, because resulting XOR
20060 ;; will not be pairable anyway.
20061 ;;
20062 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20063 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20064 ;; so this split helps here as well.
20065 ;;
20066 ;; Note: Can't do this as a regular split because we can't get proper
20067 ;; lifetime information then.
20068
20069 (define_peephole2
20070   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20071         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20072   "!optimize_size
20073    && peep2_regno_dead_p (0, FLAGS_REG)
20074    && ((TARGET_PENTIUM
20075         && (!MEM_P (operands[0])
20076             || !memory_displacement_operand (operands[0], SImode)))
20077        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
20078   [(parallel [(set (match_dup 0)
20079                    (xor:SI (match_dup 1) (const_int -1)))
20080               (clobber (reg:CC FLAGS_REG))])]
20081   "")
20082
20083 (define_peephole2
20084   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20085         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20086   "!optimize_size
20087    && peep2_regno_dead_p (0, FLAGS_REG)
20088    && ((TARGET_PENTIUM
20089         && (!MEM_P (operands[0])
20090             || !memory_displacement_operand (operands[0], HImode)))
20091        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
20092   [(parallel [(set (match_dup 0)
20093                    (xor:HI (match_dup 1) (const_int -1)))
20094               (clobber (reg:CC FLAGS_REG))])]
20095   "")
20096
20097 (define_peephole2
20098   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20099         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20100   "!optimize_size
20101    && peep2_regno_dead_p (0, FLAGS_REG)
20102    && ((TARGET_PENTIUM
20103         && (!MEM_P (operands[0])
20104             || !memory_displacement_operand (operands[0], QImode)))
20105        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
20106   [(parallel [(set (match_dup 0)
20107                    (xor:QI (match_dup 1) (const_int -1)))
20108               (clobber (reg:CC FLAGS_REG))])]
20109   "")
20110
20111 ;; Non pairable "test imm, reg" instructions can be translated to
20112 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20113 ;; byte opcode instead of two, have a short form for byte operands),
20114 ;; so do it for other CPUs as well.  Given that the value was dead,
20115 ;; this should not create any new dependencies.  Pass on the sub-word
20116 ;; versions if we're concerned about partial register stalls.
20117
20118 (define_peephole2
20119   [(set (match_operand 0 "flags_reg_operand" "")
20120         (match_operator 1 "compare_operator"
20121           [(and:SI (match_operand:SI 2 "register_operand" "")
20122                    (match_operand:SI 3 "immediate_operand" ""))
20123            (const_int 0)]))]
20124   "ix86_match_ccmode (insn, CCNOmode)
20125    && (true_regnum (operands[2]) != 0
20126        || satisfies_constraint_K (operands[3]))
20127    && peep2_reg_dead_p (1, operands[2])"
20128   [(parallel
20129      [(set (match_dup 0)
20130            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20131                             (const_int 0)]))
20132       (set (match_dup 2)
20133            (and:SI (match_dup 2) (match_dup 3)))])]
20134   "")
20135
20136 ;; We don't need to handle HImode case, because it will be promoted to SImode
20137 ;; on ! TARGET_PARTIAL_REG_STALL
20138
20139 (define_peephole2
20140   [(set (match_operand 0 "flags_reg_operand" "")
20141         (match_operator 1 "compare_operator"
20142           [(and:QI (match_operand:QI 2 "register_operand" "")
20143                    (match_operand:QI 3 "immediate_operand" ""))
20144            (const_int 0)]))]
20145   "! TARGET_PARTIAL_REG_STALL
20146    && ix86_match_ccmode (insn, CCNOmode)
20147    && true_regnum (operands[2]) != 0
20148    && peep2_reg_dead_p (1, operands[2])"
20149   [(parallel
20150      [(set (match_dup 0)
20151            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20152                             (const_int 0)]))
20153       (set (match_dup 2)
20154            (and:QI (match_dup 2) (match_dup 3)))])]
20155   "")
20156
20157 (define_peephole2
20158   [(set (match_operand 0 "flags_reg_operand" "")
20159         (match_operator 1 "compare_operator"
20160           [(and:SI
20161              (zero_extract:SI
20162                (match_operand 2 "ext_register_operand" "")
20163                (const_int 8)
20164                (const_int 8))
20165              (match_operand 3 "const_int_operand" ""))
20166            (const_int 0)]))]
20167   "! TARGET_PARTIAL_REG_STALL
20168    && ix86_match_ccmode (insn, CCNOmode)
20169    && true_regnum (operands[2]) != 0
20170    && peep2_reg_dead_p (1, operands[2])"
20171   [(parallel [(set (match_dup 0)
20172                    (match_op_dup 1
20173                      [(and:SI
20174                         (zero_extract:SI
20175                           (match_dup 2)
20176                           (const_int 8)
20177                           (const_int 8))
20178                         (match_dup 3))
20179                       (const_int 0)]))
20180               (set (zero_extract:SI (match_dup 2)
20181                                     (const_int 8)
20182                                     (const_int 8))
20183                    (and:SI
20184                      (zero_extract:SI
20185                        (match_dup 2)
20186                        (const_int 8)
20187                        (const_int 8))
20188                      (match_dup 3)))])]
20189   "")
20190
20191 ;; Don't do logical operations with memory inputs.
20192 (define_peephole2
20193   [(match_scratch:SI 2 "r")
20194    (parallel [(set (match_operand:SI 0 "register_operand" "")
20195                    (match_operator:SI 3 "arith_or_logical_operator"
20196                      [(match_dup 0)
20197                       (match_operand:SI 1 "memory_operand" "")]))
20198               (clobber (reg:CC FLAGS_REG))])]
20199   "! optimize_size && ! TARGET_READ_MODIFY"
20200   [(set (match_dup 2) (match_dup 1))
20201    (parallel [(set (match_dup 0)
20202                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20203               (clobber (reg:CC FLAGS_REG))])]
20204   "")
20205
20206 (define_peephole2
20207   [(match_scratch:SI 2 "r")
20208    (parallel [(set (match_operand:SI 0 "register_operand" "")
20209                    (match_operator:SI 3 "arith_or_logical_operator"
20210                      [(match_operand:SI 1 "memory_operand" "")
20211                       (match_dup 0)]))
20212               (clobber (reg:CC FLAGS_REG))])]
20213   "! optimize_size && ! TARGET_READ_MODIFY"
20214   [(set (match_dup 2) (match_dup 1))
20215    (parallel [(set (match_dup 0)
20216                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20217               (clobber (reg:CC FLAGS_REG))])]
20218   "")
20219
20220 ; Don't do logical operations with memory outputs
20221 ;
20222 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20223 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20224 ; the same decoder scheduling characteristics as the original.
20225
20226 (define_peephole2
20227   [(match_scratch:SI 2 "r")
20228    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20229                    (match_operator:SI 3 "arith_or_logical_operator"
20230                      [(match_dup 0)
20231                       (match_operand:SI 1 "nonmemory_operand" "")]))
20232               (clobber (reg:CC FLAGS_REG))])]
20233   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20234   [(set (match_dup 2) (match_dup 0))
20235    (parallel [(set (match_dup 2)
20236                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20237               (clobber (reg:CC FLAGS_REG))])
20238    (set (match_dup 0) (match_dup 2))]
20239   "")
20240
20241 (define_peephole2
20242   [(match_scratch:SI 2 "r")
20243    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20244                    (match_operator:SI 3 "arith_or_logical_operator"
20245                      [(match_operand:SI 1 "nonmemory_operand" "")
20246                       (match_dup 0)]))
20247               (clobber (reg:CC FLAGS_REG))])]
20248   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20249   [(set (match_dup 2) (match_dup 0))
20250    (parallel [(set (match_dup 2)
20251                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20252               (clobber (reg:CC FLAGS_REG))])
20253    (set (match_dup 0) (match_dup 2))]
20254   "")
20255
20256 ;; Attempt to always use XOR for zeroing registers.
20257 (define_peephole2
20258   [(set (match_operand 0 "register_operand" "")
20259         (match_operand 1 "const0_operand" ""))]
20260   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20261    && (! TARGET_USE_MOV0 || optimize_size)
20262    && GENERAL_REG_P (operands[0])
20263    && peep2_regno_dead_p (0, FLAGS_REG)"
20264   [(parallel [(set (match_dup 0) (const_int 0))
20265               (clobber (reg:CC FLAGS_REG))])]
20266 {
20267   operands[0] = gen_lowpart (word_mode, operands[0]);
20268 })
20269
20270 (define_peephole2
20271   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20272         (const_int 0))]
20273   "(GET_MODE (operands[0]) == QImode
20274     || GET_MODE (operands[0]) == HImode)
20275    && (! TARGET_USE_MOV0 || optimize_size)
20276    && peep2_regno_dead_p (0, FLAGS_REG)"
20277   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20278               (clobber (reg:CC FLAGS_REG))])])
20279
20280 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20281 (define_peephole2
20282   [(set (match_operand 0 "register_operand" "")
20283         (const_int -1))]
20284   "(GET_MODE (operands[0]) == HImode
20285     || GET_MODE (operands[0]) == SImode
20286     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20287    && (optimize_size || TARGET_PENTIUM)
20288    && peep2_regno_dead_p (0, FLAGS_REG)"
20289   [(parallel [(set (match_dup 0) (const_int -1))
20290               (clobber (reg:CC FLAGS_REG))])]
20291   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20292                               operands[0]);")
20293
20294 ;; Attempt to convert simple leas to adds. These can be created by
20295 ;; move expanders.
20296 (define_peephole2
20297   [(set (match_operand:SI 0 "register_operand" "")
20298         (plus:SI (match_dup 0)
20299                  (match_operand:SI 1 "nonmemory_operand" "")))]
20300   "peep2_regno_dead_p (0, FLAGS_REG)"
20301   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20302               (clobber (reg:CC FLAGS_REG))])]
20303   "")
20304
20305 (define_peephole2
20306   [(set (match_operand:SI 0 "register_operand" "")
20307         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20308                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20309   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20310   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20311               (clobber (reg:CC FLAGS_REG))])]
20312   "operands[2] = gen_lowpart (SImode, operands[2]);")
20313
20314 (define_peephole2
20315   [(set (match_operand:DI 0 "register_operand" "")
20316         (plus:DI (match_dup 0)
20317                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20318   "peep2_regno_dead_p (0, FLAGS_REG)"
20319   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20320               (clobber (reg:CC FLAGS_REG))])]
20321   "")
20322
20323 (define_peephole2
20324   [(set (match_operand:SI 0 "register_operand" "")
20325         (mult:SI (match_dup 0)
20326                  (match_operand:SI 1 "const_int_operand" "")))]
20327   "exact_log2 (INTVAL (operands[1])) >= 0
20328    && peep2_regno_dead_p (0, FLAGS_REG)"
20329   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20330               (clobber (reg:CC FLAGS_REG))])]
20331   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20332
20333 (define_peephole2
20334   [(set (match_operand:DI 0 "register_operand" "")
20335         (mult:DI (match_dup 0)
20336                  (match_operand:DI 1 "const_int_operand" "")))]
20337   "exact_log2 (INTVAL (operands[1])) >= 0
20338    && peep2_regno_dead_p (0, FLAGS_REG)"
20339   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20340               (clobber (reg:CC FLAGS_REG))])]
20341   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20342
20343 (define_peephole2
20344   [(set (match_operand:SI 0 "register_operand" "")
20345         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20346                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20347   "exact_log2 (INTVAL (operands[2])) >= 0
20348    && REGNO (operands[0]) == REGNO (operands[1])
20349    && peep2_regno_dead_p (0, FLAGS_REG)"
20350   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20351               (clobber (reg:CC FLAGS_REG))])]
20352   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20353
20354 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20355 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20356 ;; many CPUs it is also faster, since special hardware to avoid esp
20357 ;; dependencies is present.
20358
20359 ;; While some of these conversions may be done using splitters, we use peepholes
20360 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20361
20362 ;; Convert prologue esp subtractions to push.
20363 ;; We need register to push.  In order to keep verify_flow_info happy we have
20364 ;; two choices
20365 ;; - use scratch and clobber it in order to avoid dependencies
20366 ;; - use already live register
20367 ;; We can't use the second way right now, since there is no reliable way how to
20368 ;; verify that given register is live.  First choice will also most likely in
20369 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20370 ;; call clobbered registers are dead.  We may want to use base pointer as an
20371 ;; alternative when no register is available later.
20372
20373 (define_peephole2
20374   [(match_scratch:SI 0 "r")
20375    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20376               (clobber (reg:CC FLAGS_REG))
20377               (clobber (mem:BLK (scratch)))])]
20378   "optimize_size || !TARGET_SUB_ESP_4"
20379   [(clobber (match_dup 0))
20380    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20381               (clobber (mem:BLK (scratch)))])])
20382
20383 (define_peephole2
20384   [(match_scratch:SI 0 "r")
20385    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20386               (clobber (reg:CC FLAGS_REG))
20387               (clobber (mem:BLK (scratch)))])]
20388   "optimize_size || !TARGET_SUB_ESP_8"
20389   [(clobber (match_dup 0))
20390    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20391    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20392               (clobber (mem:BLK (scratch)))])])
20393
20394 ;; Convert esp subtractions to push.
20395 (define_peephole2
20396   [(match_scratch:SI 0 "r")
20397    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20398               (clobber (reg:CC FLAGS_REG))])]
20399   "optimize_size || !TARGET_SUB_ESP_4"
20400   [(clobber (match_dup 0))
20401    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20402
20403 (define_peephole2
20404   [(match_scratch:SI 0 "r")
20405    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20406               (clobber (reg:CC FLAGS_REG))])]
20407   "optimize_size || !TARGET_SUB_ESP_8"
20408   [(clobber (match_dup 0))
20409    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20410    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20411
20412 ;; Convert epilogue deallocator to pop.
20413 (define_peephole2
20414   [(match_scratch:SI 0 "r")
20415    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20416               (clobber (reg:CC FLAGS_REG))
20417               (clobber (mem:BLK (scratch)))])]
20418   "optimize_size || !TARGET_ADD_ESP_4"
20419   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20420               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20421               (clobber (mem:BLK (scratch)))])]
20422   "")
20423
20424 ;; Two pops case is tricky, since pop causes dependency on destination register.
20425 ;; We use two registers if available.
20426 (define_peephole2
20427   [(match_scratch:SI 0 "r")
20428    (match_scratch:SI 1 "r")
20429    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20430               (clobber (reg:CC FLAGS_REG))
20431               (clobber (mem:BLK (scratch)))])]
20432   "optimize_size || !TARGET_ADD_ESP_8"
20433   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20434               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20435               (clobber (mem:BLK (scratch)))])
20436    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20437               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20438   "")
20439
20440 (define_peephole2
20441   [(match_scratch:SI 0 "r")
20442    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20443               (clobber (reg:CC FLAGS_REG))
20444               (clobber (mem:BLK (scratch)))])]
20445   "optimize_size"
20446   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20447               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20448               (clobber (mem:BLK (scratch)))])
20449    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20450               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20451   "")
20452
20453 ;; Convert esp additions to pop.
20454 (define_peephole2
20455   [(match_scratch:SI 0 "r")
20456    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20457               (clobber (reg:CC FLAGS_REG))])]
20458   ""
20459   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20460               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20461   "")
20462
20463 ;; Two pops case is tricky, since pop causes dependency on destination register.
20464 ;; We use two registers if available.
20465 (define_peephole2
20466   [(match_scratch:SI 0 "r")
20467    (match_scratch:SI 1 "r")
20468    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20469               (clobber (reg:CC FLAGS_REG))])]
20470   ""
20471   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20472               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20473    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20474               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20475   "")
20476
20477 (define_peephole2
20478   [(match_scratch:SI 0 "r")
20479    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20480               (clobber (reg:CC FLAGS_REG))])]
20481   "optimize_size"
20482   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20483               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20484    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20485               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20486   "")
20487 \f
20488 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20489 ;; required and register dies.  Similarly for 128 to plus -128.
20490 (define_peephole2
20491   [(set (match_operand 0 "flags_reg_operand" "")
20492         (match_operator 1 "compare_operator"
20493           [(match_operand 2 "register_operand" "")
20494            (match_operand 3 "const_int_operand" "")]))]
20495   "(INTVAL (operands[3]) == -1
20496     || INTVAL (operands[3]) == 1
20497     || INTVAL (operands[3]) == 128)
20498    && ix86_match_ccmode (insn, CCGCmode)
20499    && peep2_reg_dead_p (1, operands[2])"
20500   [(parallel [(set (match_dup 0)
20501                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20502               (clobber (match_dup 2))])]
20503   "")
20504 \f
20505 (define_peephole2
20506   [(match_scratch:DI 0 "r")
20507    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20508               (clobber (reg:CC FLAGS_REG))
20509               (clobber (mem:BLK (scratch)))])]
20510   "optimize_size || !TARGET_SUB_ESP_4"
20511   [(clobber (match_dup 0))
20512    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20513               (clobber (mem:BLK (scratch)))])])
20514
20515 (define_peephole2
20516   [(match_scratch:DI 0 "r")
20517    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20518               (clobber (reg:CC FLAGS_REG))
20519               (clobber (mem:BLK (scratch)))])]
20520   "optimize_size || !TARGET_SUB_ESP_8"
20521   [(clobber (match_dup 0))
20522    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20523    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20524               (clobber (mem:BLK (scratch)))])])
20525
20526 ;; Convert esp subtractions to push.
20527 (define_peephole2
20528   [(match_scratch:DI 0 "r")
20529    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20530               (clobber (reg:CC FLAGS_REG))])]
20531   "optimize_size || !TARGET_SUB_ESP_4"
20532   [(clobber (match_dup 0))
20533    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20534
20535 (define_peephole2
20536   [(match_scratch:DI 0 "r")
20537    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20538               (clobber (reg:CC FLAGS_REG))])]
20539   "optimize_size || !TARGET_SUB_ESP_8"
20540   [(clobber (match_dup 0))
20541    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20542    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20543
20544 ;; Convert epilogue deallocator to pop.
20545 (define_peephole2
20546   [(match_scratch:DI 0 "r")
20547    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20548               (clobber (reg:CC FLAGS_REG))
20549               (clobber (mem:BLK (scratch)))])]
20550   "optimize_size || !TARGET_ADD_ESP_4"
20551   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20552               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20553               (clobber (mem:BLK (scratch)))])]
20554   "")
20555
20556 ;; Two pops case is tricky, since pop causes dependency on destination register.
20557 ;; We use two registers if available.
20558 (define_peephole2
20559   [(match_scratch:DI 0 "r")
20560    (match_scratch:DI 1 "r")
20561    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20562               (clobber (reg:CC FLAGS_REG))
20563               (clobber (mem:BLK (scratch)))])]
20564   "optimize_size || !TARGET_ADD_ESP_8"
20565   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20566               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20567               (clobber (mem:BLK (scratch)))])
20568    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20569               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20570   "")
20571
20572 (define_peephole2
20573   [(match_scratch:DI 0 "r")
20574    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20575               (clobber (reg:CC FLAGS_REG))
20576               (clobber (mem:BLK (scratch)))])]
20577   "optimize_size"
20578   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20579               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20580               (clobber (mem:BLK (scratch)))])
20581    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20582               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20583   "")
20584
20585 ;; Convert esp additions to pop.
20586 (define_peephole2
20587   [(match_scratch:DI 0 "r")
20588    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20589               (clobber (reg:CC FLAGS_REG))])]
20590   ""
20591   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20592               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20593   "")
20594
20595 ;; Two pops case is tricky, since pop causes dependency on destination register.
20596 ;; We use two registers if available.
20597 (define_peephole2
20598   [(match_scratch:DI 0 "r")
20599    (match_scratch:DI 1 "r")
20600    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20601               (clobber (reg:CC FLAGS_REG))])]
20602   ""
20603   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20604               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20605    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20606               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20607   "")
20608
20609 (define_peephole2
20610   [(match_scratch:DI 0 "r")
20611    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20612               (clobber (reg:CC FLAGS_REG))])]
20613   "optimize_size"
20614   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20615               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20616    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20617               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20618   "")
20619 \f
20620 ;; Convert imul by three, five and nine into lea
20621 (define_peephole2
20622   [(parallel
20623     [(set (match_operand:SI 0 "register_operand" "")
20624           (mult:SI (match_operand:SI 1 "register_operand" "")
20625                    (match_operand:SI 2 "const_int_operand" "")))
20626      (clobber (reg:CC FLAGS_REG))])]
20627   "INTVAL (operands[2]) == 3
20628    || INTVAL (operands[2]) == 5
20629    || INTVAL (operands[2]) == 9"
20630   [(set (match_dup 0)
20631         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20632                  (match_dup 1)))]
20633   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20634
20635 (define_peephole2
20636   [(parallel
20637     [(set (match_operand:SI 0 "register_operand" "")
20638           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20639                    (match_operand:SI 2 "const_int_operand" "")))
20640      (clobber (reg:CC FLAGS_REG))])]
20641   "!optimize_size
20642    && (INTVAL (operands[2]) == 3
20643        || INTVAL (operands[2]) == 5
20644        || INTVAL (operands[2]) == 9)"
20645   [(set (match_dup 0) (match_dup 1))
20646    (set (match_dup 0)
20647         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20648                  (match_dup 0)))]
20649   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20650
20651 (define_peephole2
20652   [(parallel
20653     [(set (match_operand:DI 0 "register_operand" "")
20654           (mult:DI (match_operand:DI 1 "register_operand" "")
20655                    (match_operand:DI 2 "const_int_operand" "")))
20656      (clobber (reg:CC FLAGS_REG))])]
20657   "TARGET_64BIT
20658    && (INTVAL (operands[2]) == 3
20659        || INTVAL (operands[2]) == 5
20660        || INTVAL (operands[2]) == 9)"
20661   [(set (match_dup 0)
20662         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20663                  (match_dup 1)))]
20664   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20665
20666 (define_peephole2
20667   [(parallel
20668     [(set (match_operand:DI 0 "register_operand" "")
20669           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20670                    (match_operand:DI 2 "const_int_operand" "")))
20671      (clobber (reg:CC FLAGS_REG))])]
20672   "TARGET_64BIT
20673    && !optimize_size
20674    && (INTVAL (operands[2]) == 3
20675        || INTVAL (operands[2]) == 5
20676        || INTVAL (operands[2]) == 9)"
20677   [(set (match_dup 0) (match_dup 1))
20678    (set (match_dup 0)
20679         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20680                  (match_dup 0)))]
20681   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20682
20683 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20684 ;; imul $32bit_imm, reg, reg is direct decoded.
20685 (define_peephole2
20686   [(match_scratch:DI 3 "r")
20687    (parallel [(set (match_operand:DI 0 "register_operand" "")
20688                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20689                             (match_operand:DI 2 "immediate_operand" "")))
20690               (clobber (reg:CC FLAGS_REG))])]
20691   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20692    && !satisfies_constraint_K (operands[2])"
20693   [(set (match_dup 3) (match_dup 1))
20694    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20695               (clobber (reg:CC FLAGS_REG))])]
20696 "")
20697
20698 (define_peephole2
20699   [(match_scratch:SI 3 "r")
20700    (parallel [(set (match_operand:SI 0 "register_operand" "")
20701                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20702                             (match_operand:SI 2 "immediate_operand" "")))
20703               (clobber (reg:CC FLAGS_REG))])]
20704   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20705    && !satisfies_constraint_K (operands[2])"
20706   [(set (match_dup 3) (match_dup 1))
20707    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20708               (clobber (reg:CC FLAGS_REG))])]
20709 "")
20710
20711 (define_peephole2
20712   [(match_scratch:SI 3 "r")
20713    (parallel [(set (match_operand:DI 0 "register_operand" "")
20714                    (zero_extend:DI
20715                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20716                               (match_operand:SI 2 "immediate_operand" ""))))
20717               (clobber (reg:CC FLAGS_REG))])]
20718   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20719    && !satisfies_constraint_K (operands[2])"
20720   [(set (match_dup 3) (match_dup 1))
20721    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20722               (clobber (reg:CC FLAGS_REG))])]
20723 "")
20724
20725 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20726 ;; Convert it into imul reg, reg
20727 ;; It would be better to force assembler to encode instruction using long
20728 ;; immediate, but there is apparently no way to do so.
20729 (define_peephole2
20730   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20731                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20732                             (match_operand:DI 2 "const_int_operand" "")))
20733               (clobber (reg:CC FLAGS_REG))])
20734    (match_scratch:DI 3 "r")]
20735   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20736    && satisfies_constraint_K (operands[2])"
20737   [(set (match_dup 3) (match_dup 2))
20738    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20739               (clobber (reg:CC FLAGS_REG))])]
20740 {
20741   if (!rtx_equal_p (operands[0], operands[1]))
20742     emit_move_insn (operands[0], operands[1]);
20743 })
20744
20745 (define_peephole2
20746   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20747                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20748                             (match_operand:SI 2 "const_int_operand" "")))
20749               (clobber (reg:CC FLAGS_REG))])
20750    (match_scratch:SI 3 "r")]
20751   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20752    && satisfies_constraint_K (operands[2])"
20753   [(set (match_dup 3) (match_dup 2))
20754    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20755               (clobber (reg:CC FLAGS_REG))])]
20756 {
20757   if (!rtx_equal_p (operands[0], operands[1]))
20758     emit_move_insn (operands[0], operands[1]);
20759 })
20760
20761 (define_peephole2
20762   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20763                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20764                             (match_operand:HI 2 "immediate_operand" "")))
20765               (clobber (reg:CC FLAGS_REG))])
20766    (match_scratch:HI 3 "r")]
20767   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size"
20768   [(set (match_dup 3) (match_dup 2))
20769    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20770               (clobber (reg:CC FLAGS_REG))])]
20771 {
20772   if (!rtx_equal_p (operands[0], operands[1]))
20773     emit_move_insn (operands[0], operands[1]);
20774 })
20775
20776 ;; After splitting up read-modify operations, array accesses with memory
20777 ;; operands might end up in form:
20778 ;;  sall    $2, %eax
20779 ;;  movl    4(%esp), %edx
20780 ;;  addl    %edx, %eax
20781 ;; instead of pre-splitting:
20782 ;;  sall    $2, %eax
20783 ;;  addl    4(%esp), %eax
20784 ;; Turn it into:
20785 ;;  movl    4(%esp), %edx
20786 ;;  leal    (%edx,%eax,4), %eax
20787
20788 (define_peephole2
20789   [(parallel [(set (match_operand 0 "register_operand" "")
20790                    (ashift (match_operand 1 "register_operand" "")
20791                            (match_operand 2 "const_int_operand" "")))
20792                (clobber (reg:CC FLAGS_REG))])
20793    (set (match_operand 3 "register_operand")
20794         (match_operand 4 "x86_64_general_operand" ""))
20795    (parallel [(set (match_operand 5 "register_operand" "")
20796                    (plus (match_operand 6 "register_operand" "")
20797                          (match_operand 7 "register_operand" "")))
20798                    (clobber (reg:CC FLAGS_REG))])]
20799   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20800    /* Validate MODE for lea.  */
20801    && ((!TARGET_PARTIAL_REG_STALL
20802         && (GET_MODE (operands[0]) == QImode
20803             || GET_MODE (operands[0]) == HImode))
20804        || GET_MODE (operands[0]) == SImode
20805        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20806    /* We reorder load and the shift.  */
20807    && !rtx_equal_p (operands[1], operands[3])
20808    && !reg_overlap_mentioned_p (operands[0], operands[4])
20809    /* Last PLUS must consist of operand 0 and 3.  */
20810    && !rtx_equal_p (operands[0], operands[3])
20811    && (rtx_equal_p (operands[3], operands[6])
20812        || rtx_equal_p (operands[3], operands[7]))
20813    && (rtx_equal_p (operands[0], operands[6])
20814        || rtx_equal_p (operands[0], operands[7]))
20815    /* The intermediate operand 0 must die or be same as output.  */
20816    && (rtx_equal_p (operands[0], operands[5])
20817        || peep2_reg_dead_p (3, operands[0]))"
20818   [(set (match_dup 3) (match_dup 4))
20819    (set (match_dup 0) (match_dup 1))]
20820 {
20821   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20822   int scale = 1 << INTVAL (operands[2]);
20823   rtx index = gen_lowpart (Pmode, operands[1]);
20824   rtx base = gen_lowpart (Pmode, operands[3]);
20825   rtx dest = gen_lowpart (mode, operands[5]);
20826
20827   operands[1] = gen_rtx_PLUS (Pmode, base,
20828                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20829   if (mode != Pmode)
20830     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20831   operands[0] = dest;
20832 })
20833 \f
20834 ;; Call-value patterns last so that the wildcard operand does not
20835 ;; disrupt insn-recog's switch tables.
20836
20837 (define_insn "*call_value_pop_0"
20838   [(set (match_operand 0 "" "")
20839         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20840               (match_operand:SI 2 "" "")))
20841    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20842                             (match_operand:SI 3 "immediate_operand" "")))]
20843   "!TARGET_64BIT"
20844 {
20845   if (SIBLING_CALL_P (insn))
20846     return "jmp\t%P1";
20847   else
20848     return "call\t%P1";
20849 }
20850   [(set_attr "type" "callv")])
20851
20852 (define_insn "*call_value_pop_1"
20853   [(set (match_operand 0 "" "")
20854         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20855               (match_operand:SI 2 "" "")))
20856    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20857                             (match_operand:SI 3 "immediate_operand" "i")))]
20858   "!TARGET_64BIT"
20859 {
20860   if (constant_call_address_operand (operands[1], Pmode))
20861     {
20862       if (SIBLING_CALL_P (insn))
20863         return "jmp\t%P1";
20864       else
20865         return "call\t%P1";
20866     }
20867   if (SIBLING_CALL_P (insn))
20868     return "jmp\t%A1";
20869   else
20870     return "call\t%A1";
20871 }
20872   [(set_attr "type" "callv")])
20873
20874 (define_insn "*call_value_0"
20875   [(set (match_operand 0 "" "")
20876         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20877               (match_operand:SI 2 "" "")))]
20878   "!TARGET_64BIT"
20879 {
20880   if (SIBLING_CALL_P (insn))
20881     return "jmp\t%P1";
20882   else
20883     return "call\t%P1";
20884 }
20885   [(set_attr "type" "callv")])
20886
20887 (define_insn "*call_value_0_rex64"
20888   [(set (match_operand 0 "" "")
20889         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20890               (match_operand:DI 2 "const_int_operand" "")))]
20891   "TARGET_64BIT"
20892 {
20893   if (SIBLING_CALL_P (insn))
20894     return "jmp\t%P1";
20895   else
20896     return "call\t%P1";
20897 }
20898   [(set_attr "type" "callv")])
20899
20900 (define_insn "*call_value_1"
20901   [(set (match_operand 0 "" "")
20902         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20903               (match_operand:SI 2 "" "")))]
20904   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20905 {
20906   if (constant_call_address_operand (operands[1], Pmode))
20907     return "call\t%P1";
20908   return "call\t%A1";
20909 }
20910   [(set_attr "type" "callv")])
20911
20912 (define_insn "*sibcall_value_1"
20913   [(set (match_operand 0 "" "")
20914         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20915               (match_operand:SI 2 "" "")))]
20916   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20917 {
20918   if (constant_call_address_operand (operands[1], Pmode))
20919     return "jmp\t%P1";
20920   return "jmp\t%A1";
20921 }
20922   [(set_attr "type" "callv")])
20923
20924 (define_insn "*call_value_1_rex64"
20925   [(set (match_operand 0 "" "")
20926         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20927               (match_operand:DI 2 "" "")))]
20928   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20929 {
20930   if (constant_call_address_operand (operands[1], Pmode))
20931     return "call\t%P1";
20932   return "call\t%A1";
20933 }
20934   [(set_attr "type" "callv")])
20935
20936 (define_insn "*sibcall_value_1_rex64"
20937   [(set (match_operand 0 "" "")
20938         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20939               (match_operand:DI 2 "" "")))]
20940   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20941   "jmp\t%P1"
20942   [(set_attr "type" "callv")])
20943
20944 (define_insn "*sibcall_value_1_rex64_v"
20945   [(set (match_operand 0 "" "")
20946         (call (mem:QI (reg:DI R11_REG))
20947               (match_operand:DI 1 "" "")))]
20948   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20949   "jmp\t*%%r11"
20950   [(set_attr "type" "callv")])
20951 \f
20952 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20953 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20954 ;; caught for use by garbage collectors and the like.  Using an insn that
20955 ;; maps to SIGILL makes it more likely the program will rightfully die.
20956 ;; Keeping with tradition, "6" is in honor of #UD.
20957 (define_insn "trap"
20958   [(trap_if (const_int 1) (const_int 6))]
20959   ""
20960   { return ASM_SHORT "0x0b0f"; }
20961   [(set_attr "length" "2")])
20962
20963 (define_expand "sse_prologue_save"
20964   [(parallel [(set (match_operand:BLK 0 "" "")
20965                    (unspec:BLK [(reg:DI 21)
20966                                 (reg:DI 22)
20967                                 (reg:DI 23)
20968                                 (reg:DI 24)
20969                                 (reg:DI 25)
20970                                 (reg:DI 26)
20971                                 (reg:DI 27)
20972                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20973               (use (match_operand:DI 1 "register_operand" ""))
20974               (use (match_operand:DI 2 "immediate_operand" ""))
20975               (use (label_ref:DI (match_operand 3 "" "")))])]
20976   "TARGET_64BIT"
20977   "")
20978
20979 (define_insn "*sse_prologue_save_insn"
20980   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20981                           (match_operand:DI 4 "const_int_operand" "n")))
20982         (unspec:BLK [(reg:DI 21)
20983                      (reg:DI 22)
20984                      (reg:DI 23)
20985                      (reg:DI 24)
20986                      (reg:DI 25)
20987                      (reg:DI 26)
20988                      (reg:DI 27)
20989                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20990    (use (match_operand:DI 1 "register_operand" "r"))
20991    (use (match_operand:DI 2 "const_int_operand" "i"))
20992    (use (label_ref:DI (match_operand 3 "" "X")))]
20993   "TARGET_64BIT
20994    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20995    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20996   "*
20997 {
20998   int i;
20999   operands[0] = gen_rtx_MEM (Pmode,
21000                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21001   output_asm_insn (\"jmp\\t%A1\", operands);
21002   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21003     {
21004       operands[4] = adjust_address (operands[0], DImode, i*16);
21005       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21006       PUT_MODE (operands[4], TImode);
21007       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21008         output_asm_insn (\"rex\", operands);
21009       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21010     }
21011   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21012                              CODE_LABEL_NUMBER (operands[3]));
21013   return \"\";
21014 }
21015   "
21016   [(set_attr "type" "other")
21017    (set_attr "length_immediate" "0")
21018    (set_attr "length_address" "0")
21019    (set_attr "length" "135")
21020    (set_attr "memory" "store")
21021    (set_attr "modrm" "0")
21022    (set_attr "mode" "DI")])
21023
21024 (define_expand "prefetch"
21025   [(prefetch (match_operand 0 "address_operand" "")
21026              (match_operand:SI 1 "const_int_operand" "")
21027              (match_operand:SI 2 "const_int_operand" ""))]
21028   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21029 {
21030   int rw = INTVAL (operands[1]);
21031   int locality = INTVAL (operands[2]);
21032
21033   gcc_assert (rw == 0 || rw == 1);
21034   gcc_assert (locality >= 0 && locality <= 3);
21035   gcc_assert (GET_MODE (operands[0]) == Pmode
21036               || GET_MODE (operands[0]) == VOIDmode);
21037
21038   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21039      supported by SSE counterpart or the SSE prefetch is not available
21040      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21041      of locality.  */
21042   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21043     operands[2] = GEN_INT (3);
21044   else
21045     operands[1] = const0_rtx;
21046 })
21047
21048 (define_insn "*prefetch_sse"
21049   [(prefetch (match_operand:SI 0 "address_operand" "p")
21050              (const_int 0)
21051              (match_operand:SI 1 "const_int_operand" ""))]
21052   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21053 {
21054   static const char * const patterns[4] = {
21055    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21056   };
21057
21058   int locality = INTVAL (operands[1]);
21059   gcc_assert (locality >= 0 && locality <= 3);
21060
21061   return patterns[locality];
21062 }
21063   [(set_attr "type" "sse")
21064    (set_attr "memory" "none")])
21065
21066 (define_insn "*prefetch_sse_rex"
21067   [(prefetch (match_operand:DI 0 "address_operand" "p")
21068              (const_int 0)
21069              (match_operand:SI 1 "const_int_operand" ""))]
21070   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21071 {
21072   static const char * const patterns[4] = {
21073    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21074   };
21075
21076   int locality = INTVAL (operands[1]);
21077   gcc_assert (locality >= 0 && locality <= 3);
21078
21079   return patterns[locality];
21080 }
21081   [(set_attr "type" "sse")
21082    (set_attr "memory" "none")])
21083
21084 (define_insn "*prefetch_3dnow"
21085   [(prefetch (match_operand:SI 0 "address_operand" "p")
21086              (match_operand:SI 1 "const_int_operand" "n")
21087              (const_int 3))]
21088   "TARGET_3DNOW && !TARGET_64BIT"
21089 {
21090   if (INTVAL (operands[1]) == 0)
21091     return "prefetch\t%a0";
21092   else
21093     return "prefetchw\t%a0";
21094 }
21095   [(set_attr "type" "mmx")
21096    (set_attr "memory" "none")])
21097
21098 (define_insn "*prefetch_3dnow_rex"
21099   [(prefetch (match_operand:DI 0 "address_operand" "p")
21100              (match_operand:SI 1 "const_int_operand" "n")
21101              (const_int 3))]
21102   "TARGET_3DNOW && TARGET_64BIT"
21103 {
21104   if (INTVAL (operands[1]) == 0)
21105     return "prefetch\t%a0";
21106   else
21107     return "prefetchw\t%a0";
21108 }
21109   [(set_attr "type" "mmx")
21110    (set_attr "memory" "none")])
21111
21112 (define_expand "stack_protect_set"
21113   [(match_operand 0 "memory_operand" "")
21114    (match_operand 1 "memory_operand" "")]
21115   ""
21116 {
21117 #ifdef TARGET_THREAD_SSP_OFFSET
21118   if (TARGET_64BIT)
21119     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21120                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21121   else
21122     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21123                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21124 #else
21125   if (TARGET_64BIT)
21126     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21127   else
21128     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21129 #endif
21130   DONE;
21131 })
21132
21133 (define_insn "stack_protect_set_si"
21134   [(set (match_operand:SI 0 "memory_operand" "=m")
21135         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21136    (set (match_scratch:SI 2 "=&r") (const_int 0))
21137    (clobber (reg:CC FLAGS_REG))]
21138   ""
21139   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21140   [(set_attr "type" "multi")])
21141
21142 (define_insn "stack_protect_set_di"
21143   [(set (match_operand:DI 0 "memory_operand" "=m")
21144         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21145    (set (match_scratch:DI 2 "=&r") (const_int 0))
21146    (clobber (reg:CC FLAGS_REG))]
21147   "TARGET_64BIT"
21148   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21149   [(set_attr "type" "multi")])
21150
21151 (define_insn "stack_tls_protect_set_si"
21152   [(set (match_operand:SI 0 "memory_operand" "=m")
21153         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21154    (set (match_scratch:SI 2 "=&r") (const_int 0))
21155    (clobber (reg:CC FLAGS_REG))]
21156   ""
21157   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21158   [(set_attr "type" "multi")])
21159
21160 (define_insn "stack_tls_protect_set_di"
21161   [(set (match_operand:DI 0 "memory_operand" "=m")
21162         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21163    (set (match_scratch:DI 2 "=&r") (const_int 0))
21164    (clobber (reg:CC FLAGS_REG))]
21165   "TARGET_64BIT"
21166   {
21167      /* The kernel uses a different segment register for performance reasons; a
21168         system call would not have to trash the userspace segment register,
21169         which would be expensive */
21170      if (ix86_cmodel != CM_KERNEL)
21171         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21172      else
21173         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21174   }
21175   [(set_attr "type" "multi")])
21176
21177 (define_expand "stack_protect_test"
21178   [(match_operand 0 "memory_operand" "")
21179    (match_operand 1 "memory_operand" "")
21180    (match_operand 2 "" "")]
21181   ""
21182 {
21183   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21184   ix86_compare_op0 = operands[0];
21185   ix86_compare_op1 = operands[1];
21186   ix86_compare_emitted = flags;
21187
21188 #ifdef TARGET_THREAD_SSP_OFFSET
21189   if (TARGET_64BIT)
21190     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21191                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21192   else
21193     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21194                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21195 #else
21196   if (TARGET_64BIT)
21197     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21198   else
21199     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21200 #endif
21201   emit_jump_insn (gen_beq (operands[2]));
21202   DONE;
21203 })
21204
21205 (define_insn "stack_protect_test_si"
21206   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21207         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21208                      (match_operand:SI 2 "memory_operand" "m")]
21209                     UNSPEC_SP_TEST))
21210    (clobber (match_scratch:SI 3 "=&r"))]
21211   ""
21212   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21213   [(set_attr "type" "multi")])
21214
21215 (define_insn "stack_protect_test_di"
21216   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21217         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21218                      (match_operand:DI 2 "memory_operand" "m")]
21219                     UNSPEC_SP_TEST))
21220    (clobber (match_scratch:DI 3 "=&r"))]
21221   "TARGET_64BIT"
21222   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21223   [(set_attr "type" "multi")])
21224
21225 (define_insn "stack_tls_protect_test_si"
21226   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21227         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21228                      (match_operand:SI 2 "const_int_operand" "i")]
21229                     UNSPEC_SP_TLS_TEST))
21230    (clobber (match_scratch:SI 3 "=r"))]
21231   ""
21232   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21233   [(set_attr "type" "multi")])
21234
21235 (define_insn "stack_tls_protect_test_di"
21236   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21237         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21238                      (match_operand:DI 2 "const_int_operand" "i")]
21239                     UNSPEC_SP_TLS_TEST))
21240    (clobber (match_scratch:DI 3 "=r"))]
21241   "TARGET_64BIT"
21242   {
21243      /* The kernel uses a different segment register for performance reasons; a
21244         system call would not have to trash the userspace segment register,
21245         which would be expensive */
21246      if (ix86_cmodel != CM_KERNEL)
21247         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21248      else
21249         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21250   }
21251   [(set_attr "type" "multi")])
21252
21253 (include "mmx.md")
21254 (include "sse.md")
21255 (include "sync.md")