OSDN Git Service

* config/i386/i386.md: Use REG_P, MEM_P, CONST_INT_P, LABEL_P,
[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 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
64
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
69    (UNSPEC_REG_SAVE             14)
70    (UNSPEC_DEF_CFA              15)
71
72    ; TLS support
73    (UNSPEC_TP                   16)
74    (UNSPEC_TLS_GD               17)
75    (UNSPEC_TLS_LD_BASE          18)
76    (UNSPEC_TLSDESC              19)
77
78    ; Other random patterns
79    (UNSPEC_SCAS                 20)
80    (UNSPEC_FNSTSW               21)
81    (UNSPEC_SAHF                 22)
82    (UNSPEC_FSTCW                23)
83    (UNSPEC_ADD_CARRY            24)
84    (UNSPEC_FLDCW                25)
85    (UNSPEC_REP                  26)
86    (UNSPEC_EH_RETURN            27)
87    (UNSPEC_LD_MPIC              28)     ; load_macho_picbase
88    (UNSPEC_TRUNC_NOOP           29)
89
90    ; For SSE/MMX support:
91    (UNSPEC_FIX_NOTRUNC          30)
92    (UNSPEC_MASKMOV              31)
93    (UNSPEC_MOVMSK               32)
94    (UNSPEC_MOVNT                33)
95    (UNSPEC_MOVU                 34)
96    (UNSPEC_RCP                  35)
97    (UNSPEC_RSQRT                36)
98    (UNSPEC_SFENCE               37)
99    (UNSPEC_NOP                  38)     ; prevents combiner cleverness
100    (UNSPEC_PFRCP                39)
101    (UNSPEC_PFRCPIT1             40)
102    (UNSPEC_PFRCPIT2             41)
103    (UNSPEC_PFRSQRT              42)
104    (UNSPEC_PFRSQIT1             43)
105    (UNSPEC_MFENCE               44)
106    (UNSPEC_LFENCE               45)
107    (UNSPEC_PSADBW               46)
108    (UNSPEC_LDDQU                47)
109
110    ; Generic math support
111    (UNSPEC_COPYSIGN             50)
112    (UNSPEC_IEEE_MIN             51)     ; not commutative
113    (UNSPEC_IEEE_MAX             52)     ; not commutative
114
115    ; x87 Floating point
116    (UNSPEC_SIN                  60)
117    (UNSPEC_COS                  61)
118    (UNSPEC_FPATAN               62)
119    (UNSPEC_FYL2X                63)
120    (UNSPEC_FYL2XP1              64)
121    (UNSPEC_FRNDINT              65)
122    (UNSPEC_FIST                 66)
123    (UNSPEC_F2XM1                67)
124    (UNSPEC_TAN                  68)
125
126    ; x87 Rounding
127    (UNSPEC_FRNDINT_FLOOR        70)
128    (UNSPEC_FRNDINT_CEIL         71)
129    (UNSPEC_FRNDINT_TRUNC        72)
130    (UNSPEC_FRNDINT_MASK_PM      73)
131    (UNSPEC_FIST_FLOOR           74)
132    (UNSPEC_FIST_CEIL            75)
133
134    ; x87 Double output FP
135    (UNSPEC_SINCOS_COS           80)
136    (UNSPEC_SINCOS_SIN           81)
137    (UNSPEC_XTRACT_FRACT         84)
138    (UNSPEC_XTRACT_EXP           85)
139    (UNSPEC_FSCALE_FRACT         86)
140    (UNSPEC_FSCALE_EXP           87)
141    (UNSPEC_FPREM_F              88)
142    (UNSPEC_FPREM_U              89)
143    (UNSPEC_FPREM1_F             90)
144    (UNSPEC_FPREM1_U             91)
145
146    ; SSP patterns
147    (UNSPEC_SP_SET               100)
148    (UNSPEC_SP_TEST              101)
149    (UNSPEC_SP_TLS_SET           102)
150    (UNSPEC_SP_TLS_TEST          103)
151
152    ; SSSE3
153    (UNSPEC_PSHUFB               120)
154    (UNSPEC_PSIGN                121)
155    (UNSPEC_PALIGNR              122)
156   ])
157
158 (define_constants
159   [(UNSPECV_BLOCKAGE            0)
160    (UNSPECV_STACK_PROBE         1)
161    (UNSPECV_EMMS                2)
162    (UNSPECV_LDMXCSR             3)
163    (UNSPECV_STMXCSR             4)
164    (UNSPECV_FEMMS               5)
165    (UNSPECV_CLFLUSH             6)
166    (UNSPECV_ALIGN               7)
167    (UNSPECV_MONITOR             8)
168    (UNSPECV_MWAIT               9)
169    (UNSPECV_CMPXCHG_1           10)
170    (UNSPECV_CMPXCHG_2           11)
171    (UNSPECV_XCHG                12)
172    (UNSPECV_LOCK                13)
173   ])
174
175 ;; Registers by name.
176 (define_constants
177   [(BP_REG                       6)
178    (SP_REG                       7)
179    (FLAGS_REG                   17)
180    (FPSR_REG                    18)
181    (FPCR_REG                    19)
182    (R10_REG                     39)
183    (R11_REG                     40)
184   ])
185
186 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
187 ;; from i386.c.
188
189 ;; In C guard expressions, put expressions which may be compile-time
190 ;; constants first.  This allows for better optimization.  For
191 ;; example, write "TARGET_64BIT && reload_completed", not
192 ;; "reload_completed && TARGET_64BIT".
193
194 \f
195 ;; Processor type.  This attribute must exactly match the processor_type
196 ;; enumeration in i386.h.
197 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,nocona,core2,generic32,generic64"
198   (const (symbol_ref "ix86_tune")))
199
200 ;; A basic instruction type.  Refinements due to arguments to be
201 ;; provided in other attributes.
202 (define_attr "type"
203   "other,multi,
204    alu,alu1,negnot,imov,imovx,lea,
205    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
206    icmp,test,ibr,setcc,icmov,
207    push,pop,call,callv,leave,
208    str,
209    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
210    sselog,sselog1,sseiadd,sseishft,sseimul,
211    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
212    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
213   (const_string "other"))
214
215 ;; Main data type used by the insn
216 (define_attr "mode"
217   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
218   (const_string "unknown"))
219
220 ;; The CPU unit operations uses.
221 (define_attr "unit" "integer,i387,sse,mmx,unknown"
222   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
223            (const_string "i387")
224          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
225                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
226            (const_string "sse")
227          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
228            (const_string "mmx")
229          (eq_attr "type" "other")
230            (const_string "unknown")]
231          (const_string "integer")))
232
233 ;; The (bounding maximum) length of an instruction immediate.
234 (define_attr "length_immediate" ""
235   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave")
236            (const_int 0)
237          (eq_attr "unit" "i387,sse,mmx")
238            (const_int 0)
239          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
240                           imul,icmp,push,pop")
241            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
242          (eq_attr "type" "imov,test")
243            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
244          (eq_attr "type" "call")
245            (if_then_else (match_operand 0 "constant_call_address_operand" "")
246              (const_int 4)
247              (const_int 0))
248          (eq_attr "type" "callv")
249            (if_then_else (match_operand 1 "constant_call_address_operand" "")
250              (const_int 4)
251              (const_int 0))
252          ;; We don't know the size before shorten_branches.  Expect
253          ;; the instruction to fit for better scheduling.
254          (eq_attr "type" "ibr")
255            (const_int 1)
256          ]
257          (symbol_ref "/* Update immediate_length and other attributes! */
258                       gcc_unreachable (),1")))
259
260 ;; The (bounding maximum) length of an instruction address.
261 (define_attr "length_address" ""
262   (cond [(eq_attr "type" "str,other,multi,fxch")
263            (const_int 0)
264          (and (eq_attr "type" "call")
265               (match_operand 0 "constant_call_address_operand" ""))
266              (const_int 0)
267          (and (eq_attr "type" "callv")
268               (match_operand 1 "constant_call_address_operand" ""))
269              (const_int 0)
270          ]
271          (symbol_ref "ix86_attr_length_address_default (insn)")))
272
273 ;; Set when length prefix is used.
274 (define_attr "prefix_data16" ""
275   (if_then_else (ior (eq_attr "mode" "HI")
276                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
277     (const_int 1)
278     (const_int 0)))
279
280 ;; Set when string REP prefix is used.
281 (define_attr "prefix_rep" ""
282   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
283     (const_int 1)
284     (const_int 0)))
285
286 ;; Set when 0f opcode prefix is used.
287 (define_attr "prefix_0f" ""
288   (if_then_else
289     (ior (eq_attr "type" "imovx,setcc,icmov")
290          (eq_attr "unit" "sse,mmx"))
291     (const_int 1)
292     (const_int 0)))
293
294 ;; Set when REX opcode prefix is used.
295 (define_attr "prefix_rex" ""
296   (cond [(and (eq_attr "mode" "DI")
297               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
298            (const_int 1)
299          (and (eq_attr "mode" "QI")
300               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
301                   (const_int 0)))
302            (const_int 1)
303          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
304              (const_int 0))
305            (const_int 1)
306         ]
307         (const_int 0)))
308
309 ;; Set when modrm byte is used.
310 (define_attr "modrm" ""
311   (cond [(eq_attr "type" "str,leave")
312            (const_int 0)
313          (eq_attr "unit" "i387")
314            (const_int 0)
315          (and (eq_attr "type" "incdec")
316               (ior (match_operand:SI 1 "register_operand" "")
317                    (match_operand:HI 1 "register_operand" "")))
318            (const_int 0)
319          (and (eq_attr "type" "push")
320               (not (match_operand 1 "memory_operand" "")))
321            (const_int 0)
322          (and (eq_attr "type" "pop")
323               (not (match_operand 0 "memory_operand" "")))
324            (const_int 0)
325          (and (eq_attr "type" "imov")
326               (ior (and (match_operand 0 "register_operand" "")
327                         (match_operand 1 "immediate_operand" ""))
328                    (ior (and (match_operand 0 "ax_reg_operand" "")
329                              (match_operand 1 "memory_displacement_only_operand" ""))
330                         (and (match_operand 0 "memory_displacement_only_operand" "")
331                              (match_operand 1 "ax_reg_operand" "")))))
332            (const_int 0)
333          (and (eq_attr "type" "call")
334               (match_operand 0 "constant_call_address_operand" ""))
335              (const_int 0)
336          (and (eq_attr "type" "callv")
337               (match_operand 1 "constant_call_address_operand" ""))
338              (const_int 0)
339          ]
340          (const_int 1)))
341
342 ;; The (bounding maximum) length of an instruction in bytes.
343 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
344 ;; Later we may want to split them and compute proper length as for
345 ;; other insns.
346 (define_attr "length" ""
347   (cond [(eq_attr "type" "other,multi,fistp,frndint")
348            (const_int 16)
349          (eq_attr "type" "fcmp")
350            (const_int 4)
351          (eq_attr "unit" "i387")
352            (plus (const_int 2)
353                  (plus (attr "prefix_data16")
354                        (attr "length_address")))]
355          (plus (plus (attr "modrm")
356                      (plus (attr "prefix_0f")
357                            (plus (attr "prefix_rex")
358                                  (const_int 1))))
359                (plus (attr "prefix_rep")
360                      (plus (attr "prefix_data16")
361                            (plus (attr "length_immediate")
362                                  (attr "length_address")))))))
363
364 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
365 ;; `store' if there is a simple memory reference therein, or `unknown'
366 ;; if the instruction is complex.
367
368 (define_attr "memory" "none,load,store,both,unknown"
369   (cond [(eq_attr "type" "other,multi,str")
370            (const_string "unknown")
371          (eq_attr "type" "lea,fcmov,fpspc")
372            (const_string "none")
373          (eq_attr "type" "fistp,leave")
374            (const_string "both")
375          (eq_attr "type" "frndint")
376            (const_string "load")
377          (eq_attr "type" "push")
378            (if_then_else (match_operand 1 "memory_operand" "")
379              (const_string "both")
380              (const_string "store"))
381          (eq_attr "type" "pop")
382            (if_then_else (match_operand 0 "memory_operand" "")
383              (const_string "both")
384              (const_string "load"))
385          (eq_attr "type" "setcc")
386            (if_then_else (match_operand 0 "memory_operand" "")
387              (const_string "store")
388              (const_string "none"))
389          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
390            (if_then_else (ior (match_operand 0 "memory_operand" "")
391                               (match_operand 1 "memory_operand" ""))
392              (const_string "load")
393              (const_string "none"))
394          (eq_attr "type" "ibr")
395            (if_then_else (match_operand 0 "memory_operand" "")
396              (const_string "load")
397              (const_string "none"))
398          (eq_attr "type" "call")
399            (if_then_else (match_operand 0 "constant_call_address_operand" "")
400              (const_string "none")
401              (const_string "load"))
402          (eq_attr "type" "callv")
403            (if_then_else (match_operand 1 "constant_call_address_operand" "")
404              (const_string "none")
405              (const_string "load"))
406          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
407               (match_operand 1 "memory_operand" ""))
408            (const_string "both")
409          (and (match_operand 0 "memory_operand" "")
410               (match_operand 1 "memory_operand" ""))
411            (const_string "both")
412          (match_operand 0 "memory_operand" "")
413            (const_string "store")
414          (match_operand 1 "memory_operand" "")
415            (const_string "load")
416          (and (eq_attr "type"
417                  "!alu1,negnot,ishift1,
418                    imov,imovx,icmp,test,
419                    fmov,fcmp,fsgn,
420                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
421                    mmx,mmxmov,mmxcmp,mmxcvt")
422               (match_operand 2 "memory_operand" ""))
423            (const_string "load")
424          (and (eq_attr "type" "icmov")
425               (match_operand 3 "memory_operand" ""))
426            (const_string "load")
427         ]
428         (const_string "none")))
429
430 ;; Indicates if an instruction has both an immediate and a displacement.
431
432 (define_attr "imm_disp" "false,true,unknown"
433   (cond [(eq_attr "type" "other,multi")
434            (const_string "unknown")
435          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
436               (and (match_operand 0 "memory_displacement_operand" "")
437                    (match_operand 1 "immediate_operand" "")))
438            (const_string "true")
439          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
440               (and (match_operand 0 "memory_displacement_operand" "")
441                    (match_operand 2 "immediate_operand" "")))
442            (const_string "true")
443         ]
444         (const_string "false")))
445
446 ;; Indicates if an FP operation has an integer source.
447
448 (define_attr "fp_int_src" "false,true"
449   (const_string "false"))
450
451 ;; Defines rounding mode of an FP operation.
452
453 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
454   (const_string "any"))
455
456 ;; Describe a user's asm statement.
457 (define_asm_attributes
458   [(set_attr "length" "128")
459    (set_attr "type" "multi")])
460
461 ;; All x87 floating point modes
462 (define_mode_macro X87MODEF [SF DF XF])
463
464 ;; x87 SFmode and DFMode floating point modes
465 (define_mode_macro X87MODEF12 [SF DF])
466
467 ;; All integer modes handled by x87 fisttp operator.
468 (define_mode_macro X87MODEI [HI SI DI])
469
470 ;; All integer modes handled by integer x87 operators.
471 (define_mode_macro X87MODEI12 [HI SI])
472
473 ;; All SSE floating point modes
474 (define_mode_macro SSEMODEF [SF DF])
475
476 ;; All integer modes handled by SSE cvtts?2si* operators.
477 (define_mode_macro SSEMODEI24 [SI DI])
478
479 ;; SSE asm suffix for floating point modes
480 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
481
482 \f
483 ;; Scheduling descriptions
484
485 (include "pentium.md")
486 (include "ppro.md")
487 (include "k6.md")
488 (include "athlon.md")
489 (include "geode.md")
490
491 \f
492 ;; Operand and operator predicates and constraints
493
494 (include "predicates.md")
495 (include "constraints.md")
496
497 \f
498 ;; Compare instructions.
499
500 ;; All compare insns have expanders that save the operands away without
501 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
502 ;; after the cmp) will actually emit the cmpM.
503
504 (define_expand "cmpti"
505   [(set (reg:CC FLAGS_REG)
506         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
507                     (match_operand:TI 1 "x86_64_general_operand" "")))]
508   "TARGET_64BIT"
509 {
510   if (MEM_P (operands[0]) && MEM_P (operands[1]))
511     operands[0] = force_reg (TImode, operands[0]);
512   ix86_compare_op0 = operands[0];
513   ix86_compare_op1 = operands[1];
514   DONE;
515 })
516
517 (define_expand "cmpdi"
518   [(set (reg:CC FLAGS_REG)
519         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
520                     (match_operand:DI 1 "x86_64_general_operand" "")))]
521   ""
522 {
523   if (MEM_P (operands[0]) && MEM_P (operands[1]))
524     operands[0] = force_reg (DImode, operands[0]);
525   ix86_compare_op0 = operands[0];
526   ix86_compare_op1 = operands[1];
527   DONE;
528 })
529
530 (define_expand "cmpsi"
531   [(set (reg:CC FLAGS_REG)
532         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
533                     (match_operand:SI 1 "general_operand" "")))]
534   ""
535 {
536   if (MEM_P (operands[0]) && MEM_P (operands[1]))
537     operands[0] = force_reg (SImode, operands[0]);
538   ix86_compare_op0 = operands[0];
539   ix86_compare_op1 = operands[1];
540   DONE;
541 })
542
543 (define_expand "cmphi"
544   [(set (reg:CC FLAGS_REG)
545         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
546                     (match_operand:HI 1 "general_operand" "")))]
547   ""
548 {
549   if (MEM_P (operands[0]) && MEM_P (operands[1]))
550     operands[0] = force_reg (HImode, operands[0]);
551   ix86_compare_op0 = operands[0];
552   ix86_compare_op1 = operands[1];
553   DONE;
554 })
555
556 (define_expand "cmpqi"
557   [(set (reg:CC FLAGS_REG)
558         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
559                     (match_operand:QI 1 "general_operand" "")))]
560   "TARGET_QIMODE_MATH"
561 {
562   if (MEM_P (operands[0]) && MEM_P (operands[1]))
563     operands[0] = force_reg (QImode, operands[0]);
564   ix86_compare_op0 = operands[0];
565   ix86_compare_op1 = operands[1];
566   DONE;
567 })
568
569 (define_insn "cmpdi_ccno_1_rex64"
570   [(set (reg FLAGS_REG)
571         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
572                  (match_operand:DI 1 "const0_operand" "n,n")))]
573   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
574   "@
575    test{q}\t{%0, %0|%0, %0}
576    cmp{q}\t{%1, %0|%0, %1}"
577   [(set_attr "type" "test,icmp")
578    (set_attr "length_immediate" "0,1")
579    (set_attr "mode" "DI")])
580
581 (define_insn "*cmpdi_minus_1_rex64"
582   [(set (reg FLAGS_REG)
583         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
584                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
585                  (const_int 0)))]
586   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
587   "cmp{q}\t{%1, %0|%0, %1}"
588   [(set_attr "type" "icmp")
589    (set_attr "mode" "DI")])
590
591 (define_expand "cmpdi_1_rex64"
592   [(set (reg:CC FLAGS_REG)
593         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
594                     (match_operand:DI 1 "general_operand" "")))]
595   "TARGET_64BIT"
596   "")
597
598 (define_insn "cmpdi_1_insn_rex64"
599   [(set (reg FLAGS_REG)
600         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
601                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
602   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
603   "cmp{q}\t{%1, %0|%0, %1}"
604   [(set_attr "type" "icmp")
605    (set_attr "mode" "DI")])
606
607
608 (define_insn "*cmpsi_ccno_1"
609   [(set (reg FLAGS_REG)
610         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
611                  (match_operand:SI 1 "const0_operand" "n,n")))]
612   "ix86_match_ccmode (insn, CCNOmode)"
613   "@
614    test{l}\t{%0, %0|%0, %0}
615    cmp{l}\t{%1, %0|%0, %1}"
616   [(set_attr "type" "test,icmp")
617    (set_attr "length_immediate" "0,1")
618    (set_attr "mode" "SI")])
619
620 (define_insn "*cmpsi_minus_1"
621   [(set (reg FLAGS_REG)
622         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
623                            (match_operand:SI 1 "general_operand" "ri,mr"))
624                  (const_int 0)))]
625   "ix86_match_ccmode (insn, CCGOCmode)"
626   "cmp{l}\t{%1, %0|%0, %1}"
627   [(set_attr "type" "icmp")
628    (set_attr "mode" "SI")])
629
630 (define_expand "cmpsi_1"
631   [(set (reg:CC FLAGS_REG)
632         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
633                     (match_operand:SI 1 "general_operand" "ri,mr")))]
634   ""
635   "")
636
637 (define_insn "*cmpsi_1_insn"
638   [(set (reg FLAGS_REG)
639         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
640                  (match_operand:SI 1 "general_operand" "ri,mr")))]
641   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
642     && ix86_match_ccmode (insn, CCmode)"
643   "cmp{l}\t{%1, %0|%0, %1}"
644   [(set_attr "type" "icmp")
645    (set_attr "mode" "SI")])
646
647 (define_insn "*cmphi_ccno_1"
648   [(set (reg FLAGS_REG)
649         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
650                  (match_operand:HI 1 "const0_operand" "n,n")))]
651   "ix86_match_ccmode (insn, CCNOmode)"
652   "@
653    test{w}\t{%0, %0|%0, %0}
654    cmp{w}\t{%1, %0|%0, %1}"
655   [(set_attr "type" "test,icmp")
656    (set_attr "length_immediate" "0,1")
657    (set_attr "mode" "HI")])
658
659 (define_insn "*cmphi_minus_1"
660   [(set (reg FLAGS_REG)
661         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
662                            (match_operand:HI 1 "general_operand" "ri,mr"))
663                  (const_int 0)))]
664   "ix86_match_ccmode (insn, CCGOCmode)"
665   "cmp{w}\t{%1, %0|%0, %1}"
666   [(set_attr "type" "icmp")
667    (set_attr "mode" "HI")])
668
669 (define_insn "*cmphi_1"
670   [(set (reg FLAGS_REG)
671         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
672                  (match_operand:HI 1 "general_operand" "ri,mr")))]
673   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
674    && ix86_match_ccmode (insn, CCmode)"
675   "cmp{w}\t{%1, %0|%0, %1}"
676   [(set_attr "type" "icmp")
677    (set_attr "mode" "HI")])
678
679 (define_insn "*cmpqi_ccno_1"
680   [(set (reg FLAGS_REG)
681         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
682                  (match_operand:QI 1 "const0_operand" "n,n")))]
683   "ix86_match_ccmode (insn, CCNOmode)"
684   "@
685    test{b}\t{%0, %0|%0, %0}
686    cmp{b}\t{$0, %0|%0, 0}"
687   [(set_attr "type" "test,icmp")
688    (set_attr "length_immediate" "0,1")
689    (set_attr "mode" "QI")])
690
691 (define_insn "*cmpqi_1"
692   [(set (reg FLAGS_REG)
693         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
694                  (match_operand:QI 1 "general_operand" "qi,mq")))]
695   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
696     && ix86_match_ccmode (insn, CCmode)"
697   "cmp{b}\t{%1, %0|%0, %1}"
698   [(set_attr "type" "icmp")
699    (set_attr "mode" "QI")])
700
701 (define_insn "*cmpqi_minus_1"
702   [(set (reg FLAGS_REG)
703         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
704                            (match_operand:QI 1 "general_operand" "qi,mq"))
705                  (const_int 0)))]
706   "ix86_match_ccmode (insn, CCGOCmode)"
707   "cmp{b}\t{%1, %0|%0, %1}"
708   [(set_attr "type" "icmp")
709    (set_attr "mode" "QI")])
710
711 (define_insn "*cmpqi_ext_1"
712   [(set (reg FLAGS_REG)
713         (compare
714           (match_operand:QI 0 "general_operand" "Qm")
715           (subreg:QI
716             (zero_extract:SI
717               (match_operand 1 "ext_register_operand" "Q")
718               (const_int 8)
719               (const_int 8)) 0)))]
720   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
721   "cmp{b}\t{%h1, %0|%0, %h1}"
722   [(set_attr "type" "icmp")
723    (set_attr "mode" "QI")])
724
725 (define_insn "*cmpqi_ext_1_rex64"
726   [(set (reg FLAGS_REG)
727         (compare
728           (match_operand:QI 0 "register_operand" "Q")
729           (subreg:QI
730             (zero_extract:SI
731               (match_operand 1 "ext_register_operand" "Q")
732               (const_int 8)
733               (const_int 8)) 0)))]
734   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
735   "cmp{b}\t{%h1, %0|%0, %h1}"
736   [(set_attr "type" "icmp")
737    (set_attr "mode" "QI")])
738
739 (define_insn "*cmpqi_ext_2"
740   [(set (reg FLAGS_REG)
741         (compare
742           (subreg:QI
743             (zero_extract:SI
744               (match_operand 0 "ext_register_operand" "Q")
745               (const_int 8)
746               (const_int 8)) 0)
747           (match_operand:QI 1 "const0_operand" "n")))]
748   "ix86_match_ccmode (insn, CCNOmode)"
749   "test{b}\t%h0, %h0"
750   [(set_attr "type" "test")
751    (set_attr "length_immediate" "0")
752    (set_attr "mode" "QI")])
753
754 (define_expand "cmpqi_ext_3"
755   [(set (reg:CC FLAGS_REG)
756         (compare:CC
757           (subreg:QI
758             (zero_extract:SI
759               (match_operand 0 "ext_register_operand" "")
760               (const_int 8)
761               (const_int 8)) 0)
762           (match_operand:QI 1 "general_operand" "")))]
763   ""
764   "")
765
766 (define_insn "cmpqi_ext_3_insn"
767   [(set (reg FLAGS_REG)
768         (compare
769           (subreg:QI
770             (zero_extract:SI
771               (match_operand 0 "ext_register_operand" "Q")
772               (const_int 8)
773               (const_int 8)) 0)
774           (match_operand:QI 1 "general_operand" "Qmn")))]
775   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
776   "cmp{b}\t{%1, %h0|%h0, %1}"
777   [(set_attr "type" "icmp")
778    (set_attr "mode" "QI")])
779
780 (define_insn "cmpqi_ext_3_insn_rex64"
781   [(set (reg FLAGS_REG)
782         (compare
783           (subreg:QI
784             (zero_extract:SI
785               (match_operand 0 "ext_register_operand" "Q")
786               (const_int 8)
787               (const_int 8)) 0)
788           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
789   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
790   "cmp{b}\t{%1, %h0|%h0, %1}"
791   [(set_attr "type" "icmp")
792    (set_attr "mode" "QI")])
793
794 (define_insn "*cmpqi_ext_4"
795   [(set (reg FLAGS_REG)
796         (compare
797           (subreg:QI
798             (zero_extract:SI
799               (match_operand 0 "ext_register_operand" "Q")
800               (const_int 8)
801               (const_int 8)) 0)
802           (subreg:QI
803             (zero_extract:SI
804               (match_operand 1 "ext_register_operand" "Q")
805               (const_int 8)
806               (const_int 8)) 0)))]
807   "ix86_match_ccmode (insn, CCmode)"
808   "cmp{b}\t{%h1, %h0|%h0, %h1}"
809   [(set_attr "type" "icmp")
810    (set_attr "mode" "QI")])
811
812 ;; These implement float point compares.
813 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
814 ;; which would allow mix and match FP modes on the compares.  Which is what
815 ;; the old patterns did, but with many more of them.
816
817 (define_expand "cmpxf"
818   [(set (reg:CC FLAGS_REG)
819         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
820                     (match_operand:XF 1 "nonmemory_operand" "")))]
821   "TARGET_80387"
822 {
823   ix86_compare_op0 = operands[0];
824   ix86_compare_op1 = operands[1];
825   DONE;
826 })
827
828 (define_expand "cmpdf"
829   [(set (reg:CC FLAGS_REG)
830         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
831                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
832   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
833 {
834   ix86_compare_op0 = operands[0];
835   ix86_compare_op1 = operands[1];
836   DONE;
837 })
838
839 (define_expand "cmpsf"
840   [(set (reg:CC FLAGS_REG)
841         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
842                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
843   "TARGET_80387 || TARGET_SSE_MATH"
844 {
845   ix86_compare_op0 = operands[0];
846   ix86_compare_op1 = operands[1];
847   DONE;
848 })
849
850 ;; FP compares, step 1:
851 ;; Set the FP condition codes.
852 ;;
853 ;; CCFPmode     compare with exceptions
854 ;; CCFPUmode    compare with no exceptions
855
856 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
857 ;; used to manage the reg stack popping would not be preserved.
858
859 (define_insn "*cmpfp_0"
860   [(set (match_operand:HI 0 "register_operand" "=a")
861         (unspec:HI
862           [(compare:CCFP
863              (match_operand 1 "register_operand" "f")
864              (match_operand 2 "const0_operand" "X"))]
865         UNSPEC_FNSTSW))]
866   "TARGET_80387
867    && FLOAT_MODE_P (GET_MODE (operands[1]))
868    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
869   "* return output_fp_compare (insn, operands, 0, 0);"
870   [(set_attr "type" "multi")
871    (set_attr "unit" "i387")
872    (set (attr "mode")
873      (cond [(match_operand:SF 1 "" "")
874               (const_string "SF")
875             (match_operand:DF 1 "" "")
876               (const_string "DF")
877            ]
878            (const_string "XF")))])
879
880 (define_insn "*cmpfp_sf"
881   [(set (match_operand:HI 0 "register_operand" "=a")
882         (unspec:HI
883           [(compare:CCFP
884              (match_operand:SF 1 "register_operand" "f")
885              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
886           UNSPEC_FNSTSW))]
887   "TARGET_80387"
888   "* return output_fp_compare (insn, operands, 0, 0);"
889   [(set_attr "type" "multi")
890    (set_attr "unit" "i387")
891    (set_attr "mode" "SF")])
892
893 (define_insn "*cmpfp_df"
894   [(set (match_operand:HI 0 "register_operand" "=a")
895         (unspec:HI
896           [(compare:CCFP
897              (match_operand:DF 1 "register_operand" "f")
898              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
899           UNSPEC_FNSTSW))]
900   "TARGET_80387"
901   "* return output_fp_compare (insn, operands, 0, 0);"
902   [(set_attr "type" "multi")
903    (set_attr "unit" "i387")
904    (set_attr "mode" "DF")])
905
906 (define_insn "*cmpfp_xf"
907   [(set (match_operand:HI 0 "register_operand" "=a")
908         (unspec:HI
909           [(compare:CCFP
910              (match_operand:XF 1 "register_operand" "f")
911              (match_operand:XF 2 "register_operand" "f"))]
912           UNSPEC_FNSTSW))]
913   "TARGET_80387"
914   "* return output_fp_compare (insn, operands, 0, 0);"
915   [(set_attr "type" "multi")
916    (set_attr "unit" "i387")
917    (set_attr "mode" "XF")])
918
919 (define_insn "*cmpfp_u"
920   [(set (match_operand:HI 0 "register_operand" "=a")
921         (unspec:HI
922           [(compare:CCFPU
923              (match_operand 1 "register_operand" "f")
924              (match_operand 2 "register_operand" "f"))]
925           UNSPEC_FNSTSW))]
926   "TARGET_80387
927    && FLOAT_MODE_P (GET_MODE (operands[1]))
928    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
929   "* return output_fp_compare (insn, operands, 0, 1);"
930   [(set_attr "type" "multi")
931    (set_attr "unit" "i387")
932    (set (attr "mode")
933      (cond [(match_operand:SF 1 "" "")
934               (const_string "SF")
935             (match_operand:DF 1 "" "")
936               (const_string "DF")
937            ]
938            (const_string "XF")))])
939
940 (define_insn "*cmpfp_<mode>"
941   [(set (match_operand:HI 0 "register_operand" "=a")
942         (unspec:HI
943           [(compare:CCFP
944              (match_operand 1 "register_operand" "f")
945              (match_operator 3 "float_operator"
946                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
947           UNSPEC_FNSTSW))]
948   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
949    && FLOAT_MODE_P (GET_MODE (operands[1]))
950    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
951   "* return output_fp_compare (insn, operands, 0, 0);"
952   [(set_attr "type" "multi")
953    (set_attr "unit" "i387")
954    (set_attr "fp_int_src" "true")
955    (set_attr "mode" "<MODE>")])
956
957 ;; FP compares, step 2
958 ;; Move the fpsw to ax.
959
960 (define_insn "x86_fnstsw_1"
961   [(set (match_operand:HI 0 "register_operand" "=a")
962         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
963   "TARGET_80387"
964   "fnstsw\t%0"
965   [(set_attr "length" "2")
966    (set_attr "mode" "SI")
967    (set_attr "unit" "i387")])
968
969 ;; FP compares, step 3
970 ;; Get ax into flags, general case.
971
972 (define_insn "x86_sahf_1"
973   [(set (reg:CC FLAGS_REG)
974         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
975   "!TARGET_64BIT"
976   "sahf"
977   [(set_attr "length" "1")
978    (set_attr "athlon_decode" "vector")
979    (set_attr "mode" "SI")])
980
981 ;; Pentium Pro can do steps 1 through 3 in one go.
982
983 (define_insn "*cmpfp_i_mixed"
984   [(set (reg:CCFP FLAGS_REG)
985         (compare:CCFP (match_operand 0 "register_operand" "f,x")
986                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
987   "TARGET_MIX_SSE_I387
988    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
989    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
990   "* return output_fp_compare (insn, operands, 1, 0);"
991   [(set_attr "type" "fcmp,ssecomi")
992    (set (attr "mode")
993      (if_then_else (match_operand:SF 1 "" "")
994         (const_string "SF")
995         (const_string "DF")))
996    (set_attr "athlon_decode" "vector")])
997
998 (define_insn "*cmpfp_i_sse"
999   [(set (reg:CCFP FLAGS_REG)
1000         (compare:CCFP (match_operand 0 "register_operand" "x")
1001                       (match_operand 1 "nonimmediate_operand" "xm")))]
1002   "TARGET_SSE_MATH
1003    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1004    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1005   "* return output_fp_compare (insn, operands, 1, 0);"
1006   [(set_attr "type" "ssecomi")
1007    (set (attr "mode")
1008      (if_then_else (match_operand:SF 1 "" "")
1009         (const_string "SF")
1010         (const_string "DF")))
1011    (set_attr "athlon_decode" "vector")])
1012
1013 (define_insn "*cmpfp_i_i387"
1014   [(set (reg:CCFP FLAGS_REG)
1015         (compare:CCFP (match_operand 0 "register_operand" "f")
1016                       (match_operand 1 "register_operand" "f")))]
1017   "TARGET_80387 && TARGET_CMOVE
1018    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1019    && FLOAT_MODE_P (GET_MODE (operands[0]))
1020    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1021   "* return output_fp_compare (insn, operands, 1, 0);"
1022   [(set_attr "type" "fcmp")
1023    (set (attr "mode")
1024      (cond [(match_operand:SF 1 "" "")
1025               (const_string "SF")
1026             (match_operand:DF 1 "" "")
1027               (const_string "DF")
1028            ]
1029            (const_string "XF")))
1030    (set_attr "athlon_decode" "vector")])
1031
1032 (define_insn "*cmpfp_iu_mixed"
1033   [(set (reg:CCFPU FLAGS_REG)
1034         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1035                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1036   "TARGET_MIX_SSE_I387
1037    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1038    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1039   "* return output_fp_compare (insn, operands, 1, 1);"
1040   [(set_attr "type" "fcmp,ssecomi")
1041    (set (attr "mode")
1042      (if_then_else (match_operand:SF 1 "" "")
1043         (const_string "SF")
1044         (const_string "DF")))
1045    (set_attr "athlon_decode" "vector")])
1046
1047 (define_insn "*cmpfp_iu_sse"
1048   [(set (reg:CCFPU FLAGS_REG)
1049         (compare:CCFPU (match_operand 0 "register_operand" "x")
1050                        (match_operand 1 "nonimmediate_operand" "xm")))]
1051   "TARGET_SSE_MATH
1052    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1053    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1054   "* return output_fp_compare (insn, operands, 1, 1);"
1055   [(set_attr "type" "ssecomi")
1056    (set (attr "mode")
1057      (if_then_else (match_operand:SF 1 "" "")
1058         (const_string "SF")
1059         (const_string "DF")))
1060    (set_attr "athlon_decode" "vector")])
1061
1062 (define_insn "*cmpfp_iu_387"
1063   [(set (reg:CCFPU FLAGS_REG)
1064         (compare:CCFPU (match_operand 0 "register_operand" "f")
1065                        (match_operand 1 "register_operand" "f")))]
1066   "TARGET_80387 && TARGET_CMOVE
1067    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1068    && FLOAT_MODE_P (GET_MODE (operands[0]))
1069    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1070   "* return output_fp_compare (insn, operands, 1, 1);"
1071   [(set_attr "type" "fcmp")
1072    (set (attr "mode")
1073      (cond [(match_operand:SF 1 "" "")
1074               (const_string "SF")
1075             (match_operand:DF 1 "" "")
1076               (const_string "DF")
1077            ]
1078            (const_string "XF")))
1079    (set_attr "athlon_decode" "vector")])
1080 \f
1081 ;; Move instructions.
1082
1083 ;; General case of fullword move.
1084
1085 (define_expand "movsi"
1086   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1087         (match_operand:SI 1 "general_operand" ""))]
1088   ""
1089   "ix86_expand_move (SImode, operands); DONE;")
1090
1091 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1092 ;; general_operand.
1093 ;;
1094 ;; %%% We don't use a post-inc memory reference because x86 is not a
1095 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1096 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1097 ;; targets without our curiosities, and it is just as easy to represent
1098 ;; this differently.
1099
1100 (define_insn "*pushsi2"
1101   [(set (match_operand:SI 0 "push_operand" "=<")
1102         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1103   "!TARGET_64BIT"
1104   "push{l}\t%1"
1105   [(set_attr "type" "push")
1106    (set_attr "mode" "SI")])
1107
1108 ;; For 64BIT abi we always round up to 8 bytes.
1109 (define_insn "*pushsi2_rex64"
1110   [(set (match_operand:SI 0 "push_operand" "=X")
1111         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1112   "TARGET_64BIT"
1113   "push{q}\t%q1"
1114   [(set_attr "type" "push")
1115    (set_attr "mode" "SI")])
1116
1117 (define_insn "*pushsi2_prologue"
1118   [(set (match_operand:SI 0 "push_operand" "=<")
1119         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1120    (clobber (mem:BLK (scratch)))]
1121   "!TARGET_64BIT"
1122   "push{l}\t%1"
1123   [(set_attr "type" "push")
1124    (set_attr "mode" "SI")])
1125
1126 (define_insn "*popsi1_epilogue"
1127   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1128         (mem:SI (reg:SI SP_REG)))
1129    (set (reg:SI SP_REG)
1130         (plus:SI (reg:SI SP_REG) (const_int 4)))
1131    (clobber (mem:BLK (scratch)))]
1132   "!TARGET_64BIT"
1133   "pop{l}\t%0"
1134   [(set_attr "type" "pop")
1135    (set_attr "mode" "SI")])
1136
1137 (define_insn "popsi1"
1138   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1139         (mem:SI (reg:SI SP_REG)))
1140    (set (reg:SI SP_REG)
1141         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1142   "!TARGET_64BIT"
1143   "pop{l}\t%0"
1144   [(set_attr "type" "pop")
1145    (set_attr "mode" "SI")])
1146
1147 (define_insn "*movsi_xor"
1148   [(set (match_operand:SI 0 "register_operand" "=r")
1149         (match_operand:SI 1 "const0_operand" "i"))
1150    (clobber (reg:CC FLAGS_REG))]
1151   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1152   "xor{l}\t{%0, %0|%0, %0}"
1153   [(set_attr "type" "alu1")
1154    (set_attr "mode" "SI")
1155    (set_attr "length_immediate" "0")])
1156
1157 (define_insn "*movsi_or"
1158   [(set (match_operand:SI 0 "register_operand" "=r")
1159         (match_operand:SI 1 "immediate_operand" "i"))
1160    (clobber (reg:CC FLAGS_REG))]
1161   "reload_completed
1162    && operands[1] == constm1_rtx
1163    && (TARGET_PENTIUM || optimize_size)"
1164 {
1165   operands[1] = constm1_rtx;
1166   return "or{l}\t{%1, %0|%0, %1}";
1167 }
1168   [(set_attr "type" "alu1")
1169    (set_attr "mode" "SI")
1170    (set_attr "length_immediate" "1")])
1171
1172 (define_insn "*movsi_1"
1173   [(set (match_operand:SI 0 "nonimmediate_operand"
1174                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1175         (match_operand:SI 1 "general_operand"
1176                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1177   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1178 {
1179   switch (get_attr_type (insn))
1180     {
1181     case TYPE_SSELOG1:
1182       if (get_attr_mode (insn) == MODE_TI)
1183         return "pxor\t%0, %0";
1184       return "xorps\t%0, %0";
1185
1186     case TYPE_SSEMOV:
1187       switch (get_attr_mode (insn))
1188         {
1189         case MODE_TI:
1190           return "movdqa\t{%1, %0|%0, %1}";
1191         case MODE_V4SF:
1192           return "movaps\t{%1, %0|%0, %1}";
1193         case MODE_SI:
1194           return "movd\t{%1, %0|%0, %1}";
1195         case MODE_SF:
1196           return "movss\t{%1, %0|%0, %1}";
1197         default:
1198           gcc_unreachable ();
1199         }
1200
1201     case TYPE_MMXADD:
1202       return "pxor\t%0, %0";
1203
1204     case TYPE_MMXMOV:
1205       if (get_attr_mode (insn) == MODE_DI)
1206         return "movq\t{%1, %0|%0, %1}";
1207       return "movd\t{%1, %0|%0, %1}";
1208
1209     case TYPE_LEA:
1210       return "lea{l}\t{%1, %0|%0, %1}";
1211
1212     default:
1213       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1214       return "mov{l}\t{%1, %0|%0, %1}";
1215     }
1216 }
1217   [(set (attr "type")
1218      (cond [(eq_attr "alternative" "2")
1219               (const_string "mmxadd")
1220             (eq_attr "alternative" "3,4,5")
1221               (const_string "mmxmov")
1222             (eq_attr "alternative" "6")
1223               (const_string "sselog1")
1224             (eq_attr "alternative" "7,8,9,10,11")
1225               (const_string "ssemov")
1226             (match_operand:DI 1 "pic_32bit_operand" "")
1227               (const_string "lea")
1228            ]
1229            (const_string "imov")))
1230    (set (attr "mode")
1231      (cond [(eq_attr "alternative" "2,3")
1232               (const_string "DI")
1233             (eq_attr "alternative" "6,7")
1234               (if_then_else
1235                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1236                 (const_string "V4SF")
1237                 (const_string "TI"))
1238             (and (eq_attr "alternative" "8,9,10,11")
1239                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1240               (const_string "SF")
1241            ]
1242            (const_string "SI")))])
1243
1244 ;; Stores and loads of ax to arbitrary constant address.
1245 ;; We fake an second form of instruction to force reload to load address
1246 ;; into register when rax is not available
1247 (define_insn "*movabssi_1_rex64"
1248   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1249         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1250   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1251   "@
1252    movabs{l}\t{%1, %P0|%P0, %1}
1253    mov{l}\t{%1, %a0|%a0, %1}"
1254   [(set_attr "type" "imov")
1255    (set_attr "modrm" "0,*")
1256    (set_attr "length_address" "8,0")
1257    (set_attr "length_immediate" "0,*")
1258    (set_attr "memory" "store")
1259    (set_attr "mode" "SI")])
1260
1261 (define_insn "*movabssi_2_rex64"
1262   [(set (match_operand:SI 0 "register_operand" "=a,r")
1263         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1264   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1265   "@
1266    movabs{l}\t{%P1, %0|%0, %P1}
1267    mov{l}\t{%a1, %0|%0, %a1}"
1268   [(set_attr "type" "imov")
1269    (set_attr "modrm" "0,*")
1270    (set_attr "length_address" "8,0")
1271    (set_attr "length_immediate" "0")
1272    (set_attr "memory" "load")
1273    (set_attr "mode" "SI")])
1274
1275 (define_insn "*swapsi"
1276   [(set (match_operand:SI 0 "register_operand" "+r")
1277         (match_operand:SI 1 "register_operand" "+r"))
1278    (set (match_dup 1)
1279         (match_dup 0))]
1280   ""
1281   "xchg{l}\t%1, %0"
1282   [(set_attr "type" "imov")
1283    (set_attr "mode" "SI")
1284    (set_attr "pent_pair" "np")
1285    (set_attr "athlon_decode" "vector")])
1286
1287 (define_expand "movhi"
1288   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1289         (match_operand:HI 1 "general_operand" ""))]
1290   ""
1291   "ix86_expand_move (HImode, operands); DONE;")
1292
1293 (define_insn "*pushhi2"
1294   [(set (match_operand:HI 0 "push_operand" "=X")
1295         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1296   "!TARGET_64BIT"
1297   "push{l}\t%k1"
1298   [(set_attr "type" "push")
1299    (set_attr "mode" "SI")])
1300
1301 ;; For 64BIT abi we always round up to 8 bytes.
1302 (define_insn "*pushhi2_rex64"
1303   [(set (match_operand:HI 0 "push_operand" "=X")
1304         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1305   "TARGET_64BIT"
1306   "push{q}\t%q1"
1307   [(set_attr "type" "push")
1308    (set_attr "mode" "DI")])
1309
1310 (define_insn "*movhi_1"
1311   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1312         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1313   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1314 {
1315   switch (get_attr_type (insn))
1316     {
1317     case TYPE_IMOVX:
1318       /* movzwl is faster than movw on p2 due to partial word stalls,
1319          though not as fast as an aligned movl.  */
1320       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1321     default:
1322       if (get_attr_mode (insn) == MODE_SI)
1323         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1324       else
1325         return "mov{w}\t{%1, %0|%0, %1}";
1326     }
1327 }
1328   [(set (attr "type")
1329      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1330               (const_string "imov")
1331             (and (eq_attr "alternative" "0")
1332                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1333                           (const_int 0))
1334                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1335                           (const_int 0))))
1336               (const_string "imov")
1337             (and (eq_attr "alternative" "1,2")
1338                  (match_operand:HI 1 "aligned_operand" ""))
1339               (const_string "imov")
1340             (and (ne (symbol_ref "TARGET_MOVX")
1341                      (const_int 0))
1342                  (eq_attr "alternative" "0,2"))
1343               (const_string "imovx")
1344            ]
1345            (const_string "imov")))
1346     (set (attr "mode")
1347       (cond [(eq_attr "type" "imovx")
1348                (const_string "SI")
1349              (and (eq_attr "alternative" "1,2")
1350                   (match_operand:HI 1 "aligned_operand" ""))
1351                (const_string "SI")
1352              (and (eq_attr "alternative" "0")
1353                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1354                            (const_int 0))
1355                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1356                            (const_int 0))))
1357                (const_string "SI")
1358             ]
1359             (const_string "HI")))])
1360
1361 ;; Stores and loads of ax to arbitrary constant address.
1362 ;; We fake an second form of instruction to force reload to load address
1363 ;; into register when rax is not available
1364 (define_insn "*movabshi_1_rex64"
1365   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1366         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1367   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1368   "@
1369    movabs{w}\t{%1, %P0|%P0, %1}
1370    mov{w}\t{%1, %a0|%a0, %1}"
1371   [(set_attr "type" "imov")
1372    (set_attr "modrm" "0,*")
1373    (set_attr "length_address" "8,0")
1374    (set_attr "length_immediate" "0,*")
1375    (set_attr "memory" "store")
1376    (set_attr "mode" "HI")])
1377
1378 (define_insn "*movabshi_2_rex64"
1379   [(set (match_operand:HI 0 "register_operand" "=a,r")
1380         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1381   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1382   "@
1383    movabs{w}\t{%P1, %0|%0, %P1}
1384    mov{w}\t{%a1, %0|%0, %a1}"
1385   [(set_attr "type" "imov")
1386    (set_attr "modrm" "0,*")
1387    (set_attr "length_address" "8,0")
1388    (set_attr "length_immediate" "0")
1389    (set_attr "memory" "load")
1390    (set_attr "mode" "HI")])
1391
1392 (define_insn "*swaphi_1"
1393   [(set (match_operand:HI 0 "register_operand" "+r")
1394         (match_operand:HI 1 "register_operand" "+r"))
1395    (set (match_dup 1)
1396         (match_dup 0))]
1397   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1398   "xchg{l}\t%k1, %k0"
1399   [(set_attr "type" "imov")
1400    (set_attr "mode" "SI")
1401    (set_attr "pent_pair" "np")
1402    (set_attr "athlon_decode" "vector")])
1403
1404 (define_insn "*swaphi_2"
1405   [(set (match_operand:HI 0 "register_operand" "+r")
1406         (match_operand:HI 1 "register_operand" "+r"))
1407    (set (match_dup 1)
1408         (match_dup 0))]
1409   "TARGET_PARTIAL_REG_STALL"
1410   "xchg{w}\t%1, %0"
1411   [(set_attr "type" "imov")
1412    (set_attr "mode" "HI")
1413    (set_attr "pent_pair" "np")
1414    (set_attr "athlon_decode" "vector")])
1415
1416 (define_expand "movstricthi"
1417   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1418         (match_operand:HI 1 "general_operand" ""))]
1419   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1420 {
1421   /* Don't generate memory->memory moves, go through a register */
1422   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1423     operands[1] = force_reg (HImode, operands[1]);
1424 })
1425
1426 (define_insn "*movstricthi_1"
1427   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1428         (match_operand:HI 1 "general_operand" "rn,m"))]
1429   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1430    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1431   "mov{w}\t{%1, %0|%0, %1}"
1432   [(set_attr "type" "imov")
1433    (set_attr "mode" "HI")])
1434
1435 (define_insn "*movstricthi_xor"
1436   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1437         (match_operand:HI 1 "const0_operand" "i"))
1438    (clobber (reg:CC FLAGS_REG))]
1439   "reload_completed
1440    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1441   "xor{w}\t{%0, %0|%0, %0}"
1442   [(set_attr "type" "alu1")
1443    (set_attr "mode" "HI")
1444    (set_attr "length_immediate" "0")])
1445
1446 (define_expand "movqi"
1447   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1448         (match_operand:QI 1 "general_operand" ""))]
1449   ""
1450   "ix86_expand_move (QImode, operands); DONE;")
1451
1452 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1453 ;; "push a byte".  But actually we use pushl, which has the effect
1454 ;; of rounding the amount pushed up to a word.
1455
1456 (define_insn "*pushqi2"
1457   [(set (match_operand:QI 0 "push_operand" "=X")
1458         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1459   "!TARGET_64BIT"
1460   "push{l}\t%k1"
1461   [(set_attr "type" "push")
1462    (set_attr "mode" "SI")])
1463
1464 ;; For 64BIT abi we always round up to 8 bytes.
1465 (define_insn "*pushqi2_rex64"
1466   [(set (match_operand:QI 0 "push_operand" "=X")
1467         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1468   "TARGET_64BIT"
1469   "push{q}\t%q1"
1470   [(set_attr "type" "push")
1471    (set_attr "mode" "DI")])
1472
1473 ;; Situation is quite tricky about when to choose full sized (SImode) move
1474 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1475 ;; partial register dependency machines (such as AMD Athlon), where QImode
1476 ;; moves issue extra dependency and for partial register stalls machines
1477 ;; that don't use QImode patterns (and QImode move cause stall on the next
1478 ;; instruction).
1479 ;;
1480 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1481 ;; register stall machines with, where we use QImode instructions, since
1482 ;; partial register stall can be caused there.  Then we use movzx.
1483 (define_insn "*movqi_1"
1484   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1485         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1486   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1487 {
1488   switch (get_attr_type (insn))
1489     {
1490     case TYPE_IMOVX:
1491       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1492       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1493     default:
1494       if (get_attr_mode (insn) == MODE_SI)
1495         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1496       else
1497         return "mov{b}\t{%1, %0|%0, %1}";
1498     }
1499 }
1500   [(set (attr "type")
1501      (cond [(and (eq_attr "alternative" "5")
1502                  (not (match_operand:QI 1 "aligned_operand" "")))
1503               (const_string "imovx")
1504             (ne (symbol_ref "optimize_size") (const_int 0))
1505               (const_string "imov")
1506             (and (eq_attr "alternative" "3")
1507                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1508                           (const_int 0))
1509                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1510                           (const_int 0))))
1511               (const_string "imov")
1512             (eq_attr "alternative" "3,5")
1513               (const_string "imovx")
1514             (and (ne (symbol_ref "TARGET_MOVX")
1515                      (const_int 0))
1516                  (eq_attr "alternative" "2"))
1517               (const_string "imovx")
1518            ]
1519            (const_string "imov")))
1520    (set (attr "mode")
1521       (cond [(eq_attr "alternative" "3,4,5")
1522                (const_string "SI")
1523              (eq_attr "alternative" "6")
1524                (const_string "QI")
1525              (eq_attr "type" "imovx")
1526                (const_string "SI")
1527              (and (eq_attr "type" "imov")
1528                   (and (eq_attr "alternative" "0,1")
1529                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1530                                 (const_int 0))
1531                             (and (eq (symbol_ref "optimize_size")
1532                                      (const_int 0))
1533                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1534                                      (const_int 0))))))
1535                (const_string "SI")
1536              ;; Avoid partial register stalls when not using QImode arithmetic
1537              (and (eq_attr "type" "imov")
1538                   (and (eq_attr "alternative" "0,1")
1539                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1540                                 (const_int 0))
1541                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1542                                 (const_int 0)))))
1543                (const_string "SI")
1544            ]
1545            (const_string "QI")))])
1546
1547 (define_expand "reload_outqi"
1548   [(parallel [(match_operand:QI 0 "" "=m")
1549               (match_operand:QI 1 "register_operand" "r")
1550               (match_operand:QI 2 "register_operand" "=&q")])]
1551   ""
1552 {
1553   rtx op0, op1, op2;
1554   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1555
1556   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1557   if (! q_regs_operand (op1, QImode))
1558     {
1559       emit_insn (gen_movqi (op2, op1));
1560       op1 = op2;
1561     }
1562   emit_insn (gen_movqi (op0, op1));
1563   DONE;
1564 })
1565
1566 (define_insn "*swapqi_1"
1567   [(set (match_operand:QI 0 "register_operand" "+r")
1568         (match_operand:QI 1 "register_operand" "+r"))
1569    (set (match_dup 1)
1570         (match_dup 0))]
1571   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1572   "xchg{l}\t%k1, %k0"
1573   [(set_attr "type" "imov")
1574    (set_attr "mode" "SI")
1575    (set_attr "pent_pair" "np")
1576    (set_attr "athlon_decode" "vector")])
1577
1578 (define_insn "*swapqi_2"
1579   [(set (match_operand:QI 0 "register_operand" "+q")
1580         (match_operand:QI 1 "register_operand" "+q"))
1581    (set (match_dup 1)
1582         (match_dup 0))]
1583   "TARGET_PARTIAL_REG_STALL"
1584   "xchg{b}\t%1, %0"
1585   [(set_attr "type" "imov")
1586    (set_attr "mode" "QI")
1587    (set_attr "pent_pair" "np")
1588    (set_attr "athlon_decode" "vector")])
1589
1590 (define_expand "movstrictqi"
1591   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1592         (match_operand:QI 1 "general_operand" ""))]
1593   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1594 {
1595   /* Don't generate memory->memory moves, go through a register.  */
1596   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1597     operands[1] = force_reg (QImode, operands[1]);
1598 })
1599
1600 (define_insn "*movstrictqi_1"
1601   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1602         (match_operand:QI 1 "general_operand" "*qn,m"))]
1603   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1604    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1605   "mov{b}\t{%1, %0|%0, %1}"
1606   [(set_attr "type" "imov")
1607    (set_attr "mode" "QI")])
1608
1609 (define_insn "*movstrictqi_xor"
1610   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1611         (match_operand:QI 1 "const0_operand" "i"))
1612    (clobber (reg:CC FLAGS_REG))]
1613   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1614   "xor{b}\t{%0, %0|%0, %0}"
1615   [(set_attr "type" "alu1")
1616    (set_attr "mode" "QI")
1617    (set_attr "length_immediate" "0")])
1618
1619 (define_insn "*movsi_extv_1"
1620   [(set (match_operand:SI 0 "register_operand" "=R")
1621         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1622                          (const_int 8)
1623                          (const_int 8)))]
1624   ""
1625   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1626   [(set_attr "type" "imovx")
1627    (set_attr "mode" "SI")])
1628
1629 (define_insn "*movhi_extv_1"
1630   [(set (match_operand:HI 0 "register_operand" "=R")
1631         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1632                          (const_int 8)
1633                          (const_int 8)))]
1634   ""
1635   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1636   [(set_attr "type" "imovx")
1637    (set_attr "mode" "SI")])
1638
1639 (define_insn "*movqi_extv_1"
1640   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1641         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1642                          (const_int 8)
1643                          (const_int 8)))]
1644   "!TARGET_64BIT"
1645 {
1646   switch (get_attr_type (insn))
1647     {
1648     case TYPE_IMOVX:
1649       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1650     default:
1651       return "mov{b}\t{%h1, %0|%0, %h1}";
1652     }
1653 }
1654   [(set (attr "type")
1655      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1656                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1657                              (ne (symbol_ref "TARGET_MOVX")
1658                                  (const_int 0))))
1659         (const_string "imovx")
1660         (const_string "imov")))
1661    (set (attr "mode")
1662      (if_then_else (eq_attr "type" "imovx")
1663         (const_string "SI")
1664         (const_string "QI")))])
1665
1666 (define_insn "*movqi_extv_1_rex64"
1667   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1668         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1669                          (const_int 8)
1670                          (const_int 8)))]
1671   "TARGET_64BIT"
1672 {
1673   switch (get_attr_type (insn))
1674     {
1675     case TYPE_IMOVX:
1676       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1677     default:
1678       return "mov{b}\t{%h1, %0|%0, %h1}";
1679     }
1680 }
1681   [(set (attr "type")
1682      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1683                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1684                              (ne (symbol_ref "TARGET_MOVX")
1685                                  (const_int 0))))
1686         (const_string "imovx")
1687         (const_string "imov")))
1688    (set (attr "mode")
1689      (if_then_else (eq_attr "type" "imovx")
1690         (const_string "SI")
1691         (const_string "QI")))])
1692
1693 ;; Stores and loads of ax to arbitrary constant address.
1694 ;; We fake an second form of instruction to force reload to load address
1695 ;; into register when rax is not available
1696 (define_insn "*movabsqi_1_rex64"
1697   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1698         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1699   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1700   "@
1701    movabs{b}\t{%1, %P0|%P0, %1}
1702    mov{b}\t{%1, %a0|%a0, %1}"
1703   [(set_attr "type" "imov")
1704    (set_attr "modrm" "0,*")
1705    (set_attr "length_address" "8,0")
1706    (set_attr "length_immediate" "0,*")
1707    (set_attr "memory" "store")
1708    (set_attr "mode" "QI")])
1709
1710 (define_insn "*movabsqi_2_rex64"
1711   [(set (match_operand:QI 0 "register_operand" "=a,r")
1712         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1713   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1714   "@
1715    movabs{b}\t{%P1, %0|%0, %P1}
1716    mov{b}\t{%a1, %0|%0, %a1}"
1717   [(set_attr "type" "imov")
1718    (set_attr "modrm" "0,*")
1719    (set_attr "length_address" "8,0")
1720    (set_attr "length_immediate" "0")
1721    (set_attr "memory" "load")
1722    (set_attr "mode" "QI")])
1723
1724 (define_insn "*movdi_extzv_1"
1725   [(set (match_operand:DI 0 "register_operand" "=R")
1726         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1727                          (const_int 8)
1728                          (const_int 8)))]
1729   "TARGET_64BIT"
1730   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1731   [(set_attr "type" "imovx")
1732    (set_attr "mode" "DI")])
1733
1734 (define_insn "*movsi_extzv_1"
1735   [(set (match_operand:SI 0 "register_operand" "=R")
1736         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1737                          (const_int 8)
1738                          (const_int 8)))]
1739   ""
1740   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1741   [(set_attr "type" "imovx")
1742    (set_attr "mode" "SI")])
1743
1744 (define_insn "*movqi_extzv_2"
1745   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1746         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1747                                     (const_int 8)
1748                                     (const_int 8)) 0))]
1749   "!TARGET_64BIT"
1750 {
1751   switch (get_attr_type (insn))
1752     {
1753     case TYPE_IMOVX:
1754       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1755     default:
1756       return "mov{b}\t{%h1, %0|%0, %h1}";
1757     }
1758 }
1759   [(set (attr "type")
1760      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1761                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1762                              (ne (symbol_ref "TARGET_MOVX")
1763                                  (const_int 0))))
1764         (const_string "imovx")
1765         (const_string "imov")))
1766    (set (attr "mode")
1767      (if_then_else (eq_attr "type" "imovx")
1768         (const_string "SI")
1769         (const_string "QI")))])
1770
1771 (define_insn "*movqi_extzv_2_rex64"
1772   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1773         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1774                                     (const_int 8)
1775                                     (const_int 8)) 0))]
1776   "TARGET_64BIT"
1777 {
1778   switch (get_attr_type (insn))
1779     {
1780     case TYPE_IMOVX:
1781       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1782     default:
1783       return "mov{b}\t{%h1, %0|%0, %h1}";
1784     }
1785 }
1786   [(set (attr "type")
1787      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1788                         (ne (symbol_ref "TARGET_MOVX")
1789                             (const_int 0)))
1790         (const_string "imovx")
1791         (const_string "imov")))
1792    (set (attr "mode")
1793      (if_then_else (eq_attr "type" "imovx")
1794         (const_string "SI")
1795         (const_string "QI")))])
1796
1797 (define_insn "movsi_insv_1"
1798   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1799                          (const_int 8)
1800                          (const_int 8))
1801         (match_operand:SI 1 "general_operand" "Qmn"))]
1802   "!TARGET_64BIT"
1803   "mov{b}\t{%b1, %h0|%h0, %b1}"
1804   [(set_attr "type" "imov")
1805    (set_attr "mode" "QI")])
1806
1807 (define_insn "*movsi_insv_1_rex64"
1808   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1809                          (const_int 8)
1810                          (const_int 8))
1811         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1812   "TARGET_64BIT"
1813   "mov{b}\t{%b1, %h0|%h0, %b1}"
1814   [(set_attr "type" "imov")
1815    (set_attr "mode" "QI")])
1816
1817 (define_insn "movdi_insv_1_rex64"
1818   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1819                          (const_int 8)
1820                          (const_int 8))
1821         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1822   "TARGET_64BIT"
1823   "mov{b}\t{%b1, %h0|%h0, %b1}"
1824   [(set_attr "type" "imov")
1825    (set_attr "mode" "QI")])
1826
1827 (define_insn "*movqi_insv_2"
1828   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1829                          (const_int 8)
1830                          (const_int 8))
1831         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1832                      (const_int 8)))]
1833   ""
1834   "mov{b}\t{%h1, %h0|%h0, %h1}"
1835   [(set_attr "type" "imov")
1836    (set_attr "mode" "QI")])
1837
1838 (define_expand "movdi"
1839   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1840         (match_operand:DI 1 "general_operand" ""))]
1841   ""
1842   "ix86_expand_move (DImode, operands); DONE;")
1843
1844 (define_insn "*pushdi"
1845   [(set (match_operand:DI 0 "push_operand" "=<")
1846         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1847   "!TARGET_64BIT"
1848   "#")
1849
1850 (define_insn "*pushdi2_rex64"
1851   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1852         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1853   "TARGET_64BIT"
1854   "@
1855    push{q}\t%1
1856    #"
1857   [(set_attr "type" "push,multi")
1858    (set_attr "mode" "DI")])
1859
1860 ;; Convert impossible pushes of immediate to existing instructions.
1861 ;; First try to get scratch register and go through it.  In case this
1862 ;; fails, push sign extended lower part first and then overwrite
1863 ;; upper part by 32bit move.
1864 (define_peephole2
1865   [(match_scratch:DI 2 "r")
1866    (set (match_operand:DI 0 "push_operand" "")
1867         (match_operand:DI 1 "immediate_operand" ""))]
1868   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1869    && !x86_64_immediate_operand (operands[1], DImode)"
1870   [(set (match_dup 2) (match_dup 1))
1871    (set (match_dup 0) (match_dup 2))]
1872   "")
1873
1874 ;; We need to define this as both peepholer and splitter for case
1875 ;; peephole2 pass is not run.
1876 ;; "&& 1" is needed to keep it from matching the previous pattern.
1877 (define_peephole2
1878   [(set (match_operand:DI 0 "push_operand" "")
1879         (match_operand:DI 1 "immediate_operand" ""))]
1880   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1881    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1882   [(set (match_dup 0) (match_dup 1))
1883    (set (match_dup 2) (match_dup 3))]
1884   "split_di (operands + 1, 1, operands + 2, operands + 3);
1885    operands[1] = gen_lowpart (DImode, operands[2]);
1886    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1887                                                     GEN_INT (4)));
1888   ")
1889
1890 (define_split
1891   [(set (match_operand:DI 0 "push_operand" "")
1892         (match_operand:DI 1 "immediate_operand" ""))]
1893   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1894                     ? flow2_completed : reload_completed)
1895    && !symbolic_operand (operands[1], DImode)
1896    && !x86_64_immediate_operand (operands[1], DImode)"
1897   [(set (match_dup 0) (match_dup 1))
1898    (set (match_dup 2) (match_dup 3))]
1899   "split_di (operands + 1, 1, operands + 2, operands + 3);
1900    operands[1] = gen_lowpart (DImode, operands[2]);
1901    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1902                                                     GEN_INT (4)));
1903   ")
1904
1905 (define_insn "*pushdi2_prologue_rex64"
1906   [(set (match_operand:DI 0 "push_operand" "=<")
1907         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1908    (clobber (mem:BLK (scratch)))]
1909   "TARGET_64BIT"
1910   "push{q}\t%1"
1911   [(set_attr "type" "push")
1912    (set_attr "mode" "DI")])
1913
1914 (define_insn "*popdi1_epilogue_rex64"
1915   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1916         (mem:DI (reg:DI SP_REG)))
1917    (set (reg:DI SP_REG)
1918         (plus:DI (reg:DI SP_REG) (const_int 8)))
1919    (clobber (mem:BLK (scratch)))]
1920   "TARGET_64BIT"
1921   "pop{q}\t%0"
1922   [(set_attr "type" "pop")
1923    (set_attr "mode" "DI")])
1924
1925 (define_insn "popdi1"
1926   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1927         (mem:DI (reg:DI SP_REG)))
1928    (set (reg:DI SP_REG)
1929         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1930   "TARGET_64BIT"
1931   "pop{q}\t%0"
1932   [(set_attr "type" "pop")
1933    (set_attr "mode" "DI")])
1934
1935 (define_insn "*movdi_xor_rex64"
1936   [(set (match_operand:DI 0 "register_operand" "=r")
1937         (match_operand:DI 1 "const0_operand" "i"))
1938    (clobber (reg:CC FLAGS_REG))]
1939   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1940    && reload_completed"
1941   "xor{l}\t{%k0, %k0|%k0, %k0}"
1942   [(set_attr "type" "alu1")
1943    (set_attr "mode" "SI")
1944    (set_attr "length_immediate" "0")])
1945
1946 (define_insn "*movdi_or_rex64"
1947   [(set (match_operand:DI 0 "register_operand" "=r")
1948         (match_operand:DI 1 "const_int_operand" "i"))
1949    (clobber (reg:CC FLAGS_REG))]
1950   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1951    && reload_completed
1952    && operands[1] == constm1_rtx"
1953 {
1954   operands[1] = constm1_rtx;
1955   return "or{q}\t{%1, %0|%0, %1}";
1956 }
1957   [(set_attr "type" "alu1")
1958    (set_attr "mode" "DI")
1959    (set_attr "length_immediate" "1")])
1960
1961 (define_insn "*movdi_2"
1962   [(set (match_operand:DI 0 "nonimmediate_operand"
1963                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1964         (match_operand:DI 1 "general_operand"
1965                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1966   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1967   "@
1968    #
1969    #
1970    pxor\t%0, %0
1971    movq\t{%1, %0|%0, %1}
1972    movq\t{%1, %0|%0, %1}
1973    pxor\t%0, %0
1974    movq\t{%1, %0|%0, %1}
1975    movdqa\t{%1, %0|%0, %1}
1976    movq\t{%1, %0|%0, %1}
1977    xorps\t%0, %0
1978    movlps\t{%1, %0|%0, %1}
1979    movaps\t{%1, %0|%0, %1}
1980    movlps\t{%1, %0|%0, %1}"
1981   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1982    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1983
1984 (define_split
1985   [(set (match_operand:DI 0 "push_operand" "")
1986         (match_operand:DI 1 "general_operand" ""))]
1987   "!TARGET_64BIT && reload_completed
1988    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1989   [(const_int 0)]
1990   "ix86_split_long_move (operands); DONE;")
1991
1992 ;; %%% This multiword shite has got to go.
1993 (define_split
1994   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1995         (match_operand:DI 1 "general_operand" ""))]
1996   "!TARGET_64BIT && reload_completed
1997    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1998    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1999   [(const_int 0)]
2000   "ix86_split_long_move (operands); DONE;")
2001
2002 (define_insn "*movdi_1_rex64"
2003   [(set (match_operand:DI 0 "nonimmediate_operand"
2004                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
2005         (match_operand:DI 1 "general_operand"
2006                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
2007   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2008 {
2009   switch (get_attr_type (insn))
2010     {
2011     case TYPE_SSECVT:
2012       if (which_alternative == 13)
2013         return "movq2dq\t{%1, %0|%0, %1}";
2014       else
2015         return "movdq2q\t{%1, %0|%0, %1}";
2016     case TYPE_SSEMOV:
2017       if (get_attr_mode (insn) == MODE_TI)
2018           return "movdqa\t{%1, %0|%0, %1}";
2019       /* FALLTHRU */
2020     case TYPE_MMXMOV:
2021       /* Moves from and into integer register is done using movd opcode with
2022          REX prefix.  */
2023       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2024           return "movd\t{%1, %0|%0, %1}";
2025       return "movq\t{%1, %0|%0, %1}";
2026     case TYPE_SSELOG1:
2027     case TYPE_MMXADD:
2028       return "pxor\t%0, %0";
2029     case TYPE_MULTI:
2030       return "#";
2031     case TYPE_LEA:
2032       return "lea{q}\t{%a1, %0|%0, %a1}";
2033     default:
2034       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2035       if (get_attr_mode (insn) == MODE_SI)
2036         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2037       else if (which_alternative == 2)
2038         return "movabs{q}\t{%1, %0|%0, %1}";
2039       else
2040         return "mov{q}\t{%1, %0|%0, %1}";
2041     }
2042 }
2043   [(set (attr "type")
2044      (cond [(eq_attr "alternative" "5")
2045               (const_string "mmxadd")
2046             (eq_attr "alternative" "6,7,8")
2047               (const_string "mmxmov")
2048             (eq_attr "alternative" "9")
2049               (const_string "sselog1")
2050             (eq_attr "alternative" "10,11,12")
2051               (const_string "ssemov")
2052             (eq_attr "alternative" "13,14")
2053               (const_string "ssecvt")
2054             (eq_attr "alternative" "4")
2055               (const_string "multi")
2056             (match_operand:DI 1 "pic_32bit_operand" "")
2057               (const_string "lea")
2058            ]
2059            (const_string "imov")))
2060    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2061    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2062    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2063
2064 ;; Stores and loads of ax to arbitrary constant address.
2065 ;; We fake an second form of instruction to force reload to load address
2066 ;; into register when rax is not available
2067 (define_insn "*movabsdi_1_rex64"
2068   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2069         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2070   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2071   "@
2072    movabs{q}\t{%1, %P0|%P0, %1}
2073    mov{q}\t{%1, %a0|%a0, %1}"
2074   [(set_attr "type" "imov")
2075    (set_attr "modrm" "0,*")
2076    (set_attr "length_address" "8,0")
2077    (set_attr "length_immediate" "0,*")
2078    (set_attr "memory" "store")
2079    (set_attr "mode" "DI")])
2080
2081 (define_insn "*movabsdi_2_rex64"
2082   [(set (match_operand:DI 0 "register_operand" "=a,r")
2083         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2084   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2085   "@
2086    movabs{q}\t{%P1, %0|%0, %P1}
2087    mov{q}\t{%a1, %0|%0, %a1}"
2088   [(set_attr "type" "imov")
2089    (set_attr "modrm" "0,*")
2090    (set_attr "length_address" "8,0")
2091    (set_attr "length_immediate" "0")
2092    (set_attr "memory" "load")
2093    (set_attr "mode" "DI")])
2094
2095 ;; Convert impossible stores of immediate to existing instructions.
2096 ;; First try to get scratch register and go through it.  In case this
2097 ;; fails, move by 32bit parts.
2098 (define_peephole2
2099   [(match_scratch:DI 2 "r")
2100    (set (match_operand:DI 0 "memory_operand" "")
2101         (match_operand:DI 1 "immediate_operand" ""))]
2102   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2103    && !x86_64_immediate_operand (operands[1], DImode)"
2104   [(set (match_dup 2) (match_dup 1))
2105    (set (match_dup 0) (match_dup 2))]
2106   "")
2107
2108 ;; We need to define this as both peepholer and splitter for case
2109 ;; peephole2 pass is not run.
2110 ;; "&& 1" is needed to keep it from matching the previous pattern.
2111 (define_peephole2
2112   [(set (match_operand:DI 0 "memory_operand" "")
2113         (match_operand:DI 1 "immediate_operand" ""))]
2114   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2115    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2116   [(set (match_dup 2) (match_dup 3))
2117    (set (match_dup 4) (match_dup 5))]
2118   "split_di (operands, 2, operands + 2, operands + 4);")
2119
2120 (define_split
2121   [(set (match_operand:DI 0 "memory_operand" "")
2122         (match_operand:DI 1 "immediate_operand" ""))]
2123   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2124                     ? flow2_completed : reload_completed)
2125    && !symbolic_operand (operands[1], DImode)
2126    && !x86_64_immediate_operand (operands[1], DImode)"
2127   [(set (match_dup 2) (match_dup 3))
2128    (set (match_dup 4) (match_dup 5))]
2129   "split_di (operands, 2, operands + 2, operands + 4);")
2130
2131 (define_insn "*swapdi_rex64"
2132   [(set (match_operand:DI 0 "register_operand" "+r")
2133         (match_operand:DI 1 "register_operand" "+r"))
2134    (set (match_dup 1)
2135         (match_dup 0))]
2136   "TARGET_64BIT"
2137   "xchg{q}\t%1, %0"
2138   [(set_attr "type" "imov")
2139    (set_attr "mode" "DI")
2140    (set_attr "pent_pair" "np")
2141    (set_attr "athlon_decode" "vector")])
2142
2143 (define_expand "movti"
2144   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2145         (match_operand:TI 1 "nonimmediate_operand" ""))]
2146   "TARGET_SSE || TARGET_64BIT"
2147 {
2148   if (TARGET_64BIT)
2149     ix86_expand_move (TImode, operands);
2150   else
2151     ix86_expand_vector_move (TImode, operands);
2152   DONE;
2153 })
2154
2155 (define_insn "*movti_internal"
2156   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2157         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2158   "TARGET_SSE && !TARGET_64BIT
2159    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2160 {
2161   switch (which_alternative)
2162     {
2163     case 0:
2164       if (get_attr_mode (insn) == MODE_V4SF)
2165         return "xorps\t%0, %0";
2166       else
2167         return "pxor\t%0, %0";
2168     case 1:
2169     case 2:
2170       if (get_attr_mode (insn) == MODE_V4SF)
2171         return "movaps\t{%1, %0|%0, %1}";
2172       else
2173         return "movdqa\t{%1, %0|%0, %1}";
2174     default:
2175       gcc_unreachable ();
2176     }
2177 }
2178   [(set_attr "type" "sselog1,ssemov,ssemov")
2179    (set (attr "mode")
2180         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2181                     (ne (symbol_ref "optimize_size") (const_int 0)))
2182                  (const_string "V4SF")
2183                (and (eq_attr "alternative" "2")
2184                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2185                         (const_int 0)))
2186                  (const_string "V4SF")]
2187               (const_string "TI")))])
2188
2189 (define_insn "*movti_rex64"
2190   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2191         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2192   "TARGET_64BIT
2193    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2194 {
2195   switch (which_alternative)
2196     {
2197     case 0:
2198     case 1:
2199       return "#";
2200     case 2:
2201       if (get_attr_mode (insn) == MODE_V4SF)
2202         return "xorps\t%0, %0";
2203       else
2204         return "pxor\t%0, %0";
2205     case 3:
2206     case 4:
2207       if (get_attr_mode (insn) == MODE_V4SF)
2208         return "movaps\t{%1, %0|%0, %1}";
2209       else
2210         return "movdqa\t{%1, %0|%0, %1}";
2211     default:
2212       gcc_unreachable ();
2213     }
2214 }
2215   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2216    (set (attr "mode")
2217         (cond [(eq_attr "alternative" "2,3")
2218                  (if_then_else
2219                    (ne (symbol_ref "optimize_size")
2220                        (const_int 0))
2221                    (const_string "V4SF")
2222                    (const_string "TI"))
2223                (eq_attr "alternative" "4")
2224                  (if_then_else
2225                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2226                             (const_int 0))
2227                         (ne (symbol_ref "optimize_size")
2228                             (const_int 0)))
2229                    (const_string "V4SF")
2230                    (const_string "TI"))]
2231                (const_string "DI")))])
2232
2233 (define_split
2234   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2235         (match_operand:TI 1 "general_operand" ""))]
2236   "reload_completed && !SSE_REG_P (operands[0])
2237    && !SSE_REG_P (operands[1])"
2238   [(const_int 0)]
2239   "ix86_split_long_move (operands); DONE;")
2240
2241 (define_expand "movsf"
2242   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2243         (match_operand:SF 1 "general_operand" ""))]
2244   ""
2245   "ix86_expand_move (SFmode, operands); DONE;")
2246
2247 (define_insn "*pushsf"
2248   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2249         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2250   "!TARGET_64BIT"
2251 {
2252   /* Anything else should be already split before reg-stack.  */
2253   gcc_assert (which_alternative == 1);
2254   return "push{l}\t%1";
2255 }
2256   [(set_attr "type" "multi,push,multi")
2257    (set_attr "unit" "i387,*,*")
2258    (set_attr "mode" "SF,SI,SF")])
2259
2260 (define_insn "*pushsf_rex64"
2261   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2262         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2263   "TARGET_64BIT"
2264 {
2265   /* Anything else should be already split before reg-stack.  */
2266   gcc_assert (which_alternative == 1);
2267   return "push{q}\t%q1";
2268 }
2269   [(set_attr "type" "multi,push,multi")
2270    (set_attr "unit" "i387,*,*")
2271    (set_attr "mode" "SF,DI,SF")])
2272
2273 (define_split
2274   [(set (match_operand:SF 0 "push_operand" "")
2275         (match_operand:SF 1 "memory_operand" ""))]
2276   "reload_completed
2277    && MEM_P (operands[1])
2278    && constant_pool_reference_p (operands[1])"
2279   [(set (match_dup 0)
2280         (match_dup 1))]
2281   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2282
2283
2284 ;; %%% Kill this when call knows how to work this out.
2285 (define_split
2286   [(set (match_operand:SF 0 "push_operand" "")
2287         (match_operand:SF 1 "any_fp_register_operand" ""))]
2288   "!TARGET_64BIT"
2289   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2290    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2291
2292 (define_split
2293   [(set (match_operand:SF 0 "push_operand" "")
2294         (match_operand:SF 1 "any_fp_register_operand" ""))]
2295   "TARGET_64BIT"
2296   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2297    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2298
2299 (define_insn "*movsf_1"
2300   [(set (match_operand:SF 0 "nonimmediate_operand"
2301           "=f,m   ,f,r  ,m    ,x,x,x ,m   ,!*y,!rm,!*y")
2302         (match_operand:SF 1 "general_operand"
2303           "fm,f,G   ,rmF,Fr,C   ,x   ,xm,x,rm ,*y ,*y"))]
2304   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2305    && (reload_in_progress || reload_completed
2306        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2307        || (!TARGET_SSE_MATH && optimize_size
2308            && standard_80387_constant_p (operands[1]))
2309        || GET_CODE (operands[1]) != CONST_DOUBLE
2310        || memory_operand (operands[0], SFmode))"
2311 {
2312   switch (which_alternative)
2313     {
2314     case 0:
2315       return output_387_reg_move (insn, operands);
2316
2317     case 1:
2318       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2319         return "fstp%z0\t%y0";
2320       else
2321         return "fst%z0\t%y0";
2322
2323     case 2:
2324       return standard_80387_constant_opcode (operands[1]);
2325
2326     case 3:
2327     case 4:
2328       return "mov{l}\t{%1, %0|%0, %1}";
2329     case 5:
2330       if (get_attr_mode (insn) == MODE_TI)
2331         return "pxor\t%0, %0";
2332       else
2333         return "xorps\t%0, %0";
2334     case 6:
2335       if (get_attr_mode (insn) == MODE_V4SF)
2336         return "movaps\t{%1, %0|%0, %1}";
2337       else
2338         return "movss\t{%1, %0|%0, %1}";
2339     case 7:
2340     case 8:
2341       return "movss\t{%1, %0|%0, %1}";
2342
2343     case 9:
2344     case 10:
2345       return "movd\t{%1, %0|%0, %1}";
2346
2347     case 11:
2348       return "movq\t{%1, %0|%0, %1}";
2349
2350     default:
2351       gcc_unreachable ();
2352     }
2353 }
2354   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2355    (set (attr "mode")
2356         (cond [(eq_attr "alternative" "3,4,9,10")
2357                  (const_string "SI")
2358                (eq_attr "alternative" "5")
2359                  (if_then_else
2360                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2361                                  (const_int 0))
2362                              (ne (symbol_ref "TARGET_SSE2")
2363                                  (const_int 0)))
2364                         (eq (symbol_ref "optimize_size")
2365                             (const_int 0)))
2366                    (const_string "TI")
2367                    (const_string "V4SF"))
2368                /* For architectures resolving dependencies on
2369                   whole SSE registers use APS move to break dependency
2370                   chains, otherwise use short move to avoid extra work.
2371
2372                   Do the same for architectures resolving dependencies on
2373                   the parts.  While in DF mode it is better to always handle
2374                   just register parts, the SF mode is different due to lack
2375                   of instructions to load just part of the register.  It is
2376                   better to maintain the whole registers in single format
2377                   to avoid problems on using packed logical operations.  */
2378                (eq_attr "alternative" "6")
2379                  (if_then_else
2380                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2381                             (const_int 0))
2382                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2383                             (const_int 0)))
2384                    (const_string "V4SF")
2385                    (const_string "SF"))
2386                (eq_attr "alternative" "11")
2387                  (const_string "DI")]
2388                (const_string "SF")))])
2389
2390 (define_insn "*swapsf"
2391   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2392         (match_operand:SF 1 "fp_register_operand" "+f"))
2393    (set (match_dup 1)
2394         (match_dup 0))]
2395   "reload_completed || TARGET_80387"
2396 {
2397   if (STACK_TOP_P (operands[0]))
2398     return "fxch\t%1";
2399   else
2400     return "fxch\t%0";
2401 }
2402   [(set_attr "type" "fxch")
2403    (set_attr "mode" "SF")])
2404
2405 (define_expand "movdf"
2406   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2407         (match_operand:DF 1 "general_operand" ""))]
2408   ""
2409   "ix86_expand_move (DFmode, operands); DONE;")
2410
2411 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2412 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2413 ;; On the average, pushdf using integers can be still shorter.  Allow this
2414 ;; pattern for optimize_size too.
2415
2416 (define_insn "*pushdf_nointeger"
2417   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2418         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2419   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2420 {
2421   /* This insn should be already split before reg-stack.  */
2422   gcc_unreachable ();
2423 }
2424   [(set_attr "type" "multi")
2425    (set_attr "unit" "i387,*,*,*")
2426    (set_attr "mode" "DF,SI,SI,DF")])
2427
2428 (define_insn "*pushdf_integer"
2429   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2430         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2431   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2432 {
2433   /* This insn should be already split before reg-stack.  */
2434   gcc_unreachable ();
2435 }
2436   [(set_attr "type" "multi")
2437    (set_attr "unit" "i387,*,*")
2438    (set_attr "mode" "DF,SI,DF")])
2439
2440 ;; %%% Kill this when call knows how to work this out.
2441 (define_split
2442   [(set (match_operand:DF 0 "push_operand" "")
2443         (match_operand:DF 1 "any_fp_register_operand" ""))]
2444   "!TARGET_64BIT && reload_completed"
2445   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2446    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2447   "")
2448
2449 (define_split
2450   [(set (match_operand:DF 0 "push_operand" "")
2451         (match_operand:DF 1 "any_fp_register_operand" ""))]
2452   "TARGET_64BIT && reload_completed"
2453   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2454    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2455   "")
2456
2457 (define_split
2458   [(set (match_operand:DF 0 "push_operand" "")
2459         (match_operand:DF 1 "general_operand" ""))]
2460   "reload_completed"
2461   [(const_int 0)]
2462   "ix86_split_long_move (operands); DONE;")
2463
2464 ;; Moving is usually shorter when only FP registers are used. This separate
2465 ;; movdf pattern avoids the use of integer registers for FP operations
2466 ;; when optimizing for size.
2467
2468 (define_insn "*movdf_nointeger"
2469   [(set (match_operand:DF 0 "nonimmediate_operand"
2470                         "=f,m,f,*r  ,o  ,Y*x,Y*x,Y*x ,m  ")
2471         (match_operand:DF 1 "general_operand"
2472                         "fm,f,G,*roF,F*r,C  ,Y*x,mY*x,Y*x"))]
2473   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2474    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2475    && (reload_in_progress || reload_completed
2476        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2477        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2478            && standard_80387_constant_p (operands[1]))
2479        || GET_CODE (operands[1]) != CONST_DOUBLE
2480        || memory_operand (operands[0], DFmode))"
2481 {
2482   switch (which_alternative)
2483     {
2484     case 0:
2485       return output_387_reg_move (insn, operands);
2486
2487     case 1:
2488       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2489         return "fstp%z0\t%y0";
2490       else
2491         return "fst%z0\t%y0";
2492
2493     case 2:
2494       return standard_80387_constant_opcode (operands[1]);
2495
2496     case 3:
2497     case 4:
2498       return "#";
2499     case 5:
2500       switch (get_attr_mode (insn))
2501         {
2502         case MODE_V4SF:
2503           return "xorps\t%0, %0";
2504         case MODE_V2DF:
2505           return "xorpd\t%0, %0";
2506         case MODE_TI:
2507           return "pxor\t%0, %0";
2508         default:
2509           gcc_unreachable ();
2510         }
2511     case 6:
2512     case 7:
2513     case 8:
2514       switch (get_attr_mode (insn))
2515         {
2516         case MODE_V4SF:
2517           return "movaps\t{%1, %0|%0, %1}";
2518         case MODE_V2DF:
2519           return "movapd\t{%1, %0|%0, %1}";
2520         case MODE_TI:
2521           return "movdqa\t{%1, %0|%0, %1}";
2522         case MODE_DI:
2523           return "movq\t{%1, %0|%0, %1}";
2524         case MODE_DF:
2525           return "movsd\t{%1, %0|%0, %1}";
2526         case MODE_V1DF:
2527           return "movlpd\t{%1, %0|%0, %1}";
2528         case MODE_V2SF:
2529           return "movlps\t{%1, %0|%0, %1}";
2530         default:
2531           gcc_unreachable ();
2532         }
2533
2534     default:
2535       gcc_unreachable ();
2536     }
2537 }
2538   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2539    (set (attr "mode")
2540         (cond [(eq_attr "alternative" "0,1,2")
2541                  (const_string "DF")
2542                (eq_attr "alternative" "3,4")
2543                  (const_string "SI")
2544
2545                /* For SSE1, we have many fewer alternatives.  */
2546                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2547                  (cond [(eq_attr "alternative" "5,6")
2548                           (const_string "V4SF")
2549                        ]
2550                    (const_string "V2SF"))
2551
2552                /* xorps is one byte shorter.  */
2553                (eq_attr "alternative" "5")
2554                  (cond [(ne (symbol_ref "optimize_size")
2555                             (const_int 0))
2556                           (const_string "V4SF")
2557                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2558                             (const_int 0))
2559                           (const_string "TI")
2560                        ]
2561                        (const_string "V2DF"))
2562
2563                /* For architectures resolving dependencies on
2564                   whole SSE registers use APD move to break dependency
2565                   chains, otherwise use short move to avoid extra work.
2566
2567                   movaps encodes one byte shorter.  */
2568                (eq_attr "alternative" "6")
2569                  (cond
2570                    [(ne (symbol_ref "optimize_size")
2571                         (const_int 0))
2572                       (const_string "V4SF")
2573                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2574                         (const_int 0))
2575                       (const_string "V2DF")
2576                    ]
2577                    (const_string "DF"))
2578                /* For architectures resolving dependencies on register
2579                   parts we may avoid extra work to zero out upper part
2580                   of register.  */
2581                (eq_attr "alternative" "7")
2582                  (if_then_else
2583                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2584                        (const_int 0))
2585                    (const_string "V1DF")
2586                    (const_string "DF"))
2587               ]
2588               (const_string "DF")))])
2589
2590 (define_insn "*movdf_integer"
2591   [(set (match_operand:DF 0 "nonimmediate_operand"
2592                 "=f,m,f,r  ,o ,Y*x,Y*x,Y*x,m  ")
2593         (match_operand:DF 1 "general_operand"
2594                 "fm,f,G,roF,Fr,C  ,Y*x,m  ,Y*x"))]
2595   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2596    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2597    && (reload_in_progress || reload_completed
2598        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2599        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2600            && standard_80387_constant_p (operands[1]))
2601        || GET_CODE (operands[1]) != CONST_DOUBLE
2602        || memory_operand (operands[0], DFmode))"
2603 {
2604   switch (which_alternative)
2605     {
2606     case 0:
2607       return output_387_reg_move (insn, operands);
2608
2609     case 1:
2610       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2611         return "fstp%z0\t%y0";
2612       else
2613         return "fst%z0\t%y0";
2614
2615     case 2:
2616       return standard_80387_constant_opcode (operands[1]);
2617
2618     case 3:
2619     case 4:
2620       return "#";
2621
2622     case 5:
2623       switch (get_attr_mode (insn))
2624         {
2625         case MODE_V4SF:
2626           return "xorps\t%0, %0";
2627         case MODE_V2DF:
2628           return "xorpd\t%0, %0";
2629         case MODE_TI:
2630           return "pxor\t%0, %0";
2631         default:
2632           gcc_unreachable ();
2633         }
2634     case 6:
2635     case 7:
2636     case 8:
2637       switch (get_attr_mode (insn))
2638         {
2639         case MODE_V4SF:
2640           return "movaps\t{%1, %0|%0, %1}";
2641         case MODE_V2DF:
2642           return "movapd\t{%1, %0|%0, %1}";
2643         case MODE_TI:
2644           return "movdqa\t{%1, %0|%0, %1}";
2645         case MODE_DI:
2646           return "movq\t{%1, %0|%0, %1}";
2647         case MODE_DF:
2648           return "movsd\t{%1, %0|%0, %1}";
2649         case MODE_V1DF:
2650           return "movlpd\t{%1, %0|%0, %1}";
2651         case MODE_V2SF:
2652           return "movlps\t{%1, %0|%0, %1}";
2653         default:
2654           gcc_unreachable ();
2655         }
2656
2657     default:
2658       gcc_unreachable();
2659     }
2660 }
2661   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2662    (set (attr "mode")
2663         (cond [(eq_attr "alternative" "0,1,2")
2664                  (const_string "DF")
2665                (eq_attr "alternative" "3,4")
2666                  (const_string "SI")
2667
2668                /* For SSE1, we have many fewer alternatives.  */
2669                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2670                  (cond [(eq_attr "alternative" "5,6")
2671                           (const_string "V4SF")
2672                        ]
2673                    (const_string "V2SF"))
2674
2675                /* xorps is one byte shorter.  */
2676                (eq_attr "alternative" "5")
2677                  (cond [(ne (symbol_ref "optimize_size")
2678                             (const_int 0))
2679                           (const_string "V4SF")
2680                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2681                             (const_int 0))
2682                           (const_string "TI")
2683                        ]
2684                        (const_string "V2DF"))
2685
2686                /* For architectures resolving dependencies on
2687                   whole SSE registers use APD move to break dependency
2688                   chains, otherwise use short move to avoid extra work.
2689
2690                   movaps encodes one byte shorter.  */
2691                (eq_attr "alternative" "6")
2692                  (cond
2693                    [(ne (symbol_ref "optimize_size")
2694                         (const_int 0))
2695                       (const_string "V4SF")
2696                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2697                         (const_int 0))
2698                       (const_string "V2DF")
2699                    ]
2700                    (const_string "DF"))
2701                /* For architectures resolving dependencies on register
2702                   parts we may avoid extra work to zero out upper part
2703                   of register.  */
2704                (eq_attr "alternative" "7")
2705                  (if_then_else
2706                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2707                        (const_int 0))
2708                    (const_string "V1DF")
2709                    (const_string "DF"))
2710               ]
2711               (const_string "DF")))])
2712
2713 (define_split
2714   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2715         (match_operand:DF 1 "general_operand" ""))]
2716   "reload_completed
2717    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2718    && ! (ANY_FP_REG_P (operands[0]) ||
2719          (GET_CODE (operands[0]) == SUBREG
2720           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2721    && ! (ANY_FP_REG_P (operands[1]) ||
2722          (GET_CODE (operands[1]) == SUBREG
2723           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2724   [(const_int 0)]
2725   "ix86_split_long_move (operands); DONE;")
2726
2727 (define_insn "*swapdf"
2728   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2729         (match_operand:DF 1 "fp_register_operand" "+f"))
2730    (set (match_dup 1)
2731         (match_dup 0))]
2732   "reload_completed || TARGET_80387"
2733 {
2734   if (STACK_TOP_P (operands[0]))
2735     return "fxch\t%1";
2736   else
2737     return "fxch\t%0";
2738 }
2739   [(set_attr "type" "fxch")
2740    (set_attr "mode" "DF")])
2741
2742 (define_expand "movxf"
2743   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2744         (match_operand:XF 1 "general_operand" ""))]
2745   ""
2746   "ix86_expand_move (XFmode, operands); DONE;")
2747
2748 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2749 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2750 ;; Pushing using integer instructions is longer except for constants
2751 ;; and direct memory references.
2752 ;; (assuming that any given constant is pushed only once, but this ought to be
2753 ;;  handled elsewhere).
2754
2755 (define_insn "*pushxf_nointeger"
2756   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2757         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2758   "optimize_size"
2759 {
2760   /* This insn should be already split before reg-stack.  */
2761   gcc_unreachable ();
2762 }
2763   [(set_attr "type" "multi")
2764    (set_attr "unit" "i387,*,*")
2765    (set_attr "mode" "XF,SI,SI")])
2766
2767 (define_insn "*pushxf_integer"
2768   [(set (match_operand:XF 0 "push_operand" "=<,<")
2769         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2770   "!optimize_size"
2771 {
2772   /* This insn should be already split before reg-stack.  */
2773   gcc_unreachable ();
2774 }
2775   [(set_attr "type" "multi")
2776    (set_attr "unit" "i387,*")
2777    (set_attr "mode" "XF,SI")])
2778
2779 (define_split
2780   [(set (match_operand 0 "push_operand" "")
2781         (match_operand 1 "general_operand" ""))]
2782   "reload_completed
2783    && (GET_MODE (operands[0]) == XFmode
2784        || GET_MODE (operands[0]) == DFmode)
2785    && !ANY_FP_REG_P (operands[1])"
2786   [(const_int 0)]
2787   "ix86_split_long_move (operands); DONE;")
2788
2789 (define_split
2790   [(set (match_operand:XF 0 "push_operand" "")
2791         (match_operand:XF 1 "any_fp_register_operand" ""))]
2792   "!TARGET_64BIT"
2793   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2794    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2795   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2796
2797 (define_split
2798   [(set (match_operand:XF 0 "push_operand" "")
2799         (match_operand:XF 1 "any_fp_register_operand" ""))]
2800   "TARGET_64BIT"
2801   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2802    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2803   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2804
2805 ;; Do not use integer registers when optimizing for size
2806 (define_insn "*movxf_nointeger"
2807   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2808         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2809   "optimize_size
2810    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2811    && (reload_in_progress || reload_completed
2812        || (optimize_size && standard_80387_constant_p (operands[1]))
2813        || GET_CODE (operands[1]) != CONST_DOUBLE
2814        || memory_operand (operands[0], XFmode))"
2815 {
2816   switch (which_alternative)
2817     {
2818     case 0:
2819       return output_387_reg_move (insn, operands);
2820
2821     case 1:
2822       /* There is no non-popping store to memory for XFmode.  So if
2823          we need one, follow the store with a load.  */
2824       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2825         return "fstp%z0\t%y0\;fld%z0\t%y0";
2826       else
2827         return "fstp%z0\t%y0";
2828
2829     case 2:
2830       return standard_80387_constant_opcode (operands[1]);
2831
2832     case 3: case 4:
2833       return "#";
2834     default:
2835       gcc_unreachable ();
2836     }
2837 }
2838   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2839    (set_attr "mode" "XF,XF,XF,SI,SI")])
2840
2841 (define_insn "*movxf_integer"
2842   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2843         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2844   "!optimize_size
2845    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2846    && (reload_in_progress || reload_completed
2847        || (optimize_size && standard_80387_constant_p (operands[1]))
2848        || GET_CODE (operands[1]) != CONST_DOUBLE
2849        || memory_operand (operands[0], XFmode))"
2850 {
2851   switch (which_alternative)
2852     {
2853     case 0:
2854       return output_387_reg_move (insn, operands);
2855
2856     case 1:
2857       /* There is no non-popping store to memory for XFmode.  So if
2858          we need one, follow the store with a load.  */
2859       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2860         return "fstp%z0\t%y0\;fld%z0\t%y0";
2861       else
2862         return "fstp%z0\t%y0";
2863
2864     case 2:
2865       return standard_80387_constant_opcode (operands[1]);
2866
2867     case 3: case 4:
2868       return "#";
2869
2870     default:
2871       gcc_unreachable ();
2872     }
2873 }
2874   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2875    (set_attr "mode" "XF,XF,XF,SI,SI")])
2876
2877 (define_split
2878   [(set (match_operand 0 "nonimmediate_operand" "")
2879         (match_operand 1 "general_operand" ""))]
2880   "reload_completed
2881    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2882    && GET_MODE (operands[0]) == XFmode
2883    && ! (ANY_FP_REG_P (operands[0]) ||
2884          (GET_CODE (operands[0]) == SUBREG
2885           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2886    && ! (ANY_FP_REG_P (operands[1]) ||
2887          (GET_CODE (operands[1]) == SUBREG
2888           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2889   [(const_int 0)]
2890   "ix86_split_long_move (operands); DONE;")
2891
2892 (define_split
2893   [(set (match_operand 0 "register_operand" "")
2894         (match_operand 1 "memory_operand" ""))]
2895   "reload_completed
2896    && MEM_P (operands[1])
2897    && (GET_MODE (operands[0]) == XFmode
2898        || GET_MODE (operands[0]) == SFmode
2899        || GET_MODE (operands[0]) == DFmode)
2900    && constant_pool_reference_p (operands[1])"
2901   [(set (match_dup 0) (match_dup 1))]
2902 {
2903   rtx c = avoid_constant_pool_reference (operands[1]);
2904   rtx r = operands[0];
2905
2906   if (GET_CODE (r) == SUBREG)
2907     r = SUBREG_REG (r);
2908
2909   if (SSE_REG_P (r))
2910     {
2911       if (!standard_sse_constant_p (c))
2912         FAIL;
2913     }
2914   else if (FP_REG_P (r))
2915     {
2916       if (!standard_80387_constant_p (c))
2917         FAIL;
2918     }
2919   else if (MMX_REG_P (r))
2920     FAIL;
2921
2922   operands[1] = c;
2923 })
2924
2925 (define_split
2926   [(set (match_operand 0 "register_operand" "")
2927         (float_extend (match_operand 1 "memory_operand" "")))]
2928   "reload_completed
2929    && MEM_P (operands[1])
2930    && (GET_MODE (operands[0]) == XFmode
2931        || GET_MODE (operands[0]) == SFmode
2932        || GET_MODE (operands[0]) == DFmode)
2933    && constant_pool_reference_p (operands[1])"
2934   [(set (match_dup 0) (match_dup 1))]
2935 {
2936   rtx c = avoid_constant_pool_reference (SET_SRC (PATTERN (curr_insn)));
2937   rtx r = operands[0];
2938
2939   if (GET_CODE (r) == SUBREG)
2940     r = SUBREG_REG (r);
2941
2942   if (SSE_REG_P (r))
2943     {
2944       if (!standard_sse_constant_p (c))
2945         FAIL;
2946     }
2947   else if (FP_REG_P (r))
2948     {
2949       if (!standard_80387_constant_p (c))
2950         FAIL;
2951     }
2952   else if (MMX_REG_P (r))
2953     FAIL;
2954
2955   operands[1] = c;
2956 })
2957
2958 (define_insn "swapxf"
2959   [(set (match_operand:XF 0 "register_operand" "+f")
2960         (match_operand:XF 1 "register_operand" "+f"))
2961    (set (match_dup 1)
2962         (match_dup 0))]
2963   "TARGET_80387"
2964 {
2965   if (STACK_TOP_P (operands[0]))
2966     return "fxch\t%1";
2967   else
2968     return "fxch\t%0";
2969 }
2970   [(set_attr "type" "fxch")
2971    (set_attr "mode" "XF")])
2972
2973 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
2974 (define_split
2975   [(set (match_operand:X87MODEF 0 "register_operand" "")
2976         (match_operand:X87MODEF 1 "immediate_operand" ""))]
2977   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
2978    && (standard_80387_constant_p (operands[1]) == 8
2979        || standard_80387_constant_p (operands[1]) == 9)"
2980   [(set (match_dup 0)(match_dup 1))
2981    (set (match_dup 0)
2982         (neg:X87MODEF (match_dup 0)))]
2983 {
2984   REAL_VALUE_TYPE r;
2985
2986   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2987   if (real_isnegzero (&r))
2988     operands[1] = CONST0_RTX (<MODE>mode);
2989   else
2990     operands[1] = CONST1_RTX (<MODE>mode);
2991 })
2992
2993 (define_expand "movtf"
2994   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2995         (match_operand:TF 1 "nonimmediate_operand" ""))]
2996   "TARGET_64BIT"
2997 {
2998   ix86_expand_move (TFmode, operands);
2999   DONE;
3000 })
3001
3002 (define_insn "*movtf_internal"
3003   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3004         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3005   "TARGET_64BIT
3006    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3007 {
3008   switch (which_alternative)
3009     {
3010     case 0:
3011     case 1:
3012       return "#";
3013     case 2:
3014       if (get_attr_mode (insn) == MODE_V4SF)
3015         return "xorps\t%0, %0";
3016       else
3017         return "pxor\t%0, %0";
3018     case 3:
3019     case 4:
3020       if (get_attr_mode (insn) == MODE_V4SF)
3021         return "movaps\t{%1, %0|%0, %1}";
3022       else
3023         return "movdqa\t{%1, %0|%0, %1}";
3024     default:
3025       gcc_unreachable ();
3026     }
3027 }
3028   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3029    (set (attr "mode")
3030         (cond [(eq_attr "alternative" "2,3")
3031                  (if_then_else
3032                    (ne (symbol_ref "optimize_size")
3033                        (const_int 0))
3034                    (const_string "V4SF")
3035                    (const_string "TI"))
3036                (eq_attr "alternative" "4")
3037                  (if_then_else
3038                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3039                             (const_int 0))
3040                         (ne (symbol_ref "optimize_size")
3041                             (const_int 0)))
3042                    (const_string "V4SF")
3043                    (const_string "TI"))]
3044                (const_string "DI")))])
3045
3046 (define_split
3047   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3048         (match_operand:TF 1 "general_operand" ""))]
3049   "reload_completed && !SSE_REG_P (operands[0])
3050    && !SSE_REG_P (operands[1])"
3051   [(const_int 0)]
3052   "ix86_split_long_move (operands); DONE;")
3053 \f
3054 ;; Zero extension instructions
3055
3056 (define_expand "zero_extendhisi2"
3057   [(set (match_operand:SI 0 "register_operand" "")
3058      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3059   ""
3060 {
3061   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3062     {
3063       operands[1] = force_reg (HImode, operands[1]);
3064       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3065       DONE;
3066     }
3067 })
3068
3069 (define_insn "zero_extendhisi2_and"
3070   [(set (match_operand:SI 0 "register_operand" "=r")
3071      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3072    (clobber (reg:CC FLAGS_REG))]
3073   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3074   "#"
3075   [(set_attr "type" "alu1")
3076    (set_attr "mode" "SI")])
3077
3078 (define_split
3079   [(set (match_operand:SI 0 "register_operand" "")
3080         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3081    (clobber (reg:CC FLAGS_REG))]
3082   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3083   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3084               (clobber (reg:CC FLAGS_REG))])]
3085   "")
3086
3087 (define_insn "*zero_extendhisi2_movzwl"
3088   [(set (match_operand:SI 0 "register_operand" "=r")
3089      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3090   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3091   "movz{wl|x}\t{%1, %0|%0, %1}"
3092   [(set_attr "type" "imovx")
3093    (set_attr "mode" "SI")])
3094
3095 (define_expand "zero_extendqihi2"
3096   [(parallel
3097     [(set (match_operand:HI 0 "register_operand" "")
3098        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3099      (clobber (reg:CC FLAGS_REG))])]
3100   ""
3101   "")
3102
3103 (define_insn "*zero_extendqihi2_and"
3104   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3105      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3106    (clobber (reg:CC FLAGS_REG))]
3107   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3108   "#"
3109   [(set_attr "type" "alu1")
3110    (set_attr "mode" "HI")])
3111
3112 (define_insn "*zero_extendqihi2_movzbw_and"
3113   [(set (match_operand:HI 0 "register_operand" "=r,r")
3114      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3115    (clobber (reg:CC FLAGS_REG))]
3116   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3117   "#"
3118   [(set_attr "type" "imovx,alu1")
3119    (set_attr "mode" "HI")])
3120
3121 ; zero extend to SImode here to avoid partial register stalls
3122 (define_insn "*zero_extendqihi2_movzbl"
3123   [(set (match_operand:HI 0 "register_operand" "=r")
3124      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3125   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3126   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3127   [(set_attr "type" "imovx")
3128    (set_attr "mode" "SI")])
3129
3130 ;; For the movzbw case strip only the clobber
3131 (define_split
3132   [(set (match_operand:HI 0 "register_operand" "")
3133         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3134    (clobber (reg:CC FLAGS_REG))]
3135   "reload_completed
3136    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3137    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3138   [(set (match_operand:HI 0 "register_operand" "")
3139         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3140
3141 ;; When source and destination does not overlap, clear destination
3142 ;; first and then do the movb
3143 (define_split
3144   [(set (match_operand:HI 0 "register_operand" "")
3145         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3146    (clobber (reg:CC FLAGS_REG))]
3147   "reload_completed
3148    && ANY_QI_REG_P (operands[0])
3149    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3150    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3151   [(set (match_dup 0) (const_int 0))
3152    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3153   "operands[2] = gen_lowpart (QImode, operands[0]);")
3154
3155 ;; Rest is handled by single and.
3156 (define_split
3157   [(set (match_operand:HI 0 "register_operand" "")
3158         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3159    (clobber (reg:CC FLAGS_REG))]
3160   "reload_completed
3161    && true_regnum (operands[0]) == true_regnum (operands[1])"
3162   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3163               (clobber (reg:CC FLAGS_REG))])]
3164   "")
3165
3166 (define_expand "zero_extendqisi2"
3167   [(parallel
3168     [(set (match_operand:SI 0 "register_operand" "")
3169        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3170      (clobber (reg:CC FLAGS_REG))])]
3171   ""
3172   "")
3173
3174 (define_insn "*zero_extendqisi2_and"
3175   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3176      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3177    (clobber (reg:CC FLAGS_REG))]
3178   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3179   "#"
3180   [(set_attr "type" "alu1")
3181    (set_attr "mode" "SI")])
3182
3183 (define_insn "*zero_extendqisi2_movzbw_and"
3184   [(set (match_operand:SI 0 "register_operand" "=r,r")
3185      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3186    (clobber (reg:CC FLAGS_REG))]
3187   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3188   "#"
3189   [(set_attr "type" "imovx,alu1")
3190    (set_attr "mode" "SI")])
3191
3192 (define_insn "*zero_extendqisi2_movzbw"
3193   [(set (match_operand:SI 0 "register_operand" "=r")
3194      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3195   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3196   "movz{bl|x}\t{%1, %0|%0, %1}"
3197   [(set_attr "type" "imovx")
3198    (set_attr "mode" "SI")])
3199
3200 ;; For the movzbl case strip only the clobber
3201 (define_split
3202   [(set (match_operand:SI 0 "register_operand" "")
3203         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3204    (clobber (reg:CC FLAGS_REG))]
3205   "reload_completed
3206    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3207    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3208   [(set (match_dup 0)
3209         (zero_extend:SI (match_dup 1)))])
3210
3211 ;; When source and destination does not overlap, clear destination
3212 ;; first and then do the movb
3213 (define_split
3214   [(set (match_operand:SI 0 "register_operand" "")
3215         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3216    (clobber (reg:CC FLAGS_REG))]
3217   "reload_completed
3218    && ANY_QI_REG_P (operands[0])
3219    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3220    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3221    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3222   [(set (match_dup 0) (const_int 0))
3223    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3224   "operands[2] = gen_lowpart (QImode, operands[0]);")
3225
3226 ;; Rest is handled by single and.
3227 (define_split
3228   [(set (match_operand:SI 0 "register_operand" "")
3229         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3230    (clobber (reg:CC FLAGS_REG))]
3231   "reload_completed
3232    && true_regnum (operands[0]) == true_regnum (operands[1])"
3233   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3234               (clobber (reg:CC FLAGS_REG))])]
3235   "")
3236
3237 ;; %%% Kill me once multi-word ops are sane.
3238 (define_expand "zero_extendsidi2"
3239   [(set (match_operand:DI 0 "register_operand" "=r")
3240      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3241   ""
3242   "if (!TARGET_64BIT)
3243      {
3244        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3245        DONE;
3246      }
3247   ")
3248
3249 (define_insn "zero_extendsidi2_32"
3250   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3251         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3252    (clobber (reg:CC FLAGS_REG))]
3253   "!TARGET_64BIT"
3254   "@
3255    #
3256    #
3257    #
3258    movd\t{%1, %0|%0, %1}
3259    movd\t{%1, %0|%0, %1}"
3260   [(set_attr "mode" "SI,SI,SI,DI,TI")
3261    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3262
3263 (define_insn "zero_extendsidi2_rex64"
3264   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3265      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3266   "TARGET_64BIT"
3267   "@
3268    mov\t{%k1, %k0|%k0, %k1}
3269    #
3270    movd\t{%1, %0|%0, %1}
3271    movd\t{%1, %0|%0, %1}"
3272   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3273    (set_attr "mode" "SI,DI,SI,SI")])
3274
3275 (define_split
3276   [(set (match_operand:DI 0 "memory_operand" "")
3277      (zero_extend:DI (match_dup 0)))]
3278   "TARGET_64BIT"
3279   [(set (match_dup 4) (const_int 0))]
3280   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3281
3282 (define_split
3283   [(set (match_operand:DI 0 "register_operand" "")
3284         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3285    (clobber (reg:CC FLAGS_REG))]
3286   "!TARGET_64BIT && reload_completed
3287    && true_regnum (operands[0]) == true_regnum (operands[1])"
3288   [(set (match_dup 4) (const_int 0))]
3289   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3290
3291 (define_split
3292   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3293         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3294    (clobber (reg:CC FLAGS_REG))]
3295   "!TARGET_64BIT && reload_completed
3296    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3297   [(set (match_dup 3) (match_dup 1))
3298    (set (match_dup 4) (const_int 0))]
3299   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3300
3301 (define_insn "zero_extendhidi2"
3302   [(set (match_operand:DI 0 "register_operand" "=r")
3303      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3304   "TARGET_64BIT"
3305   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3306   [(set_attr "type" "imovx")
3307    (set_attr "mode" "DI")])
3308
3309 (define_insn "zero_extendqidi2"
3310   [(set (match_operand:DI 0 "register_operand" "=r")
3311      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3312   "TARGET_64BIT"
3313   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3314   [(set_attr "type" "imovx")
3315    (set_attr "mode" "DI")])
3316 \f
3317 ;; Sign extension instructions
3318
3319 (define_expand "extendsidi2"
3320   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3321                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3322               (clobber (reg:CC FLAGS_REG))
3323               (clobber (match_scratch:SI 2 ""))])]
3324   ""
3325 {
3326   if (TARGET_64BIT)
3327     {
3328       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3329       DONE;
3330     }
3331 })
3332
3333 (define_insn "*extendsidi2_1"
3334   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3335         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3336    (clobber (reg:CC FLAGS_REG))
3337    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3338   "!TARGET_64BIT"
3339   "#")
3340
3341 (define_insn "extendsidi2_rex64"
3342   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3343         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3344   "TARGET_64BIT"
3345   "@
3346    {cltq|cdqe}
3347    movs{lq|x}\t{%1,%0|%0, %1}"
3348   [(set_attr "type" "imovx")
3349    (set_attr "mode" "DI")
3350    (set_attr "prefix_0f" "0")
3351    (set_attr "modrm" "0,1")])
3352
3353 (define_insn "extendhidi2"
3354   [(set (match_operand:DI 0 "register_operand" "=r")
3355         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3356   "TARGET_64BIT"
3357   "movs{wq|x}\t{%1,%0|%0, %1}"
3358   [(set_attr "type" "imovx")
3359    (set_attr "mode" "DI")])
3360
3361 (define_insn "extendqidi2"
3362   [(set (match_operand:DI 0 "register_operand" "=r")
3363         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3364   "TARGET_64BIT"
3365   "movs{bq|x}\t{%1,%0|%0, %1}"
3366    [(set_attr "type" "imovx")
3367     (set_attr "mode" "DI")])
3368
3369 ;; Extend to memory case when source register does die.
3370 (define_split
3371   [(set (match_operand:DI 0 "memory_operand" "")
3372         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3373    (clobber (reg:CC FLAGS_REG))
3374    (clobber (match_operand:SI 2 "register_operand" ""))]
3375   "(reload_completed
3376     && dead_or_set_p (insn, operands[1])
3377     && !reg_mentioned_p (operands[1], operands[0]))"
3378   [(set (match_dup 3) (match_dup 1))
3379    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3380               (clobber (reg:CC FLAGS_REG))])
3381    (set (match_dup 4) (match_dup 1))]
3382   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3383
3384 ;; Extend to memory case when source register does not die.
3385 (define_split
3386   [(set (match_operand:DI 0 "memory_operand" "")
3387         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3388    (clobber (reg:CC FLAGS_REG))
3389    (clobber (match_operand:SI 2 "register_operand" ""))]
3390   "reload_completed"
3391   [(const_int 0)]
3392 {
3393   split_di (&operands[0], 1, &operands[3], &operands[4]);
3394
3395   emit_move_insn (operands[3], operands[1]);
3396
3397   /* Generate a cltd if possible and doing so it profitable.  */
3398   if (true_regnum (operands[1]) == 0
3399       && true_regnum (operands[2]) == 1
3400       && (optimize_size || TARGET_USE_CLTD))
3401     {
3402       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3403     }
3404   else
3405     {
3406       emit_move_insn (operands[2], operands[1]);
3407       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3408     }
3409   emit_move_insn (operands[4], operands[2]);
3410   DONE;
3411 })
3412
3413 ;; Extend to register case.  Optimize case where source and destination
3414 ;; registers match and cases where we can use cltd.
3415 (define_split
3416   [(set (match_operand:DI 0 "register_operand" "")
3417         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3418    (clobber (reg:CC FLAGS_REG))
3419    (clobber (match_scratch:SI 2 ""))]
3420   "reload_completed"
3421   [(const_int 0)]
3422 {
3423   split_di (&operands[0], 1, &operands[3], &operands[4]);
3424
3425   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3426     emit_move_insn (operands[3], operands[1]);
3427
3428   /* Generate a cltd if possible and doing so it profitable.  */
3429   if (true_regnum (operands[3]) == 0
3430       && (optimize_size || TARGET_USE_CLTD))
3431     {
3432       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3433       DONE;
3434     }
3435
3436   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3437     emit_move_insn (operands[4], operands[1]);
3438
3439   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3440   DONE;
3441 })
3442
3443 (define_insn "extendhisi2"
3444   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3445         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3446   ""
3447 {
3448   switch (get_attr_prefix_0f (insn))
3449     {
3450     case 0:
3451       return "{cwtl|cwde}";
3452     default:
3453       return "movs{wl|x}\t{%1,%0|%0, %1}";
3454     }
3455 }
3456   [(set_attr "type" "imovx")
3457    (set_attr "mode" "SI")
3458    (set (attr "prefix_0f")
3459      ;; movsx is short decodable while cwtl is vector decoded.
3460      (if_then_else (and (eq_attr "cpu" "!k6")
3461                         (eq_attr "alternative" "0"))
3462         (const_string "0")
3463         (const_string "1")))
3464    (set (attr "modrm")
3465      (if_then_else (eq_attr "prefix_0f" "0")
3466         (const_string "0")
3467         (const_string "1")))])
3468
3469 (define_insn "*extendhisi2_zext"
3470   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3471         (zero_extend:DI
3472           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3473   "TARGET_64BIT"
3474 {
3475   switch (get_attr_prefix_0f (insn))
3476     {
3477     case 0:
3478       return "{cwtl|cwde}";
3479     default:
3480       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3481     }
3482 }
3483   [(set_attr "type" "imovx")
3484    (set_attr "mode" "SI")
3485    (set (attr "prefix_0f")
3486      ;; movsx is short decodable while cwtl is vector decoded.
3487      (if_then_else (and (eq_attr "cpu" "!k6")
3488                         (eq_attr "alternative" "0"))
3489         (const_string "0")
3490         (const_string "1")))
3491    (set (attr "modrm")
3492      (if_then_else (eq_attr "prefix_0f" "0")
3493         (const_string "0")
3494         (const_string "1")))])
3495
3496 (define_insn "extendqihi2"
3497   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3498         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3499   ""
3500 {
3501   switch (get_attr_prefix_0f (insn))
3502     {
3503     case 0:
3504       return "{cbtw|cbw}";
3505     default:
3506       return "movs{bw|x}\t{%1,%0|%0, %1}";
3507     }
3508 }
3509   [(set_attr "type" "imovx")
3510    (set_attr "mode" "HI")
3511    (set (attr "prefix_0f")
3512      ;; movsx is short decodable while cwtl is vector decoded.
3513      (if_then_else (and (eq_attr "cpu" "!k6")
3514                         (eq_attr "alternative" "0"))
3515         (const_string "0")
3516         (const_string "1")))
3517    (set (attr "modrm")
3518      (if_then_else (eq_attr "prefix_0f" "0")
3519         (const_string "0")
3520         (const_string "1")))])
3521
3522 (define_insn "extendqisi2"
3523   [(set (match_operand:SI 0 "register_operand" "=r")
3524         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3525   ""
3526   "movs{bl|x}\t{%1,%0|%0, %1}"
3527    [(set_attr "type" "imovx")
3528     (set_attr "mode" "SI")])
3529
3530 (define_insn "*extendqisi2_zext"
3531   [(set (match_operand:DI 0 "register_operand" "=r")
3532         (zero_extend:DI
3533           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3534   "TARGET_64BIT"
3535   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3536    [(set_attr "type" "imovx")
3537     (set_attr "mode" "SI")])
3538 \f
3539 ;; Conversions between float and double.
3540
3541 ;; These are all no-ops in the model used for the 80387.  So just
3542 ;; emit moves.
3543
3544 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3545 (define_insn "*dummy_extendsfdf2"
3546   [(set (match_operand:DF 0 "push_operand" "=<")
3547         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3548   "0"
3549   "#")
3550
3551 (define_split
3552   [(set (match_operand:DF 0 "push_operand" "")
3553         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3554   "!TARGET_64BIT"
3555   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3556    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3557
3558 (define_split
3559   [(set (match_operand:DF 0 "push_operand" "")
3560         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3561   "TARGET_64BIT"
3562   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3563    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3564
3565 (define_insn "*dummy_extendsfxf2"
3566   [(set (match_operand:XF 0 "push_operand" "=<")
3567         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3568   "0"
3569   "#")
3570
3571 (define_split
3572   [(set (match_operand:XF 0 "push_operand" "")
3573         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3574   ""
3575   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3576    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3577   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3578
3579 (define_split
3580   [(set (match_operand:XF 0 "push_operand" "")
3581         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3582   "TARGET_64BIT"
3583   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3584    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3585   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3586
3587 (define_split
3588   [(set (match_operand:XF 0 "push_operand" "")
3589         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3590   ""
3591   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3592    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3593   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3594
3595 (define_split
3596   [(set (match_operand:XF 0 "push_operand" "")
3597         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3598   "TARGET_64BIT"
3599   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3600    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3601   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3602
3603 (define_expand "extendsfdf2"
3604   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3605         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3606   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3607 {
3608   /* ??? Needed for compress_float_constant since all fp constants
3609      are LEGITIMATE_CONSTANT_P.  */
3610   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3611     {
3612       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3613           && standard_80387_constant_p (operands[1]) > 0)
3614         {
3615           operands[1] = simplify_const_unary_operation
3616             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3617           emit_move_insn_1 (operands[0], operands[1]);
3618           DONE;
3619         }
3620       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3621     }
3622 })
3623
3624 (define_insn "*extendsfdf2_mixed"
3625   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3626         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3627   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3628 {
3629   switch (which_alternative)
3630     {
3631     case 0:
3632       return output_387_reg_move (insn, operands);
3633
3634     case 1:
3635       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3636         return "fstp%z0\t%y0";
3637       else
3638         return "fst%z0\t%y0";
3639
3640     case 2:
3641       return "cvtss2sd\t{%1, %0|%0, %1}";
3642
3643     default:
3644       gcc_unreachable ();
3645     }
3646 }
3647   [(set_attr "type" "fmov,fmov,ssecvt")
3648    (set_attr "mode" "SF,XF,DF")])
3649
3650 (define_insn "*extendsfdf2_sse"
3651   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3652         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3653   "TARGET_SSE2 && TARGET_SSE_MATH"
3654   "cvtss2sd\t{%1, %0|%0, %1}"
3655   [(set_attr "type" "ssecvt")
3656    (set_attr "mode" "DF")])
3657
3658 (define_insn "*extendsfdf2_i387"
3659   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3660         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3661   "TARGET_80387"
3662 {
3663   switch (which_alternative)
3664     {
3665     case 0:
3666       return output_387_reg_move (insn, operands);
3667
3668     case 1:
3669       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3670         return "fstp%z0\t%y0";
3671       else
3672         return "fst%z0\t%y0";
3673
3674     default:
3675       gcc_unreachable ();
3676     }
3677 }
3678   [(set_attr "type" "fmov")
3679    (set_attr "mode" "SF,XF")])
3680
3681 (define_expand "extendsfxf2"
3682   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3683         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3684   "TARGET_80387"
3685 {
3686   /* ??? Needed for compress_float_constant since all fp constants
3687      are LEGITIMATE_CONSTANT_P.  */
3688   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3689     {
3690       if (standard_80387_constant_p (operands[1]) > 0)
3691         {
3692           operands[1] = simplify_const_unary_operation
3693             (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3694           emit_move_insn_1 (operands[0], operands[1]);
3695           DONE;
3696         }
3697       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3698     }
3699 })
3700
3701 (define_insn "*extendsfxf2_i387"
3702   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3703         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3704   "TARGET_80387"
3705 {
3706   switch (which_alternative)
3707     {
3708     case 0:
3709       return output_387_reg_move (insn, operands);
3710
3711     case 1:
3712       /* There is no non-popping store to memory for XFmode.  So if
3713          we need one, follow the store with a load.  */
3714       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3715         return "fstp%z0\t%y0";
3716       else
3717         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3718
3719     default:
3720       gcc_unreachable ();
3721     }
3722 }
3723   [(set_attr "type" "fmov")
3724    (set_attr "mode" "SF,XF")])
3725
3726 (define_expand "extenddfxf2"
3727   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3728         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3729   "TARGET_80387"
3730 {
3731   /* ??? Needed for compress_float_constant since all fp constants
3732      are LEGITIMATE_CONSTANT_P.  */
3733   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3734     {
3735       if (standard_80387_constant_p (operands[1]) > 0)
3736         {
3737           operands[1] = simplify_const_unary_operation
3738             (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3739           emit_move_insn_1 (operands[0], operands[1]);
3740           DONE;
3741         }
3742       operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3743     }
3744 })
3745
3746 (define_insn "*extenddfxf2_i387"
3747   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3748         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3749   "TARGET_80387"
3750 {
3751   switch (which_alternative)
3752     {
3753     case 0:
3754       return output_387_reg_move (insn, operands);
3755
3756     case 1:
3757       /* There is no non-popping store to memory for XFmode.  So if
3758          we need one, follow the store with a load.  */
3759       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3760         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3761       else
3762         return "fstp%z0\t%y0";
3763
3764     default:
3765       gcc_unreachable ();
3766     }
3767 }
3768   [(set_attr "type" "fmov")
3769    (set_attr "mode" "DF,XF")])
3770
3771 ;; %%% This seems bad bad news.
3772 ;; This cannot output into an f-reg because there is no way to be sure
3773 ;; of truncating in that case.  Otherwise this is just like a simple move
3774 ;; insn.  So we pretend we can output to a reg in order to get better
3775 ;; register preferencing, but we really use a stack slot.
3776
3777 ;; Conversion from DFmode to SFmode.
3778
3779 (define_expand "truncdfsf2"
3780   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3781         (float_truncate:SF
3782           (match_operand:DF 1 "nonimmediate_operand" "")))]
3783   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3784 {
3785   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3786     ;
3787   else if (flag_unsafe_math_optimizations)
3788     ;
3789   else
3790     {
3791       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3792       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3793       DONE;
3794     }
3795 })
3796
3797 (define_expand "truncdfsf2_with_temp"
3798   [(parallel [(set (match_operand:SF 0 "" "")
3799                    (float_truncate:SF (match_operand:DF 1 "" "")))
3800               (clobber (match_operand:SF 2 "" ""))])]
3801   "")
3802
3803 (define_insn "*truncdfsf_fast_mixed"
3804   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3805         (float_truncate:SF
3806           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3807   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3808 {
3809   switch (which_alternative)
3810     {
3811     case 0:
3812       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3813         return "fstp%z0\t%y0";
3814       else
3815         return "fst%z0\t%y0";
3816     case 1:
3817       return output_387_reg_move (insn, operands);
3818     case 2:
3819       return "cvtsd2ss\t{%1, %0|%0, %1}";
3820     default:
3821       gcc_unreachable ();
3822     }
3823 }
3824   [(set_attr "type" "fmov,fmov,ssecvt")
3825    (set_attr "mode" "SF")])
3826
3827 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3828 ;; because nothing we do here is unsafe.
3829 (define_insn "*truncdfsf_fast_sse"
3830   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3831         (float_truncate:SF
3832           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3833   "TARGET_SSE2 && TARGET_SSE_MATH"
3834   "cvtsd2ss\t{%1, %0|%0, %1}"
3835   [(set_attr "type" "ssecvt")
3836    (set_attr "mode" "SF")])
3837
3838 (define_insn "*truncdfsf_fast_i387"
3839   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3840         (float_truncate:SF
3841           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3842   "TARGET_80387 && flag_unsafe_math_optimizations"
3843   "* return output_387_reg_move (insn, operands);"
3844   [(set_attr "type" "fmov")
3845    (set_attr "mode" "SF")])
3846
3847 (define_insn "*truncdfsf_mixed"
3848   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3849         (float_truncate:SF
3850           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3851    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3852   "TARGET_MIX_SSE_I387"
3853 {
3854   switch (which_alternative)
3855     {
3856     case 0:
3857       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3858         return "fstp%z0\t%y0";
3859       else
3860         return "fst%z0\t%y0";
3861     case 1:
3862       return "#";
3863     case 2:
3864       return "cvtsd2ss\t{%1, %0|%0, %1}";
3865     default:
3866       gcc_unreachable ();
3867     }
3868 }
3869   [(set_attr "type" "fmov,multi,ssecvt")
3870    (set_attr "unit" "*,i387,*")
3871    (set_attr "mode" "SF")])
3872
3873 (define_insn "*truncdfsf_i387"
3874   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3875         (float_truncate:SF
3876           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3877    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3878   "TARGET_80387"
3879 {
3880   switch (which_alternative)
3881     {
3882     case 0:
3883       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3884         return "fstp%z0\t%y0";
3885       else
3886         return "fst%z0\t%y0";
3887     case 1:
3888       return "#";
3889     default:
3890       gcc_unreachable ();
3891     }
3892 }
3893   [(set_attr "type" "fmov,multi")
3894    (set_attr "unit" "*,i387")
3895    (set_attr "mode" "SF")])
3896
3897 (define_insn "*truncdfsf2_i387_1"
3898   [(set (match_operand:SF 0 "memory_operand" "=m")
3899         (float_truncate:SF
3900           (match_operand:DF 1 "register_operand" "f")))]
3901   "TARGET_80387
3902    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3903    && !TARGET_MIX_SSE_I387"
3904 {
3905   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3906     return "fstp%z0\t%y0";
3907   else
3908     return "fst%z0\t%y0";
3909 }
3910   [(set_attr "type" "fmov")
3911    (set_attr "mode" "SF")])
3912
3913 (define_split
3914   [(set (match_operand:SF 0 "register_operand" "")
3915         (float_truncate:SF
3916          (match_operand:DF 1 "fp_register_operand" "")))
3917    (clobber (match_operand 2 "" ""))]
3918   "reload_completed"
3919   [(set (match_dup 2) (match_dup 1))
3920    (set (match_dup 0) (match_dup 2))]
3921 {
3922   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3923 })
3924
3925 ;; Conversion from XFmode to SFmode.
3926
3927 (define_expand "truncxfsf2"
3928   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3929                    (float_truncate:SF
3930                     (match_operand:XF 1 "register_operand" "")))
3931               (clobber (match_dup 2))])]
3932   "TARGET_80387"
3933 {
3934   if (flag_unsafe_math_optimizations)
3935     {
3936       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3937       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3938       if (reg != operands[0])
3939         emit_move_insn (operands[0], reg);
3940       DONE;
3941     }
3942   else
3943     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3944 })
3945
3946 (define_insn "*truncxfsf2_mixed"
3947   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3948         (float_truncate:SF
3949          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3950    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3951   "TARGET_80387"
3952 {
3953   gcc_assert (!which_alternative);
3954   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3955     return "fstp%z0\t%y0";
3956   else
3957     return "fst%z0\t%y0";
3958 }
3959   [(set_attr "type" "fmov,multi,multi,multi")
3960    (set_attr "unit" "*,i387,i387,i387")
3961    (set_attr "mode" "SF")])
3962
3963 (define_insn "truncxfsf2_i387_noop"
3964   [(set (match_operand:SF 0 "register_operand" "=f")
3965         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3966   "TARGET_80387 && flag_unsafe_math_optimizations"
3967   "* return output_387_reg_move (insn, operands);"
3968   [(set_attr "type" "fmov")
3969    (set_attr "mode" "SF")])
3970
3971 (define_insn "*truncxfsf2_i387"
3972   [(set (match_operand:SF 0 "memory_operand" "=m")
3973         (float_truncate:SF
3974          (match_operand:XF 1 "register_operand" "f")))]
3975   "TARGET_80387"
3976 {
3977   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3978     return "fstp%z0\t%y0";
3979   else
3980     return "fst%z0\t%y0";
3981 }
3982   [(set_attr "type" "fmov")
3983    (set_attr "mode" "SF")])
3984
3985 (define_split
3986   [(set (match_operand:SF 0 "register_operand" "")
3987         (float_truncate:SF
3988          (match_operand:XF 1 "register_operand" "")))
3989    (clobber (match_operand:SF 2 "memory_operand" ""))]
3990   "TARGET_80387 && reload_completed"
3991   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3992    (set (match_dup 0) (match_dup 2))]
3993   "")
3994
3995 (define_split
3996   [(set (match_operand:SF 0 "memory_operand" "")
3997         (float_truncate:SF
3998          (match_operand:XF 1 "register_operand" "")))
3999    (clobber (match_operand:SF 2 "memory_operand" ""))]
4000   "TARGET_80387"
4001   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4002   "")
4003
4004 ;; Conversion from XFmode to DFmode.
4005
4006 (define_expand "truncxfdf2"
4007   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4008                    (float_truncate:DF
4009                     (match_operand:XF 1 "register_operand" "")))
4010               (clobber (match_dup 2))])]
4011   "TARGET_80387"
4012 {
4013   if (flag_unsafe_math_optimizations)
4014     {
4015       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
4016       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
4017       if (reg != operands[0])
4018         emit_move_insn (operands[0], reg);
4019       DONE;
4020     }
4021   else
4022     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
4023 })
4024
4025 (define_insn "*truncxfdf2_mixed"
4026   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
4027         (float_truncate:DF
4028          (match_operand:XF 1 "register_operand" "f,f,f,f")))
4029    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4030   "TARGET_80387"
4031 {
4032   gcc_assert (!which_alternative);
4033   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4034     return "fstp%z0\t%y0";
4035   else
4036     return "fst%z0\t%y0";
4037 }
4038   [(set_attr "type" "fmov,multi,multi,multi")
4039    (set_attr "unit" "*,i387,i387,i387")
4040    (set_attr "mode" "DF")])
4041
4042 (define_insn "truncxfdf2_i387_noop"
4043   [(set (match_operand:DF 0 "register_operand" "=f")
4044         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4045   "TARGET_80387 && flag_unsafe_math_optimizations"
4046   "* return output_387_reg_move (insn, operands);"
4047   [(set_attr "type" "fmov")
4048    (set_attr "mode" "DF")])
4049
4050 (define_insn "*truncxfdf2_i387"
4051   [(set (match_operand:DF 0 "memory_operand" "=m")
4052         (float_truncate:DF
4053           (match_operand:XF 1 "register_operand" "f")))]
4054   "TARGET_80387"
4055 {
4056   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4057     return "fstp%z0\t%y0";
4058   else
4059     return "fst%z0\t%y0";
4060 }
4061   [(set_attr "type" "fmov")
4062    (set_attr "mode" "DF")])
4063
4064 (define_split
4065   [(set (match_operand:DF 0 "register_operand" "")
4066         (float_truncate:DF
4067          (match_operand:XF 1 "register_operand" "")))
4068    (clobber (match_operand:DF 2 "memory_operand" ""))]
4069   "TARGET_80387 && reload_completed"
4070   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4071    (set (match_dup 0) (match_dup 2))]
4072   "")
4073
4074 (define_split
4075   [(set (match_operand:DF 0 "memory_operand" "")
4076         (float_truncate:DF
4077          (match_operand:XF 1 "register_operand" "")))
4078    (clobber (match_operand:DF 2 "memory_operand" ""))]
4079   "TARGET_80387"
4080   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4081   "")
4082 \f
4083 ;; Signed conversion to DImode.
4084
4085 (define_expand "fix_truncxfdi2"
4086   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4087                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4088               (clobber (reg:CC FLAGS_REG))])]
4089   "TARGET_80387"
4090 {
4091   if (TARGET_FISTTP)
4092    {
4093      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4094      DONE;
4095    }
4096 })
4097
4098 (define_expand "fix_trunc<mode>di2"
4099   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4100                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4101               (clobber (reg:CC FLAGS_REG))])]
4102   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4103 {
4104   if (TARGET_FISTTP
4105       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4106    {
4107      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4108      DONE;
4109    }
4110   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4111    {
4112      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4113      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4114      if (out != operands[0])
4115         emit_move_insn (operands[0], out);
4116      DONE;
4117    }
4118 })
4119
4120 ;; Signed conversion to SImode.
4121
4122 (define_expand "fix_truncxfsi2"
4123   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4124                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4125               (clobber (reg:CC FLAGS_REG))])]
4126   "TARGET_80387"
4127 {
4128   if (TARGET_FISTTP)
4129    {
4130      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4131      DONE;
4132    }
4133 })
4134
4135 (define_expand "fix_trunc<mode>si2"
4136   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4137                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4138               (clobber (reg:CC FLAGS_REG))])]
4139   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4140 {
4141   if (TARGET_FISTTP
4142       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4143    {
4144      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4145      DONE;
4146    }
4147   if (SSE_FLOAT_MODE_P (<MODE>mode))
4148    {
4149      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4150      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4151      if (out != operands[0])
4152         emit_move_insn (operands[0], out);
4153      DONE;
4154    }
4155 })
4156
4157 ;; Signed conversion to HImode.
4158
4159 (define_expand "fix_trunc<mode>hi2"
4160   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4161                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4162               (clobber (reg:CC FLAGS_REG))])]
4163   "TARGET_80387
4164    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4165 {
4166   if (TARGET_FISTTP)
4167    {
4168      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4169      DONE;
4170    }
4171 })
4172
4173 ;; When SSE is available, it is always faster to use it!
4174 (define_insn "fix_truncsfdi_sse"
4175   [(set (match_operand:DI 0 "register_operand" "=r,r")
4176         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4177   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4178   "cvttss2si{q}\t{%1, %0|%0, %1}"
4179   [(set_attr "type" "sseicvt")
4180    (set_attr "mode" "SF")
4181    (set_attr "athlon_decode" "double,vector")])
4182
4183 (define_insn "fix_truncdfdi_sse"
4184   [(set (match_operand:DI 0 "register_operand" "=r,r")
4185         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4186   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4187   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4188   [(set_attr "type" "sseicvt")
4189    (set_attr "mode" "DF")
4190    (set_attr "athlon_decode" "double,vector")])
4191
4192 (define_insn "fix_truncsfsi_sse"
4193   [(set (match_operand:SI 0 "register_operand" "=r,r")
4194         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4195   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4196   "cvttss2si\t{%1, %0|%0, %1}"
4197   [(set_attr "type" "sseicvt")
4198    (set_attr "mode" "DF")
4199    (set_attr "athlon_decode" "double,vector")])
4200
4201 (define_insn "fix_truncdfsi_sse"
4202   [(set (match_operand:SI 0 "register_operand" "=r,r")
4203         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4204   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4205   "cvttsd2si\t{%1, %0|%0, %1}"
4206   [(set_attr "type" "sseicvt")
4207    (set_attr "mode" "DF")
4208    (set_attr "athlon_decode" "double,vector")])
4209
4210 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4211 (define_peephole2
4212   [(set (match_operand:DF 0 "register_operand" "")
4213         (match_operand:DF 1 "memory_operand" ""))
4214    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4215         (fix:SSEMODEI24 (match_dup 0)))]
4216   "!TARGET_K8
4217    && peep2_reg_dead_p (2, operands[0])"
4218   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4219   "")
4220
4221 (define_peephole2
4222   [(set (match_operand:SF 0 "register_operand" "")
4223         (match_operand:SF 1 "memory_operand" ""))
4224    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4225         (fix:SSEMODEI24 (match_dup 0)))]
4226   "!TARGET_K8
4227    && peep2_reg_dead_p (2, operands[0])"
4228   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4229   "")
4230
4231 ;; Avoid vector decoded forms of the instruction.
4232 (define_peephole2
4233   [(match_scratch:DF 2 "Y")
4234    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4235         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4236   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4237   [(set (match_dup 2) (match_dup 1))
4238    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4239   "")
4240
4241 (define_peephole2
4242   [(match_scratch:SF 2 "x")
4243    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4244         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4245   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4246   [(set (match_dup 2) (match_dup 1))
4247    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4248   "")
4249
4250 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4251   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4252         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4253   "TARGET_FISTTP
4254    && FLOAT_MODE_P (GET_MODE (operands[1]))
4255    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4256          && (TARGET_64BIT || <MODE>mode != DImode))
4257         && TARGET_SSE_MATH)
4258    && !(reload_completed || reload_in_progress)"
4259   "#"
4260   "&& 1"
4261   [(const_int 0)]
4262 {
4263   if (memory_operand (operands[0], VOIDmode))
4264     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4265   else
4266     {
4267       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4268       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4269                                                             operands[1],
4270                                                             operands[2]));
4271     }
4272   DONE;
4273 }
4274   [(set_attr "type" "fisttp")
4275    (set_attr "mode" "<MODE>")])
4276
4277 (define_insn "fix_trunc<mode>_i387_fisttp"
4278   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4279         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4280    (clobber (match_scratch:XF 2 "=&1f"))]
4281   "TARGET_FISTTP
4282    && FLOAT_MODE_P (GET_MODE (operands[1]))
4283    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4284          && (TARGET_64BIT || <MODE>mode != DImode))
4285         && TARGET_SSE_MATH)"
4286   "* return output_fix_trunc (insn, operands, 1);"
4287   [(set_attr "type" "fisttp")
4288    (set_attr "mode" "<MODE>")])
4289
4290 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4291   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4292         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4293    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4294    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4295   "TARGET_FISTTP
4296    && FLOAT_MODE_P (GET_MODE (operands[1]))
4297    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4298         && (TARGET_64BIT || <MODE>mode != DImode))
4299         && TARGET_SSE_MATH)"
4300   "#"
4301   [(set_attr "type" "fisttp")
4302    (set_attr "mode" "<MODE>")])
4303
4304 (define_split
4305   [(set (match_operand:X87MODEI 0 "register_operand" "")
4306         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4307    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4308    (clobber (match_scratch 3 ""))]
4309   "reload_completed"
4310   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4311               (clobber (match_dup 3))])
4312    (set (match_dup 0) (match_dup 2))]
4313   "")
4314
4315 (define_split
4316   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4317         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4318    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4319    (clobber (match_scratch 3 ""))]
4320   "reload_completed"
4321   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4322               (clobber (match_dup 3))])]
4323   "")
4324
4325 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4326 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4327 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4328 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4329 ;; function in i386.c.
4330 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4331   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4332         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4333    (clobber (reg:CC FLAGS_REG))]
4334   "TARGET_80387 && !TARGET_FISTTP
4335    && FLOAT_MODE_P (GET_MODE (operands[1]))
4336    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4337          && (TARGET_64BIT || <MODE>mode != DImode))
4338    && !(reload_completed || reload_in_progress)"
4339   "#"
4340   "&& 1"
4341   [(const_int 0)]
4342 {
4343   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4344
4345   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4346   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4347   if (memory_operand (operands[0], VOIDmode))
4348     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4349                                          operands[2], operands[3]));
4350   else
4351     {
4352       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4353       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4354                                                      operands[2], operands[3],
4355                                                      operands[4]));
4356     }
4357   DONE;
4358 }
4359   [(set_attr "type" "fistp")
4360    (set_attr "i387_cw" "trunc")
4361    (set_attr "mode" "<MODE>")])
4362
4363 (define_insn "fix_truncdi_i387"
4364   [(set (match_operand:DI 0 "memory_operand" "=m")
4365         (fix:DI (match_operand 1 "register_operand" "f")))
4366    (use (match_operand:HI 2 "memory_operand" "m"))
4367    (use (match_operand:HI 3 "memory_operand" "m"))
4368    (clobber (match_scratch:XF 4 "=&1f"))]
4369   "TARGET_80387 && !TARGET_FISTTP
4370    && FLOAT_MODE_P (GET_MODE (operands[1]))
4371    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4372   "* return output_fix_trunc (insn, operands, 0);"
4373   [(set_attr "type" "fistp")
4374    (set_attr "i387_cw" "trunc")
4375    (set_attr "mode" "DI")])
4376
4377 (define_insn "fix_truncdi_i387_with_temp"
4378   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4379         (fix:DI (match_operand 1 "register_operand" "f,f")))
4380    (use (match_operand:HI 2 "memory_operand" "m,m"))
4381    (use (match_operand:HI 3 "memory_operand" "m,m"))
4382    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4383    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4384   "TARGET_80387 && !TARGET_FISTTP
4385    && FLOAT_MODE_P (GET_MODE (operands[1]))
4386    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4387   "#"
4388   [(set_attr "type" "fistp")
4389    (set_attr "i387_cw" "trunc")
4390    (set_attr "mode" "DI")])
4391
4392 (define_split
4393   [(set (match_operand:DI 0 "register_operand" "")
4394         (fix:DI (match_operand 1 "register_operand" "")))
4395    (use (match_operand:HI 2 "memory_operand" ""))
4396    (use (match_operand:HI 3 "memory_operand" ""))
4397    (clobber (match_operand:DI 4 "memory_operand" ""))
4398    (clobber (match_scratch 5 ""))]
4399   "reload_completed"
4400   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4401               (use (match_dup 2))
4402               (use (match_dup 3))
4403               (clobber (match_dup 5))])
4404    (set (match_dup 0) (match_dup 4))]
4405   "")
4406
4407 (define_split
4408   [(set (match_operand:DI 0 "memory_operand" "")
4409         (fix:DI (match_operand 1 "register_operand" "")))
4410    (use (match_operand:HI 2 "memory_operand" ""))
4411    (use (match_operand:HI 3 "memory_operand" ""))
4412    (clobber (match_operand:DI 4 "memory_operand" ""))
4413    (clobber (match_scratch 5 ""))]
4414   "reload_completed"
4415   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4416               (use (match_dup 2))
4417               (use (match_dup 3))
4418               (clobber (match_dup 5))])]
4419   "")
4420
4421 (define_insn "fix_trunc<mode>_i387"
4422   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4423         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4424    (use (match_operand:HI 2 "memory_operand" "m"))
4425    (use (match_operand:HI 3 "memory_operand" "m"))]
4426   "TARGET_80387 && !TARGET_FISTTP
4427    && FLOAT_MODE_P (GET_MODE (operands[1]))
4428    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4429   "* return output_fix_trunc (insn, operands, 0);"
4430   [(set_attr "type" "fistp")
4431    (set_attr "i387_cw" "trunc")
4432    (set_attr "mode" "<MODE>")])
4433
4434 (define_insn "fix_trunc<mode>_i387_with_temp"
4435   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4436         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4437    (use (match_operand:HI 2 "memory_operand" "m,m"))
4438    (use (match_operand:HI 3 "memory_operand" "m,m"))
4439    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4440   "TARGET_80387 && !TARGET_FISTTP
4441    && FLOAT_MODE_P (GET_MODE (operands[1]))
4442    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4443   "#"
4444   [(set_attr "type" "fistp")
4445    (set_attr "i387_cw" "trunc")
4446    (set_attr "mode" "<MODE>")])
4447
4448 (define_split
4449   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4450         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4451    (use (match_operand:HI 2 "memory_operand" ""))
4452    (use (match_operand:HI 3 "memory_operand" ""))
4453    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4454   "reload_completed"
4455   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4456               (use (match_dup 2))
4457               (use (match_dup 3))])
4458    (set (match_dup 0) (match_dup 4))]
4459   "")
4460
4461 (define_split
4462   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4463         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4464    (use (match_operand:HI 2 "memory_operand" ""))
4465    (use (match_operand:HI 3 "memory_operand" ""))
4466    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4467   "reload_completed"
4468   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4469               (use (match_dup 2))
4470               (use (match_dup 3))])]
4471   "")
4472
4473 (define_insn "x86_fnstcw_1"
4474   [(set (match_operand:HI 0 "memory_operand" "=m")
4475         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4476   "TARGET_80387"
4477   "fnstcw\t%0"
4478   [(set_attr "length" "2")
4479    (set_attr "mode" "HI")
4480    (set_attr "unit" "i387")])
4481
4482 (define_insn "x86_fldcw_1"
4483   [(set (reg:HI FPCR_REG)
4484         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4485   "TARGET_80387"
4486   "fldcw\t%0"
4487   [(set_attr "length" "2")
4488    (set_attr "mode" "HI")
4489    (set_attr "unit" "i387")
4490    (set_attr "athlon_decode" "vector")])
4491 \f
4492 ;; Conversion between fixed point and floating point.
4493
4494 ;; Even though we only accept memory inputs, the backend _really_
4495 ;; wants to be able to do this between registers.
4496
4497 (define_expand "floathisf2"
4498   [(set (match_operand:SF 0 "register_operand" "")
4499         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4500   "TARGET_80387 || TARGET_SSE_MATH"
4501 {
4502   if (TARGET_SSE_MATH)
4503     {
4504       emit_insn (gen_floatsisf2 (operands[0],
4505                                  convert_to_mode (SImode, operands[1], 0)));
4506       DONE;
4507     }
4508 })
4509
4510 (define_insn "*floathisf2_i387"
4511   [(set (match_operand:SF 0 "register_operand" "=f,f")
4512         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4513   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4514   "@
4515    fild%z1\t%1
4516    #"
4517   [(set_attr "type" "fmov,multi")
4518    (set_attr "mode" "SF")
4519    (set_attr "unit" "*,i387")
4520    (set_attr "fp_int_src" "true")])
4521
4522 (define_expand "floatsisf2"
4523   [(set (match_operand:SF 0 "register_operand" "")
4524         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4525   "TARGET_80387 || TARGET_SSE_MATH"
4526   "")
4527
4528 (define_insn "*floatsisf2_mixed"
4529   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4530         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4531   "TARGET_MIX_SSE_I387"
4532   "@
4533    fild%z1\t%1
4534    #
4535    cvtsi2ss\t{%1, %0|%0, %1}
4536    cvtsi2ss\t{%1, %0|%0, %1}"
4537   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4538    (set_attr "mode" "SF")
4539    (set_attr "unit" "*,i387,*,*")
4540    (set_attr "athlon_decode" "*,*,vector,double")
4541    (set_attr "fp_int_src" "true")])
4542
4543 (define_insn "*floatsisf2_sse"
4544   [(set (match_operand:SF 0 "register_operand" "=x,x")
4545         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4546   "TARGET_SSE_MATH"
4547   "cvtsi2ss\t{%1, %0|%0, %1}"
4548   [(set_attr "type" "sseicvt")
4549    (set_attr "mode" "SF")
4550    (set_attr "athlon_decode" "vector,double")
4551    (set_attr "fp_int_src" "true")])
4552
4553 (define_insn "*floatsisf2_i387"
4554   [(set (match_operand:SF 0 "register_operand" "=f,f")
4555         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4556   "TARGET_80387"
4557   "@
4558    fild%z1\t%1
4559    #"
4560   [(set_attr "type" "fmov,multi")
4561    (set_attr "mode" "SF")
4562    (set_attr "unit" "*,i387")
4563    (set_attr "fp_int_src" "true")])
4564
4565 (define_expand "floatdisf2"
4566   [(set (match_operand:SF 0 "register_operand" "")
4567         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4568   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4569   "")
4570
4571 (define_insn "*floatdisf2_mixed"
4572   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4573         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4574   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4575   "@
4576    fild%z1\t%1
4577    #
4578    cvtsi2ss{q}\t{%1, %0|%0, %1}
4579    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4580   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4581    (set_attr "mode" "SF")
4582    (set_attr "unit" "*,i387,*,*")
4583    (set_attr "athlon_decode" "*,*,vector,double")
4584    (set_attr "fp_int_src" "true")])
4585
4586 (define_insn "*floatdisf2_sse"
4587   [(set (match_operand:SF 0 "register_operand" "=x,x")
4588         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4589   "TARGET_64BIT && TARGET_SSE_MATH"
4590   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4591   [(set_attr "type" "sseicvt")
4592    (set_attr "mode" "SF")
4593    (set_attr "athlon_decode" "vector,double")
4594    (set_attr "fp_int_src" "true")])
4595
4596 (define_insn "*floatdisf2_i387"
4597   [(set (match_operand:SF 0 "register_operand" "=f,f")
4598         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4599   "TARGET_80387"
4600   "@
4601    fild%z1\t%1
4602    #"
4603   [(set_attr "type" "fmov,multi")
4604    (set_attr "mode" "SF")
4605    (set_attr "unit" "*,i387")
4606    (set_attr "fp_int_src" "true")])
4607
4608 (define_expand "floathidf2"
4609   [(set (match_operand:DF 0 "register_operand" "")
4610         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4611   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4612 {
4613   if (TARGET_SSE2 && TARGET_SSE_MATH)
4614     {
4615       emit_insn (gen_floatsidf2 (operands[0],
4616                                  convert_to_mode (SImode, operands[1], 0)));
4617       DONE;
4618     }
4619 })
4620
4621 (define_insn "*floathidf2_i387"
4622   [(set (match_operand:DF 0 "register_operand" "=f,f")
4623         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4624   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4625   "@
4626    fild%z1\t%1
4627    #"
4628   [(set_attr "type" "fmov,multi")
4629    (set_attr "mode" "DF")
4630    (set_attr "unit" "*,i387")
4631    (set_attr "fp_int_src" "true")])
4632
4633 (define_expand "floatsidf2"
4634   [(set (match_operand:DF 0 "register_operand" "")
4635         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4636   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4637   "")
4638
4639 (define_insn "*floatsidf2_mixed"
4640   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4641         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4642   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4643   "@
4644    fild%z1\t%1
4645    #
4646    cvtsi2sd\t{%1, %0|%0, %1}
4647    cvtsi2sd\t{%1, %0|%0, %1}"
4648   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4649    (set_attr "mode" "DF")
4650    (set_attr "unit" "*,i387,*,*")
4651    (set_attr "athlon_decode" "*,*,double,direct")
4652    (set_attr "fp_int_src" "true")])
4653
4654 (define_insn "*floatsidf2_sse"
4655   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4656         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4657   "TARGET_SSE2 && TARGET_SSE_MATH"
4658   "cvtsi2sd\t{%1, %0|%0, %1}"
4659   [(set_attr "type" "sseicvt")
4660    (set_attr "mode" "DF")
4661    (set_attr "athlon_decode" "double,direct")
4662    (set_attr "fp_int_src" "true")])
4663
4664 (define_insn "*floatsidf2_i387"
4665   [(set (match_operand:DF 0 "register_operand" "=f,f")
4666         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4667   "TARGET_80387"
4668   "@
4669    fild%z1\t%1
4670    #"
4671   [(set_attr "type" "fmov,multi")
4672    (set_attr "mode" "DF")
4673    (set_attr "unit" "*,i387")
4674    (set_attr "fp_int_src" "true")])
4675
4676 (define_expand "floatdidf2"
4677   [(set (match_operand:DF 0 "register_operand" "")
4678         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4679   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4680   "")
4681
4682 (define_insn "*floatdidf2_mixed"
4683   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4684         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4685   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4686   "@
4687    fild%z1\t%1
4688    #
4689    cvtsi2sd{q}\t{%1, %0|%0, %1}
4690    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4691   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4692    (set_attr "mode" "DF")
4693    (set_attr "unit" "*,i387,*,*")
4694    (set_attr "athlon_decode" "*,*,double,direct")
4695    (set_attr "fp_int_src" "true")])
4696
4697 (define_insn "*floatdidf2_sse"
4698   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4699         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4700   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4701   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4702   [(set_attr "type" "sseicvt")
4703    (set_attr "mode" "DF")
4704    (set_attr "athlon_decode" "double,direct")
4705    (set_attr "fp_int_src" "true")])
4706
4707 (define_insn "*floatdidf2_i387"
4708   [(set (match_operand:DF 0 "register_operand" "=f,f")
4709         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4710   "TARGET_80387"
4711   "@
4712    fild%z1\t%1
4713    #"
4714   [(set_attr "type" "fmov,multi")
4715    (set_attr "mode" "DF")
4716    (set_attr "unit" "*,i387")
4717    (set_attr "fp_int_src" "true")])
4718
4719 (define_insn "floathixf2"
4720   [(set (match_operand:XF 0 "register_operand" "=f,f")
4721         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4722   "TARGET_80387"
4723   "@
4724    fild%z1\t%1
4725    #"
4726   [(set_attr "type" "fmov,multi")
4727    (set_attr "mode" "XF")
4728    (set_attr "unit" "*,i387")
4729    (set_attr "fp_int_src" "true")])
4730
4731 (define_insn "floatsixf2"
4732   [(set (match_operand:XF 0 "register_operand" "=f,f")
4733         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4734   "TARGET_80387"
4735   "@
4736    fild%z1\t%1
4737    #"
4738   [(set_attr "type" "fmov,multi")
4739    (set_attr "mode" "XF")
4740    (set_attr "unit" "*,i387")
4741    (set_attr "fp_int_src" "true")])
4742
4743 (define_insn "floatdixf2"
4744   [(set (match_operand:XF 0 "register_operand" "=f,f")
4745         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4746   "TARGET_80387"
4747   "@
4748    fild%z1\t%1
4749    #"
4750   [(set_attr "type" "fmov,multi")
4751    (set_attr "mode" "XF")
4752    (set_attr "unit" "*,i387")
4753    (set_attr "fp_int_src" "true")])
4754
4755 ;; %%% Kill these when reload knows how to do it.
4756 (define_split
4757   [(set (match_operand 0 "fp_register_operand" "")
4758         (float (match_operand 1 "register_operand" "")))]
4759   "reload_completed
4760    && TARGET_80387
4761    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4762   [(const_int 0)]
4763 {
4764   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4765   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4766   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4767   ix86_free_from_memory (GET_MODE (operands[1]));
4768   DONE;
4769 })
4770
4771 (define_expand "floatunssisf2"
4772   [(use (match_operand:SF 0 "register_operand" ""))
4773    (use (match_operand:SI 1 "register_operand" ""))]
4774   "!TARGET_64BIT && TARGET_SSE_MATH"
4775   "x86_emit_floatuns (operands); DONE;")
4776
4777 (define_expand "floatunsdisf2"
4778   [(use (match_operand:SF 0 "register_operand" ""))
4779    (use (match_operand:DI 1 "register_operand" ""))]
4780   "TARGET_64BIT && TARGET_SSE_MATH"
4781   "x86_emit_floatuns (operands); DONE;")
4782
4783 (define_expand "floatunsdidf2"
4784   [(use (match_operand:DF 0 "register_operand" ""))
4785    (use (match_operand:DI 1 "register_operand" ""))]
4786   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4787   "x86_emit_floatuns (operands); DONE;")
4788 \f
4789 ;; SSE extract/set expanders
4790
4791 \f
4792 ;; Add instructions
4793
4794 ;; %%% splits for addditi3
4795
4796 (define_expand "addti3"
4797   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4798         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4799                  (match_operand:TI 2 "x86_64_general_operand" "")))
4800    (clobber (reg:CC FLAGS_REG))]
4801   "TARGET_64BIT"
4802   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4803
4804 (define_insn "*addti3_1"
4805   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4806         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4807                  (match_operand:TI 2 "general_operand" "roiF,riF")))
4808    (clobber (reg:CC FLAGS_REG))]
4809   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4810   "#")
4811
4812 (define_split
4813   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4814         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4815                  (match_operand:TI 2 "general_operand" "")))
4816    (clobber (reg:CC FLAGS_REG))]
4817   "TARGET_64BIT && reload_completed"
4818   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4819                                           UNSPEC_ADD_CARRY))
4820               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4821    (parallel [(set (match_dup 3)
4822                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4823                                      (match_dup 4))
4824                             (match_dup 5)))
4825               (clobber (reg:CC FLAGS_REG))])]
4826   "split_ti (operands+0, 1, operands+0, operands+3);
4827    split_ti (operands+1, 1, operands+1, operands+4);
4828    split_ti (operands+2, 1, operands+2, operands+5);")
4829
4830 ;; %%% splits for addsidi3
4831 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4832 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4833 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4834
4835 (define_expand "adddi3"
4836   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4837         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4838                  (match_operand:DI 2 "x86_64_general_operand" "")))
4839    (clobber (reg:CC FLAGS_REG))]
4840   ""
4841   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4842
4843 (define_insn "*adddi3_1"
4844   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4845         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4846                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4847    (clobber (reg:CC FLAGS_REG))]
4848   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4849   "#")
4850
4851 (define_split
4852   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4853         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4854                  (match_operand:DI 2 "general_operand" "")))
4855    (clobber (reg:CC FLAGS_REG))]
4856   "!TARGET_64BIT && reload_completed"
4857   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4858                                           UNSPEC_ADD_CARRY))
4859               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4860    (parallel [(set (match_dup 3)
4861                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4862                                      (match_dup 4))
4863                             (match_dup 5)))
4864               (clobber (reg:CC FLAGS_REG))])]
4865   "split_di (operands+0, 1, operands+0, operands+3);
4866    split_di (operands+1, 1, operands+1, operands+4);
4867    split_di (operands+2, 1, operands+2, operands+5);")
4868
4869 (define_insn "adddi3_carry_rex64"
4870   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4871           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4872                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4873                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4874    (clobber (reg:CC FLAGS_REG))]
4875   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4876   "adc{q}\t{%2, %0|%0, %2}"
4877   [(set_attr "type" "alu")
4878    (set_attr "pent_pair" "pu")
4879    (set_attr "mode" "DI")])
4880
4881 (define_insn "*adddi3_cc_rex64"
4882   [(set (reg:CC FLAGS_REG)
4883         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4884                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4885                    UNSPEC_ADD_CARRY))
4886    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4887         (plus:DI (match_dup 1) (match_dup 2)))]
4888   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4889   "add{q}\t{%2, %0|%0, %2}"
4890   [(set_attr "type" "alu")
4891    (set_attr "mode" "DI")])
4892
4893 (define_insn "addqi3_carry"
4894   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4895           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4896                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4897                    (match_operand:QI 2 "general_operand" "qi,qm")))
4898    (clobber (reg:CC FLAGS_REG))]
4899   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4900   "adc{b}\t{%2, %0|%0, %2}"
4901   [(set_attr "type" "alu")
4902    (set_attr "pent_pair" "pu")
4903    (set_attr "mode" "QI")])
4904
4905 (define_insn "addhi3_carry"
4906   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4907           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4908                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4909                    (match_operand:HI 2 "general_operand" "ri,rm")))
4910    (clobber (reg:CC FLAGS_REG))]
4911   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4912   "adc{w}\t{%2, %0|%0, %2}"
4913   [(set_attr "type" "alu")
4914    (set_attr "pent_pair" "pu")
4915    (set_attr "mode" "HI")])
4916
4917 (define_insn "addsi3_carry"
4918   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4919           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4920                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4921                    (match_operand:SI 2 "general_operand" "ri,rm")))
4922    (clobber (reg:CC FLAGS_REG))]
4923   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4924   "adc{l}\t{%2, %0|%0, %2}"
4925   [(set_attr "type" "alu")
4926    (set_attr "pent_pair" "pu")
4927    (set_attr "mode" "SI")])
4928
4929 (define_insn "*addsi3_carry_zext"
4930   [(set (match_operand:DI 0 "register_operand" "=r")
4931           (zero_extend:DI
4932             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4933                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4934                      (match_operand:SI 2 "general_operand" "rim"))))
4935    (clobber (reg:CC FLAGS_REG))]
4936   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4937   "adc{l}\t{%2, %k0|%k0, %2}"
4938   [(set_attr "type" "alu")
4939    (set_attr "pent_pair" "pu")
4940    (set_attr "mode" "SI")])
4941
4942 (define_insn "*addsi3_cc"
4943   [(set (reg:CC FLAGS_REG)
4944         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4945                     (match_operand:SI 2 "general_operand" "ri,rm")]
4946                    UNSPEC_ADD_CARRY))
4947    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4948         (plus:SI (match_dup 1) (match_dup 2)))]
4949   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4950   "add{l}\t{%2, %0|%0, %2}"
4951   [(set_attr "type" "alu")
4952    (set_attr "mode" "SI")])
4953
4954 (define_insn "addqi3_cc"
4955   [(set (reg:CC FLAGS_REG)
4956         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4957                     (match_operand:QI 2 "general_operand" "qi,qm")]
4958                    UNSPEC_ADD_CARRY))
4959    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4960         (plus:QI (match_dup 1) (match_dup 2)))]
4961   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4962   "add{b}\t{%2, %0|%0, %2}"
4963   [(set_attr "type" "alu")
4964    (set_attr "mode" "QI")])
4965
4966 (define_expand "addsi3"
4967   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4968                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4969                             (match_operand:SI 2 "general_operand" "")))
4970               (clobber (reg:CC FLAGS_REG))])]
4971   ""
4972   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4973
4974 (define_insn "*lea_1"
4975   [(set (match_operand:SI 0 "register_operand" "=r")
4976         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4977   "!TARGET_64BIT"
4978   "lea{l}\t{%a1, %0|%0, %a1}"
4979   [(set_attr "type" "lea")
4980    (set_attr "mode" "SI")])
4981
4982 (define_insn "*lea_1_rex64"
4983   [(set (match_operand:SI 0 "register_operand" "=r")
4984         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4985   "TARGET_64BIT"
4986   "lea{l}\t{%a1, %0|%0, %a1}"
4987   [(set_attr "type" "lea")
4988    (set_attr "mode" "SI")])
4989
4990 (define_insn "*lea_1_zext"
4991   [(set (match_operand:DI 0 "register_operand" "=r")
4992         (zero_extend:DI
4993          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4994   "TARGET_64BIT"
4995   "lea{l}\t{%a1, %k0|%k0, %a1}"
4996   [(set_attr "type" "lea")
4997    (set_attr "mode" "SI")])
4998
4999 (define_insn "*lea_2_rex64"
5000   [(set (match_operand:DI 0 "register_operand" "=r")
5001         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5002   "TARGET_64BIT"
5003   "lea{q}\t{%a1, %0|%0, %a1}"
5004   [(set_attr "type" "lea")
5005    (set_attr "mode" "DI")])
5006
5007 ;; The lea patterns for non-Pmodes needs to be matched by several
5008 ;; insns converted to real lea by splitters.
5009
5010 (define_insn_and_split "*lea_general_1"
5011   [(set (match_operand 0 "register_operand" "=r")
5012         (plus (plus (match_operand 1 "index_register_operand" "l")
5013                     (match_operand 2 "register_operand" "r"))
5014               (match_operand 3 "immediate_operand" "i")))]
5015   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5016     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5017    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5018    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5019    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5020    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5021        || GET_MODE (operands[3]) == VOIDmode)"
5022   "#"
5023   "&& reload_completed"
5024   [(const_int 0)]
5025 {
5026   rtx pat;
5027   operands[0] = gen_lowpart (SImode, operands[0]);
5028   operands[1] = gen_lowpart (Pmode, operands[1]);
5029   operands[2] = gen_lowpart (Pmode, operands[2]);
5030   operands[3] = gen_lowpart (Pmode, operands[3]);
5031   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5032                       operands[3]);
5033   if (Pmode != SImode)
5034     pat = gen_rtx_SUBREG (SImode, pat, 0);
5035   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5036   DONE;
5037 }
5038   [(set_attr "type" "lea")
5039    (set_attr "mode" "SI")])
5040
5041 (define_insn_and_split "*lea_general_1_zext"
5042   [(set (match_operand:DI 0 "register_operand" "=r")
5043         (zero_extend:DI
5044           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5045                             (match_operand:SI 2 "register_operand" "r"))
5046                    (match_operand:SI 3 "immediate_operand" "i"))))]
5047   "TARGET_64BIT"
5048   "#"
5049   "&& reload_completed"
5050   [(set (match_dup 0)
5051         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5052                                                      (match_dup 2))
5053                                             (match_dup 3)) 0)))]
5054 {
5055   operands[1] = gen_lowpart (Pmode, operands[1]);
5056   operands[2] = gen_lowpart (Pmode, operands[2]);
5057   operands[3] = gen_lowpart (Pmode, operands[3]);
5058 }
5059   [(set_attr "type" "lea")
5060    (set_attr "mode" "SI")])
5061
5062 (define_insn_and_split "*lea_general_2"
5063   [(set (match_operand 0 "register_operand" "=r")
5064         (plus (mult (match_operand 1 "index_register_operand" "l")
5065                     (match_operand 2 "const248_operand" "i"))
5066               (match_operand 3 "nonmemory_operand" "ri")))]
5067   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5068     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5069    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5070    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5071    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5072        || GET_MODE (operands[3]) == VOIDmode)"
5073   "#"
5074   "&& reload_completed"
5075   [(const_int 0)]
5076 {
5077   rtx pat;
5078   operands[0] = gen_lowpart (SImode, operands[0]);
5079   operands[1] = gen_lowpart (Pmode, operands[1]);
5080   operands[3] = gen_lowpart (Pmode, operands[3]);
5081   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5082                       operands[3]);
5083   if (Pmode != SImode)
5084     pat = gen_rtx_SUBREG (SImode, pat, 0);
5085   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5086   DONE;
5087 }
5088   [(set_attr "type" "lea")
5089    (set_attr "mode" "SI")])
5090
5091 (define_insn_and_split "*lea_general_2_zext"
5092   [(set (match_operand:DI 0 "register_operand" "=r")
5093         (zero_extend:DI
5094           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5095                             (match_operand:SI 2 "const248_operand" "n"))
5096                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5097   "TARGET_64BIT"
5098   "#"
5099   "&& reload_completed"
5100   [(set (match_dup 0)
5101         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5102                                                      (match_dup 2))
5103                                             (match_dup 3)) 0)))]
5104 {
5105   operands[1] = gen_lowpart (Pmode, operands[1]);
5106   operands[3] = gen_lowpart (Pmode, operands[3]);
5107 }
5108   [(set_attr "type" "lea")
5109    (set_attr "mode" "SI")])
5110
5111 (define_insn_and_split "*lea_general_3"
5112   [(set (match_operand 0 "register_operand" "=r")
5113         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5114                           (match_operand 2 "const248_operand" "i"))
5115                     (match_operand 3 "register_operand" "r"))
5116               (match_operand 4 "immediate_operand" "i")))]
5117   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5118     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5119    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5120    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5121    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5122   "#"
5123   "&& reload_completed"
5124   [(const_int 0)]
5125 {
5126   rtx pat;
5127   operands[0] = gen_lowpart (SImode, operands[0]);
5128   operands[1] = gen_lowpart (Pmode, operands[1]);
5129   operands[3] = gen_lowpart (Pmode, operands[3]);
5130   operands[4] = gen_lowpart (Pmode, operands[4]);
5131   pat = gen_rtx_PLUS (Pmode,
5132                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5133                                                          operands[2]),
5134                                     operands[3]),
5135                       operands[4]);
5136   if (Pmode != SImode)
5137     pat = gen_rtx_SUBREG (SImode, pat, 0);
5138   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5139   DONE;
5140 }
5141   [(set_attr "type" "lea")
5142    (set_attr "mode" "SI")])
5143
5144 (define_insn_and_split "*lea_general_3_zext"
5145   [(set (match_operand:DI 0 "register_operand" "=r")
5146         (zero_extend:DI
5147           (plus:SI (plus:SI (mult:SI
5148                               (match_operand:SI 1 "index_register_operand" "l")
5149                               (match_operand:SI 2 "const248_operand" "n"))
5150                             (match_operand:SI 3 "register_operand" "r"))
5151                    (match_operand:SI 4 "immediate_operand" "i"))))]
5152   "TARGET_64BIT"
5153   "#"
5154   "&& reload_completed"
5155   [(set (match_dup 0)
5156         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5157                                                               (match_dup 2))
5158                                                      (match_dup 3))
5159                                             (match_dup 4)) 0)))]
5160 {
5161   operands[1] = gen_lowpart (Pmode, operands[1]);
5162   operands[3] = gen_lowpart (Pmode, operands[3]);
5163   operands[4] = gen_lowpart (Pmode, operands[4]);
5164 }
5165   [(set_attr "type" "lea")
5166    (set_attr "mode" "SI")])
5167
5168 (define_insn "*adddi_1_rex64"
5169   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5170         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5171                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5172    (clobber (reg:CC FLAGS_REG))]
5173   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5174 {
5175   switch (get_attr_type (insn))
5176     {
5177     case TYPE_LEA:
5178       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5179       return "lea{q}\t{%a2, %0|%0, %a2}";
5180
5181     case TYPE_INCDEC:
5182       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5183       if (operands[2] == const1_rtx)
5184         return "inc{q}\t%0";
5185       else
5186         {
5187           gcc_assert (operands[2] == constm1_rtx);
5188           return "dec{q}\t%0";
5189         }
5190
5191     default:
5192       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5193
5194       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5195          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5196       if (CONST_INT_P (operands[2])
5197           /* Avoid overflows.  */
5198           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5199           && (INTVAL (operands[2]) == 128
5200               || (INTVAL (operands[2]) < 0
5201                   && INTVAL (operands[2]) != -128)))
5202         {
5203           operands[2] = GEN_INT (-INTVAL (operands[2]));
5204           return "sub{q}\t{%2, %0|%0, %2}";
5205         }
5206       return "add{q}\t{%2, %0|%0, %2}";
5207     }
5208 }
5209   [(set (attr "type")
5210      (cond [(eq_attr "alternative" "2")
5211               (const_string "lea")
5212             ; Current assemblers are broken and do not allow @GOTOFF in
5213             ; ought but a memory context.
5214             (match_operand:DI 2 "pic_symbolic_operand" "")
5215               (const_string "lea")
5216             (match_operand:DI 2 "incdec_operand" "")
5217               (const_string "incdec")
5218            ]
5219            (const_string "alu")))
5220    (set_attr "mode" "DI")])
5221
5222 ;; Convert lea to the lea pattern to avoid flags dependency.
5223 (define_split
5224   [(set (match_operand:DI 0 "register_operand" "")
5225         (plus:DI (match_operand:DI 1 "register_operand" "")
5226                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5227    (clobber (reg:CC FLAGS_REG))]
5228   "TARGET_64BIT && reload_completed
5229    && true_regnum (operands[0]) != true_regnum (operands[1])"
5230   [(set (match_dup 0)
5231         (plus:DI (match_dup 1)
5232                  (match_dup 2)))]
5233   "")
5234
5235 (define_insn "*adddi_2_rex64"
5236   [(set (reg FLAGS_REG)
5237         (compare
5238           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5239                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5240           (const_int 0)))
5241    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5242         (plus:DI (match_dup 1) (match_dup 2)))]
5243   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5244    && ix86_binary_operator_ok (PLUS, DImode, operands)
5245    /* Current assemblers are broken and do not allow @GOTOFF in
5246       ought but a memory context.  */
5247    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5248 {
5249   switch (get_attr_type (insn))
5250     {
5251     case TYPE_INCDEC:
5252       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5253       if (operands[2] == const1_rtx)
5254         return "inc{q}\t%0";
5255       else
5256         {
5257           gcc_assert (operands[2] == constm1_rtx);
5258           return "dec{q}\t%0";
5259         }
5260
5261     default:
5262       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5263       /* ???? We ought to handle there the 32bit case too
5264          - do we need new constraint?  */
5265       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5266          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5267       if (CONST_INT_P (operands[2])
5268           /* Avoid overflows.  */
5269           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5270           && (INTVAL (operands[2]) == 128
5271               || (INTVAL (operands[2]) < 0
5272                   && INTVAL (operands[2]) != -128)))
5273         {
5274           operands[2] = GEN_INT (-INTVAL (operands[2]));
5275           return "sub{q}\t{%2, %0|%0, %2}";
5276         }
5277       return "add{q}\t{%2, %0|%0, %2}";
5278     }
5279 }
5280   [(set (attr "type")
5281      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5282         (const_string "incdec")
5283         (const_string "alu")))
5284    (set_attr "mode" "DI")])
5285
5286 (define_insn "*adddi_3_rex64"
5287   [(set (reg FLAGS_REG)
5288         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5289                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5290    (clobber (match_scratch:DI 0 "=r"))]
5291   "TARGET_64BIT
5292    && ix86_match_ccmode (insn, CCZmode)
5293    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5294    /* Current assemblers are broken and do not allow @GOTOFF in
5295       ought but a memory context.  */
5296    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5297 {
5298   switch (get_attr_type (insn))
5299     {
5300     case TYPE_INCDEC:
5301       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5302       if (operands[2] == const1_rtx)
5303         return "inc{q}\t%0";
5304       else
5305         {
5306           gcc_assert (operands[2] == constm1_rtx);
5307           return "dec{q}\t%0";
5308         }
5309
5310     default:
5311       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5312       /* ???? We ought to handle there the 32bit case too
5313          - do we need new constraint?  */
5314       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5315          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5316       if (CONST_INT_P (operands[2])
5317           /* Avoid overflows.  */
5318           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5319           && (INTVAL (operands[2]) == 128
5320               || (INTVAL (operands[2]) < 0
5321                   && INTVAL (operands[2]) != -128)))
5322         {
5323           operands[2] = GEN_INT (-INTVAL (operands[2]));
5324           return "sub{q}\t{%2, %0|%0, %2}";
5325         }
5326       return "add{q}\t{%2, %0|%0, %2}";
5327     }
5328 }
5329   [(set (attr "type")
5330      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5331         (const_string "incdec")
5332         (const_string "alu")))
5333    (set_attr "mode" "DI")])
5334
5335 ; For comparisons against 1, -1 and 128, we may generate better code
5336 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5337 ; is matched then.  We can't accept general immediate, because for
5338 ; case of overflows,  the result is messed up.
5339 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5340 ; when negated.
5341 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5342 ; only for comparisons not depending on it.
5343 (define_insn "*adddi_4_rex64"
5344   [(set (reg FLAGS_REG)
5345         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5346                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5347    (clobber (match_scratch:DI 0 "=rm"))]
5348   "TARGET_64BIT
5349    &&  ix86_match_ccmode (insn, CCGCmode)"
5350 {
5351   switch (get_attr_type (insn))
5352     {
5353     case TYPE_INCDEC:
5354       if (operands[2] == constm1_rtx)
5355         return "inc{q}\t%0";
5356       else
5357         {
5358           gcc_assert (operands[2] == const1_rtx);
5359           return "dec{q}\t%0";
5360         }
5361
5362     default:
5363       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5364       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5365          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5366       if ((INTVAL (operands[2]) == -128
5367            || (INTVAL (operands[2]) > 0
5368                && INTVAL (operands[2]) != 128))
5369           /* Avoid overflows.  */
5370           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5371         return "sub{q}\t{%2, %0|%0, %2}";
5372       operands[2] = GEN_INT (-INTVAL (operands[2]));
5373       return "add{q}\t{%2, %0|%0, %2}";
5374     }
5375 }
5376   [(set (attr "type")
5377      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5378         (const_string "incdec")
5379         (const_string "alu")))
5380    (set_attr "mode" "DI")])
5381
5382 (define_insn "*adddi_5_rex64"
5383   [(set (reg FLAGS_REG)
5384         (compare
5385           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5386                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5387           (const_int 0)))
5388    (clobber (match_scratch:DI 0 "=r"))]
5389   "TARGET_64BIT
5390    && ix86_match_ccmode (insn, CCGOCmode)
5391    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5392    /* Current assemblers are broken and do not allow @GOTOFF in
5393       ought but a memory context.  */
5394    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5395 {
5396   switch (get_attr_type (insn))
5397     {
5398     case TYPE_INCDEC:
5399       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5400       if (operands[2] == const1_rtx)
5401         return "inc{q}\t%0";
5402       else
5403         {
5404           gcc_assert (operands[2] == constm1_rtx);
5405           return "dec{q}\t%0";
5406         }
5407
5408     default:
5409       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5410       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5411          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5412       if (CONST_INT_P (operands[2])
5413           /* Avoid overflows.  */
5414           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5415           && (INTVAL (operands[2]) == 128
5416               || (INTVAL (operands[2]) < 0
5417                   && INTVAL (operands[2]) != -128)))
5418         {
5419           operands[2] = GEN_INT (-INTVAL (operands[2]));
5420           return "sub{q}\t{%2, %0|%0, %2}";
5421         }
5422       return "add{q}\t{%2, %0|%0, %2}";
5423     }
5424 }
5425   [(set (attr "type")
5426      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5427         (const_string "incdec")
5428         (const_string "alu")))
5429    (set_attr "mode" "DI")])
5430
5431
5432 (define_insn "*addsi_1"
5433   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5434         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5435                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5436    (clobber (reg:CC FLAGS_REG))]
5437   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5438 {
5439   switch (get_attr_type (insn))
5440     {
5441     case TYPE_LEA:
5442       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5443       return "lea{l}\t{%a2, %0|%0, %a2}";
5444
5445     case TYPE_INCDEC:
5446       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5447       if (operands[2] == const1_rtx)
5448         return "inc{l}\t%0";
5449       else
5450         {
5451           gcc_assert (operands[2] == constm1_rtx);
5452           return "dec{l}\t%0";
5453         }
5454
5455     default:
5456       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5457
5458       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5459          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5460       if (CONST_INT_P (operands[2])
5461           && (INTVAL (operands[2]) == 128
5462               || (INTVAL (operands[2]) < 0
5463                   && INTVAL (operands[2]) != -128)))
5464         {
5465           operands[2] = GEN_INT (-INTVAL (operands[2]));
5466           return "sub{l}\t{%2, %0|%0, %2}";
5467         }
5468       return "add{l}\t{%2, %0|%0, %2}";
5469     }
5470 }
5471   [(set (attr "type")
5472      (cond [(eq_attr "alternative" "2")
5473               (const_string "lea")
5474             ; Current assemblers are broken and do not allow @GOTOFF in
5475             ; ought but a memory context.
5476             (match_operand:SI 2 "pic_symbolic_operand" "")
5477               (const_string "lea")
5478             (match_operand:SI 2 "incdec_operand" "")
5479               (const_string "incdec")
5480            ]
5481            (const_string "alu")))
5482    (set_attr "mode" "SI")])
5483
5484 ;; Convert lea to the lea pattern to avoid flags dependency.
5485 (define_split
5486   [(set (match_operand 0 "register_operand" "")
5487         (plus (match_operand 1 "register_operand" "")
5488               (match_operand 2 "nonmemory_operand" "")))
5489    (clobber (reg:CC FLAGS_REG))]
5490   "reload_completed
5491    && true_regnum (operands[0]) != true_regnum (operands[1])"
5492   [(const_int 0)]
5493 {
5494   rtx pat;
5495   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5496      may confuse gen_lowpart.  */
5497   if (GET_MODE (operands[0]) != Pmode)
5498     {
5499       operands[1] = gen_lowpart (Pmode, operands[1]);
5500       operands[2] = gen_lowpart (Pmode, operands[2]);
5501     }
5502   operands[0] = gen_lowpart (SImode, operands[0]);
5503   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5504   if (Pmode != SImode)
5505     pat = gen_rtx_SUBREG (SImode, pat, 0);
5506   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5507   DONE;
5508 })
5509
5510 ;; It may seem that nonimmediate operand is proper one for operand 1.
5511 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5512 ;; we take care in ix86_binary_operator_ok to not allow two memory
5513 ;; operands so proper swapping will be done in reload.  This allow
5514 ;; patterns constructed from addsi_1 to match.
5515 (define_insn "addsi_1_zext"
5516   [(set (match_operand:DI 0 "register_operand" "=r,r")
5517         (zero_extend:DI
5518           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5519                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5520    (clobber (reg:CC FLAGS_REG))]
5521   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5522 {
5523   switch (get_attr_type (insn))
5524     {
5525     case TYPE_LEA:
5526       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5527       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5528
5529     case TYPE_INCDEC:
5530       if (operands[2] == const1_rtx)
5531         return "inc{l}\t%k0";
5532       else
5533         {
5534           gcc_assert (operands[2] == constm1_rtx);
5535           return "dec{l}\t%k0";
5536         }
5537
5538     default:
5539       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5540          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5541       if (CONST_INT_P (operands[2])
5542           && (INTVAL (operands[2]) == 128
5543               || (INTVAL (operands[2]) < 0
5544                   && INTVAL (operands[2]) != -128)))
5545         {
5546           operands[2] = GEN_INT (-INTVAL (operands[2]));
5547           return "sub{l}\t{%2, %k0|%k0, %2}";
5548         }
5549       return "add{l}\t{%2, %k0|%k0, %2}";
5550     }
5551 }
5552   [(set (attr "type")
5553      (cond [(eq_attr "alternative" "1")
5554               (const_string "lea")
5555             ; Current assemblers are broken and do not allow @GOTOFF in
5556             ; ought but a memory context.
5557             (match_operand:SI 2 "pic_symbolic_operand" "")
5558               (const_string "lea")
5559             (match_operand:SI 2 "incdec_operand" "")
5560               (const_string "incdec")
5561            ]
5562            (const_string "alu")))
5563    (set_attr "mode" "SI")])
5564
5565 ;; Convert lea to the lea pattern to avoid flags dependency.
5566 (define_split
5567   [(set (match_operand:DI 0 "register_operand" "")
5568         (zero_extend:DI
5569           (plus:SI (match_operand:SI 1 "register_operand" "")
5570                    (match_operand:SI 2 "nonmemory_operand" ""))))
5571    (clobber (reg:CC FLAGS_REG))]
5572   "TARGET_64BIT && reload_completed
5573    && true_regnum (operands[0]) != true_regnum (operands[1])"
5574   [(set (match_dup 0)
5575         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5576 {
5577   operands[1] = gen_lowpart (Pmode, operands[1]);
5578   operands[2] = gen_lowpart (Pmode, operands[2]);
5579 })
5580
5581 (define_insn "*addsi_2"
5582   [(set (reg FLAGS_REG)
5583         (compare
5584           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5585                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5586           (const_int 0)))
5587    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5588         (plus:SI (match_dup 1) (match_dup 2)))]
5589   "ix86_match_ccmode (insn, CCGOCmode)
5590    && ix86_binary_operator_ok (PLUS, SImode, operands)
5591    /* Current assemblers are broken and do not allow @GOTOFF in
5592       ought but a memory context.  */
5593    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5594 {
5595   switch (get_attr_type (insn))
5596     {
5597     case TYPE_INCDEC:
5598       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5599       if (operands[2] == const1_rtx)
5600         return "inc{l}\t%0";
5601       else
5602         {
5603           gcc_assert (operands[2] == constm1_rtx);
5604           return "dec{l}\t%0";
5605         }
5606
5607     default:
5608       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5609       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5610          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5611       if (CONST_INT_P (operands[2])
5612           && (INTVAL (operands[2]) == 128
5613               || (INTVAL (operands[2]) < 0
5614                   && INTVAL (operands[2]) != -128)))
5615         {
5616           operands[2] = GEN_INT (-INTVAL (operands[2]));
5617           return "sub{l}\t{%2, %0|%0, %2}";
5618         }
5619       return "add{l}\t{%2, %0|%0, %2}";
5620     }
5621 }
5622   [(set (attr "type")
5623      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5624         (const_string "incdec")
5625         (const_string "alu")))
5626    (set_attr "mode" "SI")])
5627
5628 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5629 (define_insn "*addsi_2_zext"
5630   [(set (reg FLAGS_REG)
5631         (compare
5632           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5633                    (match_operand:SI 2 "general_operand" "rmni"))
5634           (const_int 0)))
5635    (set (match_operand:DI 0 "register_operand" "=r")
5636         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5637   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5638    && ix86_binary_operator_ok (PLUS, SImode, operands)
5639    /* Current assemblers are broken and do not allow @GOTOFF in
5640       ought but a memory context.  */
5641    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5642 {
5643   switch (get_attr_type (insn))
5644     {
5645     case TYPE_INCDEC:
5646       if (operands[2] == const1_rtx)
5647         return "inc{l}\t%k0";
5648       else
5649         {
5650           gcc_assert (operands[2] == constm1_rtx);
5651           return "dec{l}\t%k0";
5652         }
5653
5654     default:
5655       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5656          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5657       if (CONST_INT_P (operands[2])
5658           && (INTVAL (operands[2]) == 128
5659               || (INTVAL (operands[2]) < 0
5660                   && INTVAL (operands[2]) != -128)))
5661         {
5662           operands[2] = GEN_INT (-INTVAL (operands[2]));
5663           return "sub{l}\t{%2, %k0|%k0, %2}";
5664         }
5665       return "add{l}\t{%2, %k0|%k0, %2}";
5666     }
5667 }
5668   [(set (attr "type")
5669      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5670         (const_string "incdec")
5671         (const_string "alu")))
5672    (set_attr "mode" "SI")])
5673
5674 (define_insn "*addsi_3"
5675   [(set (reg FLAGS_REG)
5676         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5677                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5678    (clobber (match_scratch:SI 0 "=r"))]
5679   "ix86_match_ccmode (insn, CCZmode)
5680    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5681    /* Current assemblers are broken and do not allow @GOTOFF in
5682       ought but a memory context.  */
5683    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5684 {
5685   switch (get_attr_type (insn))
5686     {
5687     case TYPE_INCDEC:
5688       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5689       if (operands[2] == const1_rtx)
5690         return "inc{l}\t%0";
5691       else
5692         {
5693           gcc_assert (operands[2] == constm1_rtx);
5694           return "dec{l}\t%0";
5695         }
5696
5697     default:
5698       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5699       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5700          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5701       if (CONST_INT_P (operands[2])
5702           && (INTVAL (operands[2]) == 128
5703               || (INTVAL (operands[2]) < 0
5704                   && INTVAL (operands[2]) != -128)))
5705         {
5706           operands[2] = GEN_INT (-INTVAL (operands[2]));
5707           return "sub{l}\t{%2, %0|%0, %2}";
5708         }
5709       return "add{l}\t{%2, %0|%0, %2}";
5710     }
5711 }
5712   [(set (attr "type")
5713      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5714         (const_string "incdec")
5715         (const_string "alu")))
5716    (set_attr "mode" "SI")])
5717
5718 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5719 (define_insn "*addsi_3_zext"
5720   [(set (reg FLAGS_REG)
5721         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5722                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5723    (set (match_operand:DI 0 "register_operand" "=r")
5724         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5725   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5726    && ix86_binary_operator_ok (PLUS, SImode, operands)
5727    /* Current assemblers are broken and do not allow @GOTOFF in
5728       ought but a memory context.  */
5729    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5730 {
5731   switch (get_attr_type (insn))
5732     {
5733     case TYPE_INCDEC:
5734       if (operands[2] == const1_rtx)
5735         return "inc{l}\t%k0";
5736       else
5737         {
5738           gcc_assert (operands[2] == constm1_rtx);
5739           return "dec{l}\t%k0";
5740         }
5741
5742     default:
5743       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5744          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5745       if (CONST_INT_P (operands[2])
5746           && (INTVAL (operands[2]) == 128
5747               || (INTVAL (operands[2]) < 0
5748                   && INTVAL (operands[2]) != -128)))
5749         {
5750           operands[2] = GEN_INT (-INTVAL (operands[2]));
5751           return "sub{l}\t{%2, %k0|%k0, %2}";
5752         }
5753       return "add{l}\t{%2, %k0|%k0, %2}";
5754     }
5755 }
5756   [(set (attr "type")
5757      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5758         (const_string "incdec")
5759         (const_string "alu")))
5760    (set_attr "mode" "SI")])
5761
5762 ; For comparisons against 1, -1 and 128, we may generate better code
5763 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5764 ; is matched then.  We can't accept general immediate, because for
5765 ; case of overflows,  the result is messed up.
5766 ; This pattern also don't hold of 0x80000000, since the value overflows
5767 ; when negated.
5768 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5769 ; only for comparisons not depending on it.
5770 (define_insn "*addsi_4"
5771   [(set (reg FLAGS_REG)
5772         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5773                  (match_operand:SI 2 "const_int_operand" "n")))
5774    (clobber (match_scratch:SI 0 "=rm"))]
5775   "ix86_match_ccmode (insn, CCGCmode)
5776    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5777 {
5778   switch (get_attr_type (insn))
5779     {
5780     case TYPE_INCDEC:
5781       if (operands[2] == constm1_rtx)
5782         return "inc{l}\t%0";
5783       else
5784         {
5785           gcc_assert (operands[2] == const1_rtx);
5786           return "dec{l}\t%0";
5787         }
5788
5789     default:
5790       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5791       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5792          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5793       if ((INTVAL (operands[2]) == -128
5794            || (INTVAL (operands[2]) > 0
5795                && INTVAL (operands[2]) != 128)))
5796         return "sub{l}\t{%2, %0|%0, %2}";
5797       operands[2] = GEN_INT (-INTVAL (operands[2]));
5798       return "add{l}\t{%2, %0|%0, %2}";
5799     }
5800 }
5801   [(set (attr "type")
5802      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5803         (const_string "incdec")
5804         (const_string "alu")))
5805    (set_attr "mode" "SI")])
5806
5807 (define_insn "*addsi_5"
5808   [(set (reg FLAGS_REG)
5809         (compare
5810           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5811                    (match_operand:SI 2 "general_operand" "rmni"))
5812           (const_int 0)))
5813    (clobber (match_scratch:SI 0 "=r"))]
5814   "ix86_match_ccmode (insn, CCGOCmode)
5815    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5816    /* Current assemblers are broken and do not allow @GOTOFF in
5817       ought but a memory context.  */
5818    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5819 {
5820   switch (get_attr_type (insn))
5821     {
5822     case TYPE_INCDEC:
5823       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5824       if (operands[2] == const1_rtx)
5825         return "inc{l}\t%0";
5826       else
5827         {
5828           gcc_assert (operands[2] == constm1_rtx);
5829           return "dec{l}\t%0";
5830         }
5831
5832     default:
5833       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5834       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5835          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5836       if (CONST_INT_P (operands[2])
5837           && (INTVAL (operands[2]) == 128
5838               || (INTVAL (operands[2]) < 0
5839                   && INTVAL (operands[2]) != -128)))
5840         {
5841           operands[2] = GEN_INT (-INTVAL (operands[2]));
5842           return "sub{l}\t{%2, %0|%0, %2}";
5843         }
5844       return "add{l}\t{%2, %0|%0, %2}";
5845     }
5846 }
5847   [(set (attr "type")
5848      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5849         (const_string "incdec")
5850         (const_string "alu")))
5851    (set_attr "mode" "SI")])
5852
5853 (define_expand "addhi3"
5854   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5855                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5856                             (match_operand:HI 2 "general_operand" "")))
5857               (clobber (reg:CC FLAGS_REG))])]
5858   "TARGET_HIMODE_MATH"
5859   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5860
5861 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5862 ;; type optimizations enabled by define-splits.  This is not important
5863 ;; for PII, and in fact harmful because of partial register stalls.
5864
5865 (define_insn "*addhi_1_lea"
5866   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5867         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5868                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5869    (clobber (reg:CC FLAGS_REG))]
5870   "!TARGET_PARTIAL_REG_STALL
5871    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5872 {
5873   switch (get_attr_type (insn))
5874     {
5875     case TYPE_LEA:
5876       return "#";
5877     case TYPE_INCDEC:
5878       if (operands[2] == const1_rtx)
5879         return "inc{w}\t%0";
5880       else
5881         {
5882           gcc_assert (operands[2] == constm1_rtx);
5883           return "dec{w}\t%0";
5884         }
5885
5886     default:
5887       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5888          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5889       if (CONST_INT_P (operands[2])
5890           && (INTVAL (operands[2]) == 128
5891               || (INTVAL (operands[2]) < 0
5892                   && INTVAL (operands[2]) != -128)))
5893         {
5894           operands[2] = GEN_INT (-INTVAL (operands[2]));
5895           return "sub{w}\t{%2, %0|%0, %2}";
5896         }
5897       return "add{w}\t{%2, %0|%0, %2}";
5898     }
5899 }
5900   [(set (attr "type")
5901      (if_then_else (eq_attr "alternative" "2")
5902         (const_string "lea")
5903         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5904            (const_string "incdec")
5905            (const_string "alu"))))
5906    (set_attr "mode" "HI,HI,SI")])
5907
5908 (define_insn "*addhi_1"
5909   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5910         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5911                  (match_operand:HI 2 "general_operand" "ri,rm")))
5912    (clobber (reg:CC FLAGS_REG))]
5913   "TARGET_PARTIAL_REG_STALL
5914    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5915 {
5916   switch (get_attr_type (insn))
5917     {
5918     case TYPE_INCDEC:
5919       if (operands[2] == const1_rtx)
5920         return "inc{w}\t%0";
5921       else
5922         {
5923           gcc_assert (operands[2] == constm1_rtx);
5924           return "dec{w}\t%0";
5925         }
5926
5927     default:
5928       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5929          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5930       if (CONST_INT_P (operands[2])
5931           && (INTVAL (operands[2]) == 128
5932               || (INTVAL (operands[2]) < 0
5933                   && INTVAL (operands[2]) != -128)))
5934         {
5935           operands[2] = GEN_INT (-INTVAL (operands[2]));
5936           return "sub{w}\t{%2, %0|%0, %2}";
5937         }
5938       return "add{w}\t{%2, %0|%0, %2}";
5939     }
5940 }
5941   [(set (attr "type")
5942      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5943         (const_string "incdec")
5944         (const_string "alu")))
5945    (set_attr "mode" "HI")])
5946
5947 (define_insn "*addhi_2"
5948   [(set (reg FLAGS_REG)
5949         (compare
5950           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5951                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5952           (const_int 0)))
5953    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5954         (plus:HI (match_dup 1) (match_dup 2)))]
5955   "ix86_match_ccmode (insn, CCGOCmode)
5956    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5957 {
5958   switch (get_attr_type (insn))
5959     {
5960     case TYPE_INCDEC:
5961       if (operands[2] == const1_rtx)
5962         return "inc{w}\t%0";
5963       else
5964         {
5965           gcc_assert (operands[2] == constm1_rtx);
5966           return "dec{w}\t%0";
5967         }
5968
5969     default:
5970       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5971          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5972       if (CONST_INT_P (operands[2])
5973           && (INTVAL (operands[2]) == 128
5974               || (INTVAL (operands[2]) < 0
5975                   && INTVAL (operands[2]) != -128)))
5976         {
5977           operands[2] = GEN_INT (-INTVAL (operands[2]));
5978           return "sub{w}\t{%2, %0|%0, %2}";
5979         }
5980       return "add{w}\t{%2, %0|%0, %2}";
5981     }
5982 }
5983   [(set (attr "type")
5984      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5985         (const_string "incdec")
5986         (const_string "alu")))
5987    (set_attr "mode" "HI")])
5988
5989 (define_insn "*addhi_3"
5990   [(set (reg FLAGS_REG)
5991         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5992                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5993    (clobber (match_scratch:HI 0 "=r"))]
5994   "ix86_match_ccmode (insn, CCZmode)
5995    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5996 {
5997   switch (get_attr_type (insn))
5998     {
5999     case TYPE_INCDEC:
6000       if (operands[2] == const1_rtx)
6001         return "inc{w}\t%0";
6002       else
6003         {
6004           gcc_assert (operands[2] == constm1_rtx);
6005           return "dec{w}\t%0";
6006         }
6007
6008     default:
6009       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6010          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6011       if (CONST_INT_P (operands[2])
6012           && (INTVAL (operands[2]) == 128
6013               || (INTVAL (operands[2]) < 0
6014                   && INTVAL (operands[2]) != -128)))
6015         {
6016           operands[2] = GEN_INT (-INTVAL (operands[2]));
6017           return "sub{w}\t{%2, %0|%0, %2}";
6018         }
6019       return "add{w}\t{%2, %0|%0, %2}";
6020     }
6021 }
6022   [(set (attr "type")
6023      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6024         (const_string "incdec")
6025         (const_string "alu")))
6026    (set_attr "mode" "HI")])
6027
6028 ; See comments above addsi_4 for details.
6029 (define_insn "*addhi_4"
6030   [(set (reg FLAGS_REG)
6031         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6032                  (match_operand:HI 2 "const_int_operand" "n")))
6033    (clobber (match_scratch:HI 0 "=rm"))]
6034   "ix86_match_ccmode (insn, CCGCmode)
6035    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6036 {
6037   switch (get_attr_type (insn))
6038     {
6039     case TYPE_INCDEC:
6040       if (operands[2] == constm1_rtx)
6041         return "inc{w}\t%0";
6042       else
6043         {
6044           gcc_assert (operands[2] == const1_rtx);
6045           return "dec{w}\t%0";
6046         }
6047
6048     default:
6049       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6050       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6051          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6052       if ((INTVAL (operands[2]) == -128
6053            || (INTVAL (operands[2]) > 0
6054                && INTVAL (operands[2]) != 128)))
6055         return "sub{w}\t{%2, %0|%0, %2}";
6056       operands[2] = GEN_INT (-INTVAL (operands[2]));
6057       return "add{w}\t{%2, %0|%0, %2}";
6058     }
6059 }
6060   [(set (attr "type")
6061      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6062         (const_string "incdec")
6063         (const_string "alu")))
6064    (set_attr "mode" "SI")])
6065
6066
6067 (define_insn "*addhi_5"
6068   [(set (reg FLAGS_REG)
6069         (compare
6070           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6071                    (match_operand:HI 2 "general_operand" "rmni"))
6072           (const_int 0)))
6073    (clobber (match_scratch:HI 0 "=r"))]
6074   "ix86_match_ccmode (insn, CCGOCmode)
6075    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6076 {
6077   switch (get_attr_type (insn))
6078     {
6079     case TYPE_INCDEC:
6080       if (operands[2] == const1_rtx)
6081         return "inc{w}\t%0";
6082       else
6083         {
6084           gcc_assert (operands[2] == constm1_rtx);
6085           return "dec{w}\t%0";
6086         }
6087
6088     default:
6089       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6090          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6091       if (CONST_INT_P (operands[2])
6092           && (INTVAL (operands[2]) == 128
6093               || (INTVAL (operands[2]) < 0
6094                   && INTVAL (operands[2]) != -128)))
6095         {
6096           operands[2] = GEN_INT (-INTVAL (operands[2]));
6097           return "sub{w}\t{%2, %0|%0, %2}";
6098         }
6099       return "add{w}\t{%2, %0|%0, %2}";
6100     }
6101 }
6102   [(set (attr "type")
6103      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6104         (const_string "incdec")
6105         (const_string "alu")))
6106    (set_attr "mode" "HI")])
6107
6108 (define_expand "addqi3"
6109   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6110                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6111                             (match_operand:QI 2 "general_operand" "")))
6112               (clobber (reg:CC FLAGS_REG))])]
6113   "TARGET_QIMODE_MATH"
6114   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6115
6116 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6117 (define_insn "*addqi_1_lea"
6118   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6119         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6120                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6121    (clobber (reg:CC FLAGS_REG))]
6122   "!TARGET_PARTIAL_REG_STALL
6123    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6124 {
6125   int widen = (which_alternative == 2);
6126   switch (get_attr_type (insn))
6127     {
6128     case TYPE_LEA:
6129       return "#";
6130     case TYPE_INCDEC:
6131       if (operands[2] == const1_rtx)
6132         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6133       else
6134         {
6135           gcc_assert (operands[2] == constm1_rtx);
6136           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6137         }
6138
6139     default:
6140       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6141          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6142       if (CONST_INT_P (operands[2])
6143           && (INTVAL (operands[2]) == 128
6144               || (INTVAL (operands[2]) < 0
6145                   && INTVAL (operands[2]) != -128)))
6146         {
6147           operands[2] = GEN_INT (-INTVAL (operands[2]));
6148           if (widen)
6149             return "sub{l}\t{%2, %k0|%k0, %2}";
6150           else
6151             return "sub{b}\t{%2, %0|%0, %2}";
6152         }
6153       if (widen)
6154         return "add{l}\t{%k2, %k0|%k0, %k2}";
6155       else
6156         return "add{b}\t{%2, %0|%0, %2}";
6157     }
6158 }
6159   [(set (attr "type")
6160      (if_then_else (eq_attr "alternative" "3")
6161         (const_string "lea")
6162         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6163            (const_string "incdec")
6164            (const_string "alu"))))
6165    (set_attr "mode" "QI,QI,SI,SI")])
6166
6167 (define_insn "*addqi_1"
6168   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6169         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6170                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6171    (clobber (reg:CC FLAGS_REG))]
6172   "TARGET_PARTIAL_REG_STALL
6173    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6174 {
6175   int widen = (which_alternative == 2);
6176   switch (get_attr_type (insn))
6177     {
6178     case TYPE_INCDEC:
6179       if (operands[2] == const1_rtx)
6180         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6181       else
6182         {
6183           gcc_assert (operands[2] == constm1_rtx);
6184           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6185         }
6186
6187     default:
6188       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6189          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6190       if (CONST_INT_P (operands[2])
6191           && (INTVAL (operands[2]) == 128
6192               || (INTVAL (operands[2]) < 0
6193                   && INTVAL (operands[2]) != -128)))
6194         {
6195           operands[2] = GEN_INT (-INTVAL (operands[2]));
6196           if (widen)
6197             return "sub{l}\t{%2, %k0|%k0, %2}";
6198           else
6199             return "sub{b}\t{%2, %0|%0, %2}";
6200         }
6201       if (widen)
6202         return "add{l}\t{%k2, %k0|%k0, %k2}";
6203       else
6204         return "add{b}\t{%2, %0|%0, %2}";
6205     }
6206 }
6207   [(set (attr "type")
6208      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6209         (const_string "incdec")
6210         (const_string "alu")))
6211    (set_attr "mode" "QI,QI,SI")])
6212
6213 (define_insn "*addqi_1_slp"
6214   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6215         (plus:QI (match_dup 0)
6216                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6217    (clobber (reg:CC FLAGS_REG))]
6218   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6219    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6220 {
6221   switch (get_attr_type (insn))
6222     {
6223     case TYPE_INCDEC:
6224       if (operands[1] == const1_rtx)
6225         return "inc{b}\t%0";
6226       else
6227         {
6228           gcc_assert (operands[1] == constm1_rtx);
6229           return "dec{b}\t%0";
6230         }
6231
6232     default:
6233       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6234       if (CONST_INT_P (operands[1])
6235           && INTVAL (operands[1]) < 0)
6236         {
6237           operands[1] = GEN_INT (-INTVAL (operands[1]));
6238           return "sub{b}\t{%1, %0|%0, %1}";
6239         }
6240       return "add{b}\t{%1, %0|%0, %1}";
6241     }
6242 }
6243   [(set (attr "type")
6244      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6245         (const_string "incdec")
6246         (const_string "alu1")))
6247    (set (attr "memory")
6248      (if_then_else (match_operand 1 "memory_operand" "")
6249         (const_string "load")
6250         (const_string "none")))
6251    (set_attr "mode" "QI")])
6252
6253 (define_insn "*addqi_2"
6254   [(set (reg FLAGS_REG)
6255         (compare
6256           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6257                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6258           (const_int 0)))
6259    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6260         (plus:QI (match_dup 1) (match_dup 2)))]
6261   "ix86_match_ccmode (insn, CCGOCmode)
6262    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6263 {
6264   switch (get_attr_type (insn))
6265     {
6266     case TYPE_INCDEC:
6267       if (operands[2] == const1_rtx)
6268         return "inc{b}\t%0";
6269       else
6270         {
6271           gcc_assert (operands[2] == constm1_rtx
6272                       || (CONST_INT_P (operands[2])
6273                           && INTVAL (operands[2]) == 255));
6274           return "dec{b}\t%0";
6275         }
6276
6277     default:
6278       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6279       if (CONST_INT_P (operands[2])
6280           && INTVAL (operands[2]) < 0)
6281         {
6282           operands[2] = GEN_INT (-INTVAL (operands[2]));
6283           return "sub{b}\t{%2, %0|%0, %2}";
6284         }
6285       return "add{b}\t{%2, %0|%0, %2}";
6286     }
6287 }
6288   [(set (attr "type")
6289      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6290         (const_string "incdec")
6291         (const_string "alu")))
6292    (set_attr "mode" "QI")])
6293
6294 (define_insn "*addqi_3"
6295   [(set (reg FLAGS_REG)
6296         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6297                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6298    (clobber (match_scratch:QI 0 "=q"))]
6299   "ix86_match_ccmode (insn, CCZmode)
6300    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6301 {
6302   switch (get_attr_type (insn))
6303     {
6304     case TYPE_INCDEC:
6305       if (operands[2] == const1_rtx)
6306         return "inc{b}\t%0";
6307       else
6308         {
6309           gcc_assert (operands[2] == constm1_rtx
6310                       || (CONST_INT_P (operands[2])
6311                           && INTVAL (operands[2]) == 255));
6312           return "dec{b}\t%0";
6313         }
6314
6315     default:
6316       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6317       if (CONST_INT_P (operands[2])
6318           && INTVAL (operands[2]) < 0)
6319         {
6320           operands[2] = GEN_INT (-INTVAL (operands[2]));
6321           return "sub{b}\t{%2, %0|%0, %2}";
6322         }
6323       return "add{b}\t{%2, %0|%0, %2}";
6324     }
6325 }
6326   [(set (attr "type")
6327      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6328         (const_string "incdec")
6329         (const_string "alu")))
6330    (set_attr "mode" "QI")])
6331
6332 ; See comments above addsi_4 for details.
6333 (define_insn "*addqi_4"
6334   [(set (reg FLAGS_REG)
6335         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6336                  (match_operand:QI 2 "const_int_operand" "n")))
6337    (clobber (match_scratch:QI 0 "=qm"))]
6338   "ix86_match_ccmode (insn, CCGCmode)
6339    && (INTVAL (operands[2]) & 0xff) != 0x80"
6340 {
6341   switch (get_attr_type (insn))
6342     {
6343     case TYPE_INCDEC:
6344       if (operands[2] == constm1_rtx
6345           || (CONST_INT_P (operands[2])
6346               && INTVAL (operands[2]) == 255))
6347         return "inc{b}\t%0";
6348       else
6349         {
6350           gcc_assert (operands[2] == const1_rtx);
6351           return "dec{b}\t%0";
6352         }
6353
6354     default:
6355       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6356       if (INTVAL (operands[2]) < 0)
6357         {
6358           operands[2] = GEN_INT (-INTVAL (operands[2]));
6359           return "add{b}\t{%2, %0|%0, %2}";
6360         }
6361       return "sub{b}\t{%2, %0|%0, %2}";
6362     }
6363 }
6364   [(set (attr "type")
6365      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6366         (const_string "incdec")
6367         (const_string "alu")))
6368    (set_attr "mode" "QI")])
6369
6370
6371 (define_insn "*addqi_5"
6372   [(set (reg FLAGS_REG)
6373         (compare
6374           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6375                    (match_operand:QI 2 "general_operand" "qmni"))
6376           (const_int 0)))
6377    (clobber (match_scratch:QI 0 "=q"))]
6378   "ix86_match_ccmode (insn, CCGOCmode)
6379    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6380 {
6381   switch (get_attr_type (insn))
6382     {
6383     case TYPE_INCDEC:
6384       if (operands[2] == const1_rtx)
6385         return "inc{b}\t%0";
6386       else
6387         {
6388           gcc_assert (operands[2] == constm1_rtx
6389                       || (CONST_INT_P (operands[2])
6390                           && INTVAL (operands[2]) == 255));
6391           return "dec{b}\t%0";
6392         }
6393
6394     default:
6395       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6396       if (CONST_INT_P (operands[2])
6397           && INTVAL (operands[2]) < 0)
6398         {
6399           operands[2] = GEN_INT (-INTVAL (operands[2]));
6400           return "sub{b}\t{%2, %0|%0, %2}";
6401         }
6402       return "add{b}\t{%2, %0|%0, %2}";
6403     }
6404 }
6405   [(set (attr "type")
6406      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6407         (const_string "incdec")
6408         (const_string "alu")))
6409    (set_attr "mode" "QI")])
6410
6411
6412 (define_insn "addqi_ext_1"
6413   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6414                          (const_int 8)
6415                          (const_int 8))
6416         (plus:SI
6417           (zero_extract:SI
6418             (match_operand 1 "ext_register_operand" "0")
6419             (const_int 8)
6420             (const_int 8))
6421           (match_operand:QI 2 "general_operand" "Qmn")))
6422    (clobber (reg:CC FLAGS_REG))]
6423   "!TARGET_64BIT"
6424 {
6425   switch (get_attr_type (insn))
6426     {
6427     case TYPE_INCDEC:
6428       if (operands[2] == const1_rtx)
6429         return "inc{b}\t%h0";
6430       else
6431         {
6432           gcc_assert (operands[2] == constm1_rtx
6433                       || (CONST_INT_P (operands[2])
6434                           && INTVAL (operands[2]) == 255));
6435           return "dec{b}\t%h0";
6436         }
6437
6438     default:
6439       return "add{b}\t{%2, %h0|%h0, %2}";
6440     }
6441 }
6442   [(set (attr "type")
6443      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6444         (const_string "incdec")
6445         (const_string "alu")))
6446    (set_attr "mode" "QI")])
6447
6448 (define_insn "*addqi_ext_1_rex64"
6449   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6450                          (const_int 8)
6451                          (const_int 8))
6452         (plus:SI
6453           (zero_extract:SI
6454             (match_operand 1 "ext_register_operand" "0")
6455             (const_int 8)
6456             (const_int 8))
6457           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6458    (clobber (reg:CC FLAGS_REG))]
6459   "TARGET_64BIT"
6460 {
6461   switch (get_attr_type (insn))
6462     {
6463     case TYPE_INCDEC:
6464       if (operands[2] == const1_rtx)
6465         return "inc{b}\t%h0";
6466       else
6467         {
6468           gcc_assert (operands[2] == constm1_rtx
6469                       || (CONST_INT_P (operands[2])
6470                           && INTVAL (operands[2]) == 255));
6471           return "dec{b}\t%h0";
6472         }
6473
6474     default:
6475       return "add{b}\t{%2, %h0|%h0, %2}";
6476     }
6477 }
6478   [(set (attr "type")
6479      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6480         (const_string "incdec")
6481         (const_string "alu")))
6482    (set_attr "mode" "QI")])
6483
6484 (define_insn "*addqi_ext_2"
6485   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6486                          (const_int 8)
6487                          (const_int 8))
6488         (plus:SI
6489           (zero_extract:SI
6490             (match_operand 1 "ext_register_operand" "%0")
6491             (const_int 8)
6492             (const_int 8))
6493           (zero_extract:SI
6494             (match_operand 2 "ext_register_operand" "Q")
6495             (const_int 8)
6496             (const_int 8))))
6497    (clobber (reg:CC FLAGS_REG))]
6498   ""
6499   "add{b}\t{%h2, %h0|%h0, %h2}"
6500   [(set_attr "type" "alu")
6501    (set_attr "mode" "QI")])
6502
6503 ;; The patterns that match these are at the end of this file.
6504
6505 (define_expand "addxf3"
6506   [(set (match_operand:XF 0 "register_operand" "")
6507         (plus:XF (match_operand:XF 1 "register_operand" "")
6508                  (match_operand:XF 2 "register_operand" "")))]
6509   "TARGET_80387"
6510   "")
6511
6512 (define_expand "adddf3"
6513   [(set (match_operand:DF 0 "register_operand" "")
6514         (plus:DF (match_operand:DF 1 "register_operand" "")
6515                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6516   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6517   "")
6518
6519 (define_expand "addsf3"
6520   [(set (match_operand:SF 0 "register_operand" "")
6521         (plus:SF (match_operand:SF 1 "register_operand" "")
6522                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6523   "TARGET_80387 || TARGET_SSE_MATH"
6524   "")
6525 \f
6526 ;; Subtract instructions
6527
6528 ;; %%% splits for subditi3
6529
6530 (define_expand "subti3"
6531   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6532                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6533                              (match_operand:TI 2 "x86_64_general_operand" "")))
6534               (clobber (reg:CC FLAGS_REG))])]
6535   "TARGET_64BIT"
6536   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6537
6538 (define_insn "*subti3_1"
6539   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6540         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6541                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6542    (clobber (reg:CC FLAGS_REG))]
6543   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6544   "#")
6545
6546 (define_split
6547   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6548         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6549                   (match_operand:TI 2 "general_operand" "")))
6550    (clobber (reg:CC FLAGS_REG))]
6551   "TARGET_64BIT && reload_completed"
6552   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6553               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6554    (parallel [(set (match_dup 3)
6555                    (minus:DI (match_dup 4)
6556                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6557                                       (match_dup 5))))
6558               (clobber (reg:CC FLAGS_REG))])]
6559   "split_ti (operands+0, 1, operands+0, operands+3);
6560    split_ti (operands+1, 1, operands+1, operands+4);
6561    split_ti (operands+2, 1, operands+2, operands+5);")
6562
6563 ;; %%% splits for subsidi3
6564
6565 (define_expand "subdi3"
6566   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6567                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6568                              (match_operand:DI 2 "x86_64_general_operand" "")))
6569               (clobber (reg:CC FLAGS_REG))])]
6570   ""
6571   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6572
6573 (define_insn "*subdi3_1"
6574   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6575         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6576                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6577    (clobber (reg:CC FLAGS_REG))]
6578   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6579   "#")
6580
6581 (define_split
6582   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6583         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6584                   (match_operand:DI 2 "general_operand" "")))
6585    (clobber (reg:CC FLAGS_REG))]
6586   "!TARGET_64BIT && reload_completed"
6587   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6588               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6589    (parallel [(set (match_dup 3)
6590                    (minus:SI (match_dup 4)
6591                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6592                                       (match_dup 5))))
6593               (clobber (reg:CC FLAGS_REG))])]
6594   "split_di (operands+0, 1, operands+0, operands+3);
6595    split_di (operands+1, 1, operands+1, operands+4);
6596    split_di (operands+2, 1, operands+2, operands+5);")
6597
6598 (define_insn "subdi3_carry_rex64"
6599   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6600           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6601             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6602                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6603    (clobber (reg:CC FLAGS_REG))]
6604   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6605   "sbb{q}\t{%2, %0|%0, %2}"
6606   [(set_attr "type" "alu")
6607    (set_attr "pent_pair" "pu")
6608    (set_attr "mode" "DI")])
6609
6610 (define_insn "*subdi_1_rex64"
6611   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6612         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6613                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6614    (clobber (reg:CC FLAGS_REG))]
6615   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6616   "sub{q}\t{%2, %0|%0, %2}"
6617   [(set_attr "type" "alu")
6618    (set_attr "mode" "DI")])
6619
6620 (define_insn "*subdi_2_rex64"
6621   [(set (reg FLAGS_REG)
6622         (compare
6623           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6624                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6625           (const_int 0)))
6626    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6627         (minus:DI (match_dup 1) (match_dup 2)))]
6628   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6629    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6630   "sub{q}\t{%2, %0|%0, %2}"
6631   [(set_attr "type" "alu")
6632    (set_attr "mode" "DI")])
6633
6634 (define_insn "*subdi_3_rex63"
6635   [(set (reg FLAGS_REG)
6636         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6637                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6638    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6639         (minus:DI (match_dup 1) (match_dup 2)))]
6640   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6641    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6642   "sub{q}\t{%2, %0|%0, %2}"
6643   [(set_attr "type" "alu")
6644    (set_attr "mode" "DI")])
6645
6646 (define_insn "subqi3_carry"
6647   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6648           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6649             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6650                (match_operand:QI 2 "general_operand" "qi,qm"))))
6651    (clobber (reg:CC FLAGS_REG))]
6652   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6653   "sbb{b}\t{%2, %0|%0, %2}"
6654   [(set_attr "type" "alu")
6655    (set_attr "pent_pair" "pu")
6656    (set_attr "mode" "QI")])
6657
6658 (define_insn "subhi3_carry"
6659   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6660           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6661             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6662                (match_operand:HI 2 "general_operand" "ri,rm"))))
6663    (clobber (reg:CC FLAGS_REG))]
6664   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6665   "sbb{w}\t{%2, %0|%0, %2}"
6666   [(set_attr "type" "alu")
6667    (set_attr "pent_pair" "pu")
6668    (set_attr "mode" "HI")])
6669
6670 (define_insn "subsi3_carry"
6671   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6672           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6673             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6674                (match_operand:SI 2 "general_operand" "ri,rm"))))
6675    (clobber (reg:CC FLAGS_REG))]
6676   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6677   "sbb{l}\t{%2, %0|%0, %2}"
6678   [(set_attr "type" "alu")
6679    (set_attr "pent_pair" "pu")
6680    (set_attr "mode" "SI")])
6681
6682 (define_insn "subsi3_carry_zext"
6683   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6684           (zero_extend:DI
6685             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6686               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6687                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6688    (clobber (reg:CC FLAGS_REG))]
6689   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6690   "sbb{l}\t{%2, %k0|%k0, %2}"
6691   [(set_attr "type" "alu")
6692    (set_attr "pent_pair" "pu")
6693    (set_attr "mode" "SI")])
6694
6695 (define_expand "subsi3"
6696   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6697                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6698                              (match_operand:SI 2 "general_operand" "")))
6699               (clobber (reg:CC FLAGS_REG))])]
6700   ""
6701   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6702
6703 (define_insn "*subsi_1"
6704   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6705         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6706                   (match_operand:SI 2 "general_operand" "ri,rm")))
6707    (clobber (reg:CC FLAGS_REG))]
6708   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6709   "sub{l}\t{%2, %0|%0, %2}"
6710   [(set_attr "type" "alu")
6711    (set_attr "mode" "SI")])
6712
6713 (define_insn "*subsi_1_zext"
6714   [(set (match_operand:DI 0 "register_operand" "=r")
6715         (zero_extend:DI
6716           (minus:SI (match_operand:SI 1 "register_operand" "0")
6717                     (match_operand:SI 2 "general_operand" "rim"))))
6718    (clobber (reg:CC FLAGS_REG))]
6719   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6720   "sub{l}\t{%2, %k0|%k0, %2}"
6721   [(set_attr "type" "alu")
6722    (set_attr "mode" "SI")])
6723
6724 (define_insn "*subsi_2"
6725   [(set (reg FLAGS_REG)
6726         (compare
6727           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6728                     (match_operand:SI 2 "general_operand" "ri,rm"))
6729           (const_int 0)))
6730    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6731         (minus:SI (match_dup 1) (match_dup 2)))]
6732   "ix86_match_ccmode (insn, CCGOCmode)
6733    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6734   "sub{l}\t{%2, %0|%0, %2}"
6735   [(set_attr "type" "alu")
6736    (set_attr "mode" "SI")])
6737
6738 (define_insn "*subsi_2_zext"
6739   [(set (reg FLAGS_REG)
6740         (compare
6741           (minus:SI (match_operand:SI 1 "register_operand" "0")
6742                     (match_operand:SI 2 "general_operand" "rim"))
6743           (const_int 0)))
6744    (set (match_operand:DI 0 "register_operand" "=r")
6745         (zero_extend:DI
6746           (minus:SI (match_dup 1)
6747                     (match_dup 2))))]
6748   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6749    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6750   "sub{l}\t{%2, %k0|%k0, %2}"
6751   [(set_attr "type" "alu")
6752    (set_attr "mode" "SI")])
6753
6754 (define_insn "*subsi_3"
6755   [(set (reg FLAGS_REG)
6756         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6757                  (match_operand:SI 2 "general_operand" "ri,rm")))
6758    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6759         (minus:SI (match_dup 1) (match_dup 2)))]
6760   "ix86_match_ccmode (insn, CCmode)
6761    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6762   "sub{l}\t{%2, %0|%0, %2}"
6763   [(set_attr "type" "alu")
6764    (set_attr "mode" "SI")])
6765
6766 (define_insn "*subsi_3_zext"
6767   [(set (reg FLAGS_REG)
6768         (compare (match_operand:SI 1 "register_operand" "0")
6769                  (match_operand:SI 2 "general_operand" "rim")))
6770    (set (match_operand:DI 0 "register_operand" "=r")
6771         (zero_extend:DI
6772           (minus:SI (match_dup 1)
6773                     (match_dup 2))))]
6774   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6775    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6776   "sub{l}\t{%2, %1|%1, %2}"
6777   [(set_attr "type" "alu")
6778    (set_attr "mode" "DI")])
6779
6780 (define_expand "subhi3"
6781   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6782                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6783                              (match_operand:HI 2 "general_operand" "")))
6784               (clobber (reg:CC FLAGS_REG))])]
6785   "TARGET_HIMODE_MATH"
6786   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6787
6788 (define_insn "*subhi_1"
6789   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6790         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6791                   (match_operand:HI 2 "general_operand" "ri,rm")))
6792    (clobber (reg:CC FLAGS_REG))]
6793   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6794   "sub{w}\t{%2, %0|%0, %2}"
6795   [(set_attr "type" "alu")
6796    (set_attr "mode" "HI")])
6797
6798 (define_insn "*subhi_2"
6799   [(set (reg FLAGS_REG)
6800         (compare
6801           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6802                     (match_operand:HI 2 "general_operand" "ri,rm"))
6803           (const_int 0)))
6804    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6805         (minus:HI (match_dup 1) (match_dup 2)))]
6806   "ix86_match_ccmode (insn, CCGOCmode)
6807    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6808   "sub{w}\t{%2, %0|%0, %2}"
6809   [(set_attr "type" "alu")
6810    (set_attr "mode" "HI")])
6811
6812 (define_insn "*subhi_3"
6813   [(set (reg FLAGS_REG)
6814         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6815                  (match_operand:HI 2 "general_operand" "ri,rm")))
6816    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6817         (minus:HI (match_dup 1) (match_dup 2)))]
6818   "ix86_match_ccmode (insn, CCmode)
6819    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6820   "sub{w}\t{%2, %0|%0, %2}"
6821   [(set_attr "type" "alu")
6822    (set_attr "mode" "HI")])
6823
6824 (define_expand "subqi3"
6825   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6826                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6827                              (match_operand:QI 2 "general_operand" "")))
6828               (clobber (reg:CC FLAGS_REG))])]
6829   "TARGET_QIMODE_MATH"
6830   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6831
6832 (define_insn "*subqi_1"
6833   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6834         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6835                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6836    (clobber (reg:CC FLAGS_REG))]
6837   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6838   "sub{b}\t{%2, %0|%0, %2}"
6839   [(set_attr "type" "alu")
6840    (set_attr "mode" "QI")])
6841
6842 (define_insn "*subqi_1_slp"
6843   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6844         (minus:QI (match_dup 0)
6845                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6846    (clobber (reg:CC FLAGS_REG))]
6847   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6848    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6849   "sub{b}\t{%1, %0|%0, %1}"
6850   [(set_attr "type" "alu1")
6851    (set_attr "mode" "QI")])
6852
6853 (define_insn "*subqi_2"
6854   [(set (reg FLAGS_REG)
6855         (compare
6856           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6857                     (match_operand:QI 2 "general_operand" "qi,qm"))
6858           (const_int 0)))
6859    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6860         (minus:HI (match_dup 1) (match_dup 2)))]
6861   "ix86_match_ccmode (insn, CCGOCmode)
6862    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6863   "sub{b}\t{%2, %0|%0, %2}"
6864   [(set_attr "type" "alu")
6865    (set_attr "mode" "QI")])
6866
6867 (define_insn "*subqi_3"
6868   [(set (reg FLAGS_REG)
6869         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6870                  (match_operand:QI 2 "general_operand" "qi,qm")))
6871    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6872         (minus:HI (match_dup 1) (match_dup 2)))]
6873   "ix86_match_ccmode (insn, CCmode)
6874    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6875   "sub{b}\t{%2, %0|%0, %2}"
6876   [(set_attr "type" "alu")
6877    (set_attr "mode" "QI")])
6878
6879 ;; The patterns that match these are at the end of this file.
6880
6881 (define_expand "subxf3"
6882   [(set (match_operand:XF 0 "register_operand" "")
6883         (minus:XF (match_operand:XF 1 "register_operand" "")
6884                   (match_operand:XF 2 "register_operand" "")))]
6885   "TARGET_80387"
6886   "")
6887
6888 (define_expand "subdf3"
6889   [(set (match_operand:DF 0 "register_operand" "")
6890         (minus:DF (match_operand:DF 1 "register_operand" "")
6891                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6892   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6893   "")
6894
6895 (define_expand "subsf3"
6896   [(set (match_operand:SF 0 "register_operand" "")
6897         (minus:SF (match_operand:SF 1 "register_operand" "")
6898                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6899   "TARGET_80387 || TARGET_SSE_MATH"
6900   "")
6901 \f
6902 ;; Multiply instructions
6903
6904 (define_expand "muldi3"
6905   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6906                    (mult:DI (match_operand:DI 1 "register_operand" "")
6907                             (match_operand:DI 2 "x86_64_general_operand" "")))
6908               (clobber (reg:CC FLAGS_REG))])]
6909   "TARGET_64BIT"
6910   "")
6911
6912 (define_insn "*muldi3_1_rex64"
6913   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6914         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6915                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6916    (clobber (reg:CC FLAGS_REG))]
6917   "TARGET_64BIT
6918    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6919   "@
6920    imul{q}\t{%2, %1, %0|%0, %1, %2}
6921    imul{q}\t{%2, %1, %0|%0, %1, %2}
6922    imul{q}\t{%2, %0|%0, %2}"
6923   [(set_attr "type" "imul")
6924    (set_attr "prefix_0f" "0,0,1")
6925    (set (attr "athlon_decode")
6926         (cond [(eq_attr "cpu" "athlon")
6927                   (const_string "vector")
6928                (eq_attr "alternative" "1")
6929                   (const_string "vector")
6930                (and (eq_attr "alternative" "2")
6931                     (match_operand 1 "memory_operand" ""))
6932                   (const_string "vector")]
6933               (const_string "direct")))
6934    (set_attr "mode" "DI")])
6935
6936 (define_expand "mulsi3"
6937   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6938                    (mult:SI (match_operand:SI 1 "register_operand" "")
6939                             (match_operand:SI 2 "general_operand" "")))
6940               (clobber (reg:CC FLAGS_REG))])]
6941   ""
6942   "")
6943
6944 (define_insn "*mulsi3_1"
6945   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6946         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6947                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6948    (clobber (reg:CC FLAGS_REG))]
6949   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6950   "@
6951    imul{l}\t{%2, %1, %0|%0, %1, %2}
6952    imul{l}\t{%2, %1, %0|%0, %1, %2}
6953    imul{l}\t{%2, %0|%0, %2}"
6954   [(set_attr "type" "imul")
6955    (set_attr "prefix_0f" "0,0,1")
6956    (set (attr "athlon_decode")
6957         (cond [(eq_attr "cpu" "athlon")
6958                   (const_string "vector")
6959                (eq_attr "alternative" "1")
6960                   (const_string "vector")
6961                (and (eq_attr "alternative" "2")
6962                     (match_operand 1 "memory_operand" ""))
6963                   (const_string "vector")]
6964               (const_string "direct")))
6965    (set_attr "mode" "SI")])
6966
6967 (define_insn "*mulsi3_1_zext"
6968   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6969         (zero_extend:DI
6970           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6971                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6972    (clobber (reg:CC FLAGS_REG))]
6973   "TARGET_64BIT
6974    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6975   "@
6976    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6977    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6978    imul{l}\t{%2, %k0|%k0, %2}"
6979   [(set_attr "type" "imul")
6980    (set_attr "prefix_0f" "0,0,1")
6981    (set (attr "athlon_decode")
6982         (cond [(eq_attr "cpu" "athlon")
6983                   (const_string "vector")
6984                (eq_attr "alternative" "1")
6985                   (const_string "vector")
6986                (and (eq_attr "alternative" "2")
6987                     (match_operand 1 "memory_operand" ""))
6988                   (const_string "vector")]
6989               (const_string "direct")))
6990    (set_attr "mode" "SI")])
6991
6992 (define_expand "mulhi3"
6993   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6994                    (mult:HI (match_operand:HI 1 "register_operand" "")
6995                             (match_operand:HI 2 "general_operand" "")))
6996               (clobber (reg:CC FLAGS_REG))])]
6997   "TARGET_HIMODE_MATH"
6998   "")
6999
7000 (define_insn "*mulhi3_1"
7001   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7002         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7003                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7004    (clobber (reg:CC FLAGS_REG))]
7005   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7006   "@
7007    imul{w}\t{%2, %1, %0|%0, %1, %2}
7008    imul{w}\t{%2, %1, %0|%0, %1, %2}
7009    imul{w}\t{%2, %0|%0, %2}"
7010   [(set_attr "type" "imul")
7011    (set_attr "prefix_0f" "0,0,1")
7012    (set (attr "athlon_decode")
7013         (cond [(eq_attr "cpu" "athlon")
7014                   (const_string "vector")
7015                (eq_attr "alternative" "1,2")
7016                   (const_string "vector")]
7017               (const_string "direct")))
7018    (set_attr "mode" "HI")])
7019
7020 (define_expand "mulqi3"
7021   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7022                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7023                             (match_operand:QI 2 "register_operand" "")))
7024               (clobber (reg:CC FLAGS_REG))])]
7025   "TARGET_QIMODE_MATH"
7026   "")
7027
7028 (define_insn "*mulqi3_1"
7029   [(set (match_operand:QI 0 "register_operand" "=a")
7030         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7031                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7032    (clobber (reg:CC FLAGS_REG))]
7033   "TARGET_QIMODE_MATH
7034    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7035   "mul{b}\t%2"
7036   [(set_attr "type" "imul")
7037    (set_attr "length_immediate" "0")
7038    (set (attr "athlon_decode")
7039      (if_then_else (eq_attr "cpu" "athlon")
7040         (const_string "vector")
7041         (const_string "direct")))
7042    (set_attr "mode" "QI")])
7043
7044 (define_expand "umulqihi3"
7045   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7046                    (mult:HI (zero_extend:HI
7047                               (match_operand:QI 1 "nonimmediate_operand" ""))
7048                             (zero_extend:HI
7049                               (match_operand:QI 2 "register_operand" ""))))
7050               (clobber (reg:CC FLAGS_REG))])]
7051   "TARGET_QIMODE_MATH"
7052   "")
7053
7054 (define_insn "*umulqihi3_1"
7055   [(set (match_operand:HI 0 "register_operand" "=a")
7056         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7057                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7058    (clobber (reg:CC FLAGS_REG))]
7059   "TARGET_QIMODE_MATH
7060    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7061   "mul{b}\t%2"
7062   [(set_attr "type" "imul")
7063    (set_attr "length_immediate" "0")
7064    (set (attr "athlon_decode")
7065      (if_then_else (eq_attr "cpu" "athlon")
7066         (const_string "vector")
7067         (const_string "direct")))
7068    (set_attr "mode" "QI")])
7069
7070 (define_expand "mulqihi3"
7071   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7072                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7073                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7074               (clobber (reg:CC FLAGS_REG))])]
7075   "TARGET_QIMODE_MATH"
7076   "")
7077
7078 (define_insn "*mulqihi3_insn"
7079   [(set (match_operand:HI 0 "register_operand" "=a")
7080         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7081                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7082    (clobber (reg:CC FLAGS_REG))]
7083   "TARGET_QIMODE_MATH
7084    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7085   "imul{b}\t%2"
7086   [(set_attr "type" "imul")
7087    (set_attr "length_immediate" "0")
7088    (set (attr "athlon_decode")
7089      (if_then_else (eq_attr "cpu" "athlon")
7090         (const_string "vector")
7091         (const_string "direct")))
7092    (set_attr "mode" "QI")])
7093
7094 (define_expand "umulditi3"
7095   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7096                    (mult:TI (zero_extend:TI
7097                               (match_operand:DI 1 "nonimmediate_operand" ""))
7098                             (zero_extend:TI
7099                               (match_operand:DI 2 "register_operand" ""))))
7100               (clobber (reg:CC FLAGS_REG))])]
7101   "TARGET_64BIT"
7102   "")
7103
7104 (define_insn "*umulditi3_insn"
7105   [(set (match_operand:TI 0 "register_operand" "=A")
7106         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7107                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7108    (clobber (reg:CC FLAGS_REG))]
7109   "TARGET_64BIT
7110    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7111   "mul{q}\t%2"
7112   [(set_attr "type" "imul")
7113    (set_attr "length_immediate" "0")
7114    (set (attr "athlon_decode")
7115      (if_then_else (eq_attr "cpu" "athlon")
7116         (const_string "vector")
7117         (const_string "double")))
7118    (set_attr "mode" "DI")])
7119
7120 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7121 (define_expand "umulsidi3"
7122   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7123                    (mult:DI (zero_extend:DI
7124                               (match_operand:SI 1 "nonimmediate_operand" ""))
7125                             (zero_extend:DI
7126                               (match_operand:SI 2 "register_operand" ""))))
7127               (clobber (reg:CC FLAGS_REG))])]
7128   "!TARGET_64BIT"
7129   "")
7130
7131 (define_insn "*umulsidi3_insn"
7132   [(set (match_operand:DI 0 "register_operand" "=A")
7133         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7134                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7135    (clobber (reg:CC FLAGS_REG))]
7136   "!TARGET_64BIT
7137    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7138   "mul{l}\t%2"
7139   [(set_attr "type" "imul")
7140    (set_attr "length_immediate" "0")
7141    (set (attr "athlon_decode")
7142      (if_then_else (eq_attr "cpu" "athlon")
7143         (const_string "vector")
7144         (const_string "double")))
7145    (set_attr "mode" "SI")])
7146
7147 (define_expand "mulditi3"
7148   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7149                    (mult:TI (sign_extend:TI
7150                               (match_operand:DI 1 "nonimmediate_operand" ""))
7151                             (sign_extend:TI
7152                               (match_operand:DI 2 "register_operand" ""))))
7153               (clobber (reg:CC FLAGS_REG))])]
7154   "TARGET_64BIT"
7155   "")
7156
7157 (define_insn "*mulditi3_insn"
7158   [(set (match_operand:TI 0 "register_operand" "=A")
7159         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7160                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7161    (clobber (reg:CC FLAGS_REG))]
7162   "TARGET_64BIT
7163    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7164   "imul{q}\t%2"
7165   [(set_attr "type" "imul")
7166    (set_attr "length_immediate" "0")
7167    (set (attr "athlon_decode")
7168      (if_then_else (eq_attr "cpu" "athlon")
7169         (const_string "vector")
7170         (const_string "double")))
7171    (set_attr "mode" "DI")])
7172
7173 (define_expand "mulsidi3"
7174   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7175                    (mult:DI (sign_extend:DI
7176                               (match_operand:SI 1 "nonimmediate_operand" ""))
7177                             (sign_extend:DI
7178                               (match_operand:SI 2 "register_operand" ""))))
7179               (clobber (reg:CC FLAGS_REG))])]
7180   "!TARGET_64BIT"
7181   "")
7182
7183 (define_insn "*mulsidi3_insn"
7184   [(set (match_operand:DI 0 "register_operand" "=A")
7185         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7186                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7187    (clobber (reg:CC FLAGS_REG))]
7188   "!TARGET_64BIT
7189    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7190   "imul{l}\t%2"
7191   [(set_attr "type" "imul")
7192    (set_attr "length_immediate" "0")
7193    (set (attr "athlon_decode")
7194      (if_then_else (eq_attr "cpu" "athlon")
7195         (const_string "vector")
7196         (const_string "double")))
7197    (set_attr "mode" "SI")])
7198
7199 (define_expand "umuldi3_highpart"
7200   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7201                    (truncate:DI
7202                      (lshiftrt:TI
7203                        (mult:TI (zero_extend:TI
7204                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7205                                 (zero_extend:TI
7206                                   (match_operand:DI 2 "register_operand" "")))
7207                        (const_int 64))))
7208               (clobber (match_scratch:DI 3 ""))
7209               (clobber (reg:CC FLAGS_REG))])]
7210   "TARGET_64BIT"
7211   "")
7212
7213 (define_insn "*umuldi3_highpart_rex64"
7214   [(set (match_operand:DI 0 "register_operand" "=d")
7215         (truncate:DI
7216           (lshiftrt:TI
7217             (mult:TI (zero_extend:TI
7218                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7219                      (zero_extend:TI
7220                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7221             (const_int 64))))
7222    (clobber (match_scratch:DI 3 "=1"))
7223    (clobber (reg:CC FLAGS_REG))]
7224   "TARGET_64BIT
7225    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7226   "mul{q}\t%2"
7227   [(set_attr "type" "imul")
7228    (set_attr "length_immediate" "0")
7229    (set (attr "athlon_decode")
7230      (if_then_else (eq_attr "cpu" "athlon")
7231         (const_string "vector")
7232         (const_string "double")))
7233    (set_attr "mode" "DI")])
7234
7235 (define_expand "umulsi3_highpart"
7236   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7237                    (truncate:SI
7238                      (lshiftrt:DI
7239                        (mult:DI (zero_extend:DI
7240                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7241                                 (zero_extend:DI
7242                                   (match_operand:SI 2 "register_operand" "")))
7243                        (const_int 32))))
7244               (clobber (match_scratch:SI 3 ""))
7245               (clobber (reg:CC FLAGS_REG))])]
7246   ""
7247   "")
7248
7249 (define_insn "*umulsi3_highpart_insn"
7250   [(set (match_operand:SI 0 "register_operand" "=d")
7251         (truncate:SI
7252           (lshiftrt:DI
7253             (mult:DI (zero_extend:DI
7254                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7255                      (zero_extend:DI
7256                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7257             (const_int 32))))
7258    (clobber (match_scratch:SI 3 "=1"))
7259    (clobber (reg:CC FLAGS_REG))]
7260   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7261   "mul{l}\t%2"
7262   [(set_attr "type" "imul")
7263    (set_attr "length_immediate" "0")
7264    (set (attr "athlon_decode")
7265      (if_then_else (eq_attr "cpu" "athlon")
7266         (const_string "vector")
7267         (const_string "double")))
7268    (set_attr "mode" "SI")])
7269
7270 (define_insn "*umulsi3_highpart_zext"
7271   [(set (match_operand:DI 0 "register_operand" "=d")
7272         (zero_extend:DI (truncate:SI
7273           (lshiftrt:DI
7274             (mult:DI (zero_extend:DI
7275                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7276                      (zero_extend:DI
7277                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7278             (const_int 32)))))
7279    (clobber (match_scratch:SI 3 "=1"))
7280    (clobber (reg:CC FLAGS_REG))]
7281   "TARGET_64BIT
7282    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7283   "mul{l}\t%2"
7284   [(set_attr "type" "imul")
7285    (set_attr "length_immediate" "0")
7286    (set (attr "athlon_decode")
7287      (if_then_else (eq_attr "cpu" "athlon")
7288         (const_string "vector")
7289         (const_string "double")))
7290    (set_attr "mode" "SI")])
7291
7292 (define_expand "smuldi3_highpart"
7293   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7294                    (truncate:DI
7295                      (lshiftrt:TI
7296                        (mult:TI (sign_extend:TI
7297                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7298                                 (sign_extend:TI
7299                                   (match_operand:DI 2 "register_operand" "")))
7300                        (const_int 64))))
7301               (clobber (match_scratch:DI 3 ""))
7302               (clobber (reg:CC FLAGS_REG))])]
7303   "TARGET_64BIT"
7304   "")
7305
7306 (define_insn "*smuldi3_highpart_rex64"
7307   [(set (match_operand:DI 0 "register_operand" "=d")
7308         (truncate:DI
7309           (lshiftrt:TI
7310             (mult:TI (sign_extend:TI
7311                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7312                      (sign_extend:TI
7313                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7314             (const_int 64))))
7315    (clobber (match_scratch:DI 3 "=1"))
7316    (clobber (reg:CC FLAGS_REG))]
7317   "TARGET_64BIT
7318    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7319   "imul{q}\t%2"
7320   [(set_attr "type" "imul")
7321    (set (attr "athlon_decode")
7322      (if_then_else (eq_attr "cpu" "athlon")
7323         (const_string "vector")
7324         (const_string "double")))
7325    (set_attr "mode" "DI")])
7326
7327 (define_expand "smulsi3_highpart"
7328   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7329                    (truncate:SI
7330                      (lshiftrt:DI
7331                        (mult:DI (sign_extend:DI
7332                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7333                                 (sign_extend:DI
7334                                   (match_operand:SI 2 "register_operand" "")))
7335                        (const_int 32))))
7336               (clobber (match_scratch:SI 3 ""))
7337               (clobber (reg:CC FLAGS_REG))])]
7338   ""
7339   "")
7340
7341 (define_insn "*smulsi3_highpart_insn"
7342   [(set (match_operand:SI 0 "register_operand" "=d")
7343         (truncate:SI
7344           (lshiftrt:DI
7345             (mult:DI (sign_extend:DI
7346                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7347                      (sign_extend:DI
7348                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7349             (const_int 32))))
7350    (clobber (match_scratch:SI 3 "=1"))
7351    (clobber (reg:CC FLAGS_REG))]
7352   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7353   "imul{l}\t%2"
7354   [(set_attr "type" "imul")
7355    (set (attr "athlon_decode")
7356      (if_then_else (eq_attr "cpu" "athlon")
7357         (const_string "vector")
7358         (const_string "double")))
7359    (set_attr "mode" "SI")])
7360
7361 (define_insn "*smulsi3_highpart_zext"
7362   [(set (match_operand:DI 0 "register_operand" "=d")
7363         (zero_extend:DI (truncate:SI
7364           (lshiftrt:DI
7365             (mult:DI (sign_extend:DI
7366                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7367                      (sign_extend:DI
7368                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7369             (const_int 32)))))
7370    (clobber (match_scratch:SI 3 "=1"))
7371    (clobber (reg:CC FLAGS_REG))]
7372   "TARGET_64BIT
7373    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7374   "imul{l}\t%2"
7375   [(set_attr "type" "imul")
7376    (set (attr "athlon_decode")
7377      (if_then_else (eq_attr "cpu" "athlon")
7378         (const_string "vector")
7379         (const_string "double")))
7380    (set_attr "mode" "SI")])
7381
7382 ;; The patterns that match these are at the end of this file.
7383
7384 (define_expand "mulxf3"
7385   [(set (match_operand:XF 0 "register_operand" "")
7386         (mult:XF (match_operand:XF 1 "register_operand" "")
7387                  (match_operand:XF 2 "register_operand" "")))]
7388   "TARGET_80387"
7389   "")
7390
7391 (define_expand "muldf3"
7392   [(set (match_operand:DF 0 "register_operand" "")
7393         (mult:DF (match_operand:DF 1 "register_operand" "")
7394                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7395   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7396   "")
7397
7398 (define_expand "mulsf3"
7399   [(set (match_operand:SF 0 "register_operand" "")
7400         (mult:SF (match_operand:SF 1 "register_operand" "")
7401                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7402   "TARGET_80387 || TARGET_SSE_MATH"
7403   "")
7404 \f
7405 ;; Divide instructions
7406
7407 (define_insn "divqi3"
7408   [(set (match_operand:QI 0 "register_operand" "=a")
7409         (div:QI (match_operand:HI 1 "register_operand" "0")
7410                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7411    (clobber (reg:CC FLAGS_REG))]
7412   "TARGET_QIMODE_MATH"
7413   "idiv{b}\t%2"
7414   [(set_attr "type" "idiv")
7415    (set_attr "mode" "QI")])
7416
7417 (define_insn "udivqi3"
7418   [(set (match_operand:QI 0 "register_operand" "=a")
7419         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7420                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7421    (clobber (reg:CC FLAGS_REG))]
7422   "TARGET_QIMODE_MATH"
7423   "div{b}\t%2"
7424   [(set_attr "type" "idiv")
7425    (set_attr "mode" "QI")])
7426
7427 ;; The patterns that match these are at the end of this file.
7428
7429 (define_expand "divxf3"
7430   [(set (match_operand:XF 0 "register_operand" "")
7431         (div:XF (match_operand:XF 1 "register_operand" "")
7432                 (match_operand:XF 2 "register_operand" "")))]
7433   "TARGET_80387"
7434   "")
7435
7436 (define_expand "divdf3"
7437   [(set (match_operand:DF 0 "register_operand" "")
7438         (div:DF (match_operand:DF 1 "register_operand" "")
7439                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7440    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7441    "")
7442
7443 (define_expand "divsf3"
7444   [(set (match_operand:SF 0 "register_operand" "")
7445         (div:SF (match_operand:SF 1 "register_operand" "")
7446                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7447   "TARGET_80387 || TARGET_SSE_MATH"
7448   "")
7449 \f
7450 ;; Remainder instructions.
7451
7452 (define_expand "divmoddi4"
7453   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7454                    (div:DI (match_operand:DI 1 "register_operand" "")
7455                            (match_operand:DI 2 "nonimmediate_operand" "")))
7456               (set (match_operand:DI 3 "register_operand" "")
7457                    (mod:DI (match_dup 1) (match_dup 2)))
7458               (clobber (reg:CC FLAGS_REG))])]
7459   "TARGET_64BIT"
7460   "")
7461
7462 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7463 ;; Penalize eax case slightly because it results in worse scheduling
7464 ;; of code.
7465 (define_insn "*divmoddi4_nocltd_rex64"
7466   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7467         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7468                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7469    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7470         (mod:DI (match_dup 2) (match_dup 3)))
7471    (clobber (reg:CC FLAGS_REG))]
7472   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7473   "#"
7474   [(set_attr "type" "multi")])
7475
7476 (define_insn "*divmoddi4_cltd_rex64"
7477   [(set (match_operand:DI 0 "register_operand" "=a")
7478         (div:DI (match_operand:DI 2 "register_operand" "a")
7479                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7480    (set (match_operand:DI 1 "register_operand" "=&d")
7481         (mod:DI (match_dup 2) (match_dup 3)))
7482    (clobber (reg:CC FLAGS_REG))]
7483   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7484   "#"
7485   [(set_attr "type" "multi")])
7486
7487 (define_insn "*divmoddi_noext_rex64"
7488   [(set (match_operand:DI 0 "register_operand" "=a")
7489         (div:DI (match_operand:DI 1 "register_operand" "0")
7490                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7491    (set (match_operand:DI 3 "register_operand" "=d")
7492         (mod:DI (match_dup 1) (match_dup 2)))
7493    (use (match_operand:DI 4 "register_operand" "3"))
7494    (clobber (reg:CC FLAGS_REG))]
7495   "TARGET_64BIT"
7496   "idiv{q}\t%2"
7497   [(set_attr "type" "idiv")
7498    (set_attr "mode" "DI")])
7499
7500 (define_split
7501   [(set (match_operand:DI 0 "register_operand" "")
7502         (div:DI (match_operand:DI 1 "register_operand" "")
7503                 (match_operand:DI 2 "nonimmediate_operand" "")))
7504    (set (match_operand:DI 3 "register_operand" "")
7505         (mod:DI (match_dup 1) (match_dup 2)))
7506    (clobber (reg:CC FLAGS_REG))]
7507   "TARGET_64BIT && reload_completed"
7508   [(parallel [(set (match_dup 3)
7509                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7510               (clobber (reg:CC FLAGS_REG))])
7511    (parallel [(set (match_dup 0)
7512                    (div:DI (reg:DI 0) (match_dup 2)))
7513               (set (match_dup 3)
7514                    (mod:DI (reg:DI 0) (match_dup 2)))
7515               (use (match_dup 3))
7516               (clobber (reg:CC FLAGS_REG))])]
7517 {
7518   /* Avoid use of cltd in favor of a mov+shift.  */
7519   if (!TARGET_USE_CLTD && !optimize_size)
7520     {
7521       if (true_regnum (operands[1]))
7522         emit_move_insn (operands[0], operands[1]);
7523       else
7524         emit_move_insn (operands[3], operands[1]);
7525       operands[4] = operands[3];
7526     }
7527   else
7528     {
7529       gcc_assert (!true_regnum (operands[1]));
7530       operands[4] = operands[1];
7531     }
7532 })
7533
7534
7535 (define_expand "divmodsi4"
7536   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7537                    (div:SI (match_operand:SI 1 "register_operand" "")
7538                            (match_operand:SI 2 "nonimmediate_operand" "")))
7539               (set (match_operand:SI 3 "register_operand" "")
7540                    (mod:SI (match_dup 1) (match_dup 2)))
7541               (clobber (reg:CC FLAGS_REG))])]
7542   ""
7543   "")
7544
7545 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7546 ;; Penalize eax case slightly because it results in worse scheduling
7547 ;; of code.
7548 (define_insn "*divmodsi4_nocltd"
7549   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7550         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7551                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7552    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7553         (mod:SI (match_dup 2) (match_dup 3)))
7554    (clobber (reg:CC FLAGS_REG))]
7555   "!optimize_size && !TARGET_USE_CLTD"
7556   "#"
7557   [(set_attr "type" "multi")])
7558
7559 (define_insn "*divmodsi4_cltd"
7560   [(set (match_operand:SI 0 "register_operand" "=a")
7561         (div:SI (match_operand:SI 2 "register_operand" "a")
7562                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7563    (set (match_operand:SI 1 "register_operand" "=&d")
7564         (mod:SI (match_dup 2) (match_dup 3)))
7565    (clobber (reg:CC FLAGS_REG))]
7566   "optimize_size || TARGET_USE_CLTD"
7567   "#"
7568   [(set_attr "type" "multi")])
7569
7570 (define_insn "*divmodsi_noext"
7571   [(set (match_operand:SI 0 "register_operand" "=a")
7572         (div:SI (match_operand:SI 1 "register_operand" "0")
7573                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7574    (set (match_operand:SI 3 "register_operand" "=d")
7575         (mod:SI (match_dup 1) (match_dup 2)))
7576    (use (match_operand:SI 4 "register_operand" "3"))
7577    (clobber (reg:CC FLAGS_REG))]
7578   ""
7579   "idiv{l}\t%2"
7580   [(set_attr "type" "idiv")
7581    (set_attr "mode" "SI")])
7582
7583 (define_split
7584   [(set (match_operand:SI 0 "register_operand" "")
7585         (div:SI (match_operand:SI 1 "register_operand" "")
7586                 (match_operand:SI 2 "nonimmediate_operand" "")))
7587    (set (match_operand:SI 3 "register_operand" "")
7588         (mod:SI (match_dup 1) (match_dup 2)))
7589    (clobber (reg:CC FLAGS_REG))]
7590   "reload_completed"
7591   [(parallel [(set (match_dup 3)
7592                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7593               (clobber (reg:CC FLAGS_REG))])
7594    (parallel [(set (match_dup 0)
7595                    (div:SI (reg:SI 0) (match_dup 2)))
7596               (set (match_dup 3)
7597                    (mod:SI (reg:SI 0) (match_dup 2)))
7598               (use (match_dup 3))
7599               (clobber (reg:CC FLAGS_REG))])]
7600 {
7601   /* Avoid use of cltd in favor of a mov+shift.  */
7602   if (!TARGET_USE_CLTD && !optimize_size)
7603     {
7604       if (true_regnum (operands[1]))
7605         emit_move_insn (operands[0], operands[1]);
7606       else
7607         emit_move_insn (operands[3], operands[1]);
7608       operands[4] = operands[3];
7609     }
7610   else
7611     {
7612       gcc_assert (!true_regnum (operands[1]));
7613       operands[4] = operands[1];
7614     }
7615 })
7616 ;; %%% Split me.
7617 (define_insn "divmodhi4"
7618   [(set (match_operand:HI 0 "register_operand" "=a")
7619         (div:HI (match_operand:HI 1 "register_operand" "0")
7620                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7621    (set (match_operand:HI 3 "register_operand" "=&d")
7622         (mod:HI (match_dup 1) (match_dup 2)))
7623    (clobber (reg:CC FLAGS_REG))]
7624   "TARGET_HIMODE_MATH"
7625   "cwtd\;idiv{w}\t%2"
7626   [(set_attr "type" "multi")
7627    (set_attr "length_immediate" "0")
7628    (set_attr "mode" "SI")])
7629
7630 (define_insn "udivmoddi4"
7631   [(set (match_operand:DI 0 "register_operand" "=a")
7632         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7633                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7634    (set (match_operand:DI 3 "register_operand" "=&d")
7635         (umod:DI (match_dup 1) (match_dup 2)))
7636    (clobber (reg:CC FLAGS_REG))]
7637   "TARGET_64BIT"
7638   "xor{q}\t%3, %3\;div{q}\t%2"
7639   [(set_attr "type" "multi")
7640    (set_attr "length_immediate" "0")
7641    (set_attr "mode" "DI")])
7642
7643 (define_insn "*udivmoddi4_noext"
7644   [(set (match_operand:DI 0 "register_operand" "=a")
7645         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7646                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7647    (set (match_operand:DI 3 "register_operand" "=d")
7648         (umod:DI (match_dup 1) (match_dup 2)))
7649    (use (match_dup 3))
7650    (clobber (reg:CC FLAGS_REG))]
7651   "TARGET_64BIT"
7652   "div{q}\t%2"
7653   [(set_attr "type" "idiv")
7654    (set_attr "mode" "DI")])
7655
7656 (define_split
7657   [(set (match_operand:DI 0 "register_operand" "")
7658         (udiv:DI (match_operand:DI 1 "register_operand" "")
7659                  (match_operand:DI 2 "nonimmediate_operand" "")))
7660    (set (match_operand:DI 3 "register_operand" "")
7661         (umod:DI (match_dup 1) (match_dup 2)))
7662    (clobber (reg:CC FLAGS_REG))]
7663   "TARGET_64BIT && reload_completed"
7664   [(set (match_dup 3) (const_int 0))
7665    (parallel [(set (match_dup 0)
7666                    (udiv:DI (match_dup 1) (match_dup 2)))
7667               (set (match_dup 3)
7668                    (umod:DI (match_dup 1) (match_dup 2)))
7669               (use (match_dup 3))
7670               (clobber (reg:CC FLAGS_REG))])]
7671   "")
7672
7673 (define_insn "udivmodsi4"
7674   [(set (match_operand:SI 0 "register_operand" "=a")
7675         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7676                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7677    (set (match_operand:SI 3 "register_operand" "=&d")
7678         (umod:SI (match_dup 1) (match_dup 2)))
7679    (clobber (reg:CC FLAGS_REG))]
7680   ""
7681   "xor{l}\t%3, %3\;div{l}\t%2"
7682   [(set_attr "type" "multi")
7683    (set_attr "length_immediate" "0")
7684    (set_attr "mode" "SI")])
7685
7686 (define_insn "*udivmodsi4_noext"
7687   [(set (match_operand:SI 0 "register_operand" "=a")
7688         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7689                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7690    (set (match_operand:SI 3 "register_operand" "=d")
7691         (umod:SI (match_dup 1) (match_dup 2)))
7692    (use (match_dup 3))
7693    (clobber (reg:CC FLAGS_REG))]
7694   ""
7695   "div{l}\t%2"
7696   [(set_attr "type" "idiv")
7697    (set_attr "mode" "SI")])
7698
7699 (define_split
7700   [(set (match_operand:SI 0 "register_operand" "")
7701         (udiv:SI (match_operand:SI 1 "register_operand" "")
7702                  (match_operand:SI 2 "nonimmediate_operand" "")))
7703    (set (match_operand:SI 3 "register_operand" "")
7704         (umod:SI (match_dup 1) (match_dup 2)))
7705    (clobber (reg:CC FLAGS_REG))]
7706   "reload_completed"
7707   [(set (match_dup 3) (const_int 0))
7708    (parallel [(set (match_dup 0)
7709                    (udiv:SI (match_dup 1) (match_dup 2)))
7710               (set (match_dup 3)
7711                    (umod:SI (match_dup 1) (match_dup 2)))
7712               (use (match_dup 3))
7713               (clobber (reg:CC FLAGS_REG))])]
7714   "")
7715
7716 (define_expand "udivmodhi4"
7717   [(set (match_dup 4) (const_int 0))
7718    (parallel [(set (match_operand:HI 0 "register_operand" "")
7719                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7720                             (match_operand:HI 2 "nonimmediate_operand" "")))
7721               (set (match_operand:HI 3 "register_operand" "")
7722                    (umod:HI (match_dup 1) (match_dup 2)))
7723               (use (match_dup 4))
7724               (clobber (reg:CC FLAGS_REG))])]
7725   "TARGET_HIMODE_MATH"
7726   "operands[4] = gen_reg_rtx (HImode);")
7727
7728 (define_insn "*udivmodhi_noext"
7729   [(set (match_operand:HI 0 "register_operand" "=a")
7730         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7731                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7732    (set (match_operand:HI 3 "register_operand" "=d")
7733         (umod:HI (match_dup 1) (match_dup 2)))
7734    (use (match_operand:HI 4 "register_operand" "3"))
7735    (clobber (reg:CC FLAGS_REG))]
7736   ""
7737   "div{w}\t%2"
7738   [(set_attr "type" "idiv")
7739    (set_attr "mode" "HI")])
7740
7741 ;; We cannot use div/idiv for double division, because it causes
7742 ;; "division by zero" on the overflow and that's not what we expect
7743 ;; from truncate.  Because true (non truncating) double division is
7744 ;; never generated, we can't create this insn anyway.
7745 ;
7746 ;(define_insn ""
7747 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7748 ;       (truncate:SI
7749 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7750 ;                  (zero_extend:DI
7751 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7752 ;   (set (match_operand:SI 3 "register_operand" "=d")
7753 ;       (truncate:SI
7754 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7755 ;   (clobber (reg:CC FLAGS_REG))]
7756 ;  ""
7757 ;  "div{l}\t{%2, %0|%0, %2}"
7758 ;  [(set_attr "type" "idiv")])
7759 \f
7760 ;;- Logical AND instructions
7761
7762 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7763 ;; Note that this excludes ah.
7764
7765 (define_insn "*testdi_1_rex64"
7766   [(set (reg FLAGS_REG)
7767         (compare
7768           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7769                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7770           (const_int 0)))]
7771   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7772    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7773   "@
7774    test{l}\t{%k1, %k0|%k0, %k1}
7775    test{l}\t{%k1, %k0|%k0, %k1}
7776    test{q}\t{%1, %0|%0, %1}
7777    test{q}\t{%1, %0|%0, %1}
7778    test{q}\t{%1, %0|%0, %1}"
7779   [(set_attr "type" "test")
7780    (set_attr "modrm" "0,1,0,1,1")
7781    (set_attr "mode" "SI,SI,DI,DI,DI")
7782    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7783
7784 (define_insn "testsi_1"
7785   [(set (reg FLAGS_REG)
7786         (compare
7787           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7788                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7789           (const_int 0)))]
7790   "ix86_match_ccmode (insn, CCNOmode)
7791    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7792   "test{l}\t{%1, %0|%0, %1}"
7793   [(set_attr "type" "test")
7794    (set_attr "modrm" "0,1,1")
7795    (set_attr "mode" "SI")
7796    (set_attr "pent_pair" "uv,np,uv")])
7797
7798 (define_expand "testsi_ccno_1"
7799   [(set (reg:CCNO FLAGS_REG)
7800         (compare:CCNO
7801           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7802                   (match_operand:SI 1 "nonmemory_operand" ""))
7803           (const_int 0)))]
7804   ""
7805   "")
7806
7807 (define_insn "*testhi_1"
7808   [(set (reg FLAGS_REG)
7809         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7810                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7811                  (const_int 0)))]
7812   "ix86_match_ccmode (insn, CCNOmode)
7813    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7814   "test{w}\t{%1, %0|%0, %1}"
7815   [(set_attr "type" "test")
7816    (set_attr "modrm" "0,1,1")
7817    (set_attr "mode" "HI")
7818    (set_attr "pent_pair" "uv,np,uv")])
7819
7820 (define_expand "testqi_ccz_1"
7821   [(set (reg:CCZ FLAGS_REG)
7822         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7823                              (match_operand:QI 1 "nonmemory_operand" ""))
7824                  (const_int 0)))]
7825   ""
7826   "")
7827
7828 (define_insn "*testqi_1_maybe_si"
7829   [(set (reg FLAGS_REG)
7830         (compare
7831           (and:QI
7832             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7833             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7834           (const_int 0)))]
7835    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7836     && ix86_match_ccmode (insn,
7837                          CONST_INT_P (operands[1])
7838                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7839 {
7840   if (which_alternative == 3)
7841     {
7842       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7843         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7844       return "test{l}\t{%1, %k0|%k0, %1}";
7845     }
7846   return "test{b}\t{%1, %0|%0, %1}";
7847 }
7848   [(set_attr "type" "test")
7849    (set_attr "modrm" "0,1,1,1")
7850    (set_attr "mode" "QI,QI,QI,SI")
7851    (set_attr "pent_pair" "uv,np,uv,np")])
7852
7853 (define_insn "*testqi_1"
7854   [(set (reg FLAGS_REG)
7855         (compare
7856           (and:QI
7857             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7858             (match_operand:QI 1 "general_operand" "n,n,qn"))
7859           (const_int 0)))]
7860   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7861    && ix86_match_ccmode (insn, CCNOmode)"
7862   "test{b}\t{%1, %0|%0, %1}"
7863   [(set_attr "type" "test")
7864    (set_attr "modrm" "0,1,1")
7865    (set_attr "mode" "QI")
7866    (set_attr "pent_pair" "uv,np,uv")])
7867
7868 (define_expand "testqi_ext_ccno_0"
7869   [(set (reg:CCNO FLAGS_REG)
7870         (compare:CCNO
7871           (and:SI
7872             (zero_extract:SI
7873               (match_operand 0 "ext_register_operand" "")
7874               (const_int 8)
7875               (const_int 8))
7876             (match_operand 1 "const_int_operand" ""))
7877           (const_int 0)))]
7878   ""
7879   "")
7880
7881 (define_insn "*testqi_ext_0"
7882   [(set (reg FLAGS_REG)
7883         (compare
7884           (and:SI
7885             (zero_extract:SI
7886               (match_operand 0 "ext_register_operand" "Q")
7887               (const_int 8)
7888               (const_int 8))
7889             (match_operand 1 "const_int_operand" "n"))
7890           (const_int 0)))]
7891   "ix86_match_ccmode (insn, CCNOmode)"
7892   "test{b}\t{%1, %h0|%h0, %1}"
7893   [(set_attr "type" "test")
7894    (set_attr "mode" "QI")
7895    (set_attr "length_immediate" "1")
7896    (set_attr "pent_pair" "np")])
7897
7898 (define_insn "*testqi_ext_1"
7899   [(set (reg FLAGS_REG)
7900         (compare
7901           (and:SI
7902             (zero_extract:SI
7903               (match_operand 0 "ext_register_operand" "Q")
7904               (const_int 8)
7905               (const_int 8))
7906             (zero_extend:SI
7907               (match_operand:QI 1 "general_operand" "Qm")))
7908           (const_int 0)))]
7909   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7910    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7911   "test{b}\t{%1, %h0|%h0, %1}"
7912   [(set_attr "type" "test")
7913    (set_attr "mode" "QI")])
7914
7915 (define_insn "*testqi_ext_1_rex64"
7916   [(set (reg FLAGS_REG)
7917         (compare
7918           (and:SI
7919             (zero_extract:SI
7920               (match_operand 0 "ext_register_operand" "Q")
7921               (const_int 8)
7922               (const_int 8))
7923             (zero_extend:SI
7924               (match_operand:QI 1 "register_operand" "Q")))
7925           (const_int 0)))]
7926   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7927   "test{b}\t{%1, %h0|%h0, %1}"
7928   [(set_attr "type" "test")
7929    (set_attr "mode" "QI")])
7930
7931 (define_insn "*testqi_ext_2"
7932   [(set (reg FLAGS_REG)
7933         (compare
7934           (and:SI
7935             (zero_extract:SI
7936               (match_operand 0 "ext_register_operand" "Q")
7937               (const_int 8)
7938               (const_int 8))
7939             (zero_extract:SI
7940               (match_operand 1 "ext_register_operand" "Q")
7941               (const_int 8)
7942               (const_int 8)))
7943           (const_int 0)))]
7944   "ix86_match_ccmode (insn, CCNOmode)"
7945   "test{b}\t{%h1, %h0|%h0, %h1}"
7946   [(set_attr "type" "test")
7947    (set_attr "mode" "QI")])
7948
7949 ;; Combine likes to form bit extractions for some tests.  Humor it.
7950 (define_insn "*testqi_ext_3"
7951   [(set (reg FLAGS_REG)
7952         (compare (zero_extract:SI
7953                    (match_operand 0 "nonimmediate_operand" "rm")
7954                    (match_operand:SI 1 "const_int_operand" "")
7955                    (match_operand:SI 2 "const_int_operand" ""))
7956                  (const_int 0)))]
7957   "ix86_match_ccmode (insn, CCNOmode)
7958    && INTVAL (operands[1]) > 0
7959    && INTVAL (operands[2]) >= 0
7960    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7961    && (GET_MODE (operands[0]) == SImode
7962        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7963        || GET_MODE (operands[0]) == HImode
7964        || GET_MODE (operands[0]) == QImode)"
7965   "#")
7966
7967 (define_insn "*testqi_ext_3_rex64"
7968   [(set (reg FLAGS_REG)
7969         (compare (zero_extract:DI
7970                    (match_operand 0 "nonimmediate_operand" "rm")
7971                    (match_operand:DI 1 "const_int_operand" "")
7972                    (match_operand:DI 2 "const_int_operand" ""))
7973                  (const_int 0)))]
7974   "TARGET_64BIT
7975    && ix86_match_ccmode (insn, CCNOmode)
7976    && INTVAL (operands[1]) > 0
7977    && INTVAL (operands[2]) >= 0
7978    /* Ensure that resulting mask is zero or sign extended operand.  */
7979    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7980        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7981            && INTVAL (operands[1]) > 32))
7982    && (GET_MODE (operands[0]) == SImode
7983        || GET_MODE (operands[0]) == DImode
7984        || GET_MODE (operands[0]) == HImode
7985        || GET_MODE (operands[0]) == QImode)"
7986   "#")
7987
7988 (define_split
7989   [(set (match_operand 0 "flags_reg_operand" "")
7990         (match_operator 1 "compare_operator"
7991           [(zero_extract
7992              (match_operand 2 "nonimmediate_operand" "")
7993              (match_operand 3 "const_int_operand" "")
7994              (match_operand 4 "const_int_operand" ""))
7995            (const_int 0)]))]
7996   "ix86_match_ccmode (insn, CCNOmode)"
7997   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7998 {
7999   rtx val = operands[2];
8000   HOST_WIDE_INT len = INTVAL (operands[3]);
8001   HOST_WIDE_INT pos = INTVAL (operands[4]);
8002   HOST_WIDE_INT mask;
8003   enum machine_mode mode, submode;
8004
8005   mode = GET_MODE (val);
8006   if (MEM_P (val))
8007     {
8008       /* ??? Combine likes to put non-volatile mem extractions in QImode
8009          no matter the size of the test.  So find a mode that works.  */
8010       if (! MEM_VOLATILE_P (val))
8011         {
8012           mode = smallest_mode_for_size (pos + len, MODE_INT);
8013           val = adjust_address (val, mode, 0);
8014         }
8015     }
8016   else if (GET_CODE (val) == SUBREG
8017            && (submode = GET_MODE (SUBREG_REG (val)),
8018                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8019            && pos + len <= GET_MODE_BITSIZE (submode))
8020     {
8021       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8022       mode = submode;
8023       val = SUBREG_REG (val);
8024     }
8025   else if (mode == HImode && pos + len <= 8)
8026     {
8027       /* Small HImode tests can be converted to QImode.  */
8028       mode = QImode;
8029       val = gen_lowpart (QImode, val);
8030     }
8031
8032   if (len == HOST_BITS_PER_WIDE_INT)
8033     mask = -1;
8034   else
8035     mask = ((HOST_WIDE_INT)1 << len) - 1;
8036   mask <<= pos;
8037
8038   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8039 })
8040
8041 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8042 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8043 ;; this is relatively important trick.
8044 ;; Do the conversion only post-reload to avoid limiting of the register class
8045 ;; to QI regs.
8046 (define_split
8047   [(set (match_operand 0 "flags_reg_operand" "")
8048         (match_operator 1 "compare_operator"
8049           [(and (match_operand 2 "register_operand" "")
8050                 (match_operand 3 "const_int_operand" ""))
8051            (const_int 0)]))]
8052    "reload_completed
8053     && QI_REG_P (operands[2])
8054     && GET_MODE (operands[2]) != QImode
8055     && ((ix86_match_ccmode (insn, CCZmode)
8056          && !(INTVAL (operands[3]) & ~(255 << 8)))
8057         || (ix86_match_ccmode (insn, CCNOmode)
8058             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8059   [(set (match_dup 0)
8060         (match_op_dup 1
8061           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8062                    (match_dup 3))
8063            (const_int 0)]))]
8064   "operands[2] = gen_lowpart (SImode, operands[2]);
8065    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8066
8067 (define_split
8068   [(set (match_operand 0 "flags_reg_operand" "")
8069         (match_operator 1 "compare_operator"
8070           [(and (match_operand 2 "nonimmediate_operand" "")
8071                 (match_operand 3 "const_int_operand" ""))
8072            (const_int 0)]))]
8073    "reload_completed
8074     && GET_MODE (operands[2]) != QImode
8075     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8076     && ((ix86_match_ccmode (insn, CCZmode)
8077          && !(INTVAL (operands[3]) & ~255))
8078         || (ix86_match_ccmode (insn, CCNOmode)
8079             && !(INTVAL (operands[3]) & ~127)))"
8080   [(set (match_dup 0)
8081         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8082                          (const_int 0)]))]
8083   "operands[2] = gen_lowpart (QImode, operands[2]);
8084    operands[3] = gen_lowpart (QImode, operands[3]);")
8085
8086
8087 ;; %%% This used to optimize known byte-wide and operations to memory,
8088 ;; and sometimes to QImode registers.  If this is considered useful,
8089 ;; it should be done with splitters.
8090
8091 (define_expand "anddi3"
8092   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8093         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8094                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8095    (clobber (reg:CC FLAGS_REG))]
8096   "TARGET_64BIT"
8097   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8098
8099 (define_insn "*anddi_1_rex64"
8100   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8101         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8102                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8103    (clobber (reg:CC FLAGS_REG))]
8104   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8105 {
8106   switch (get_attr_type (insn))
8107     {
8108     case TYPE_IMOVX:
8109       {
8110         enum machine_mode mode;
8111
8112         gcc_assert (CONST_INT_P (operands[2]));
8113         if (INTVAL (operands[2]) == 0xff)
8114           mode = QImode;
8115         else
8116           {
8117             gcc_assert (INTVAL (operands[2]) == 0xffff);
8118             mode = HImode;
8119           }
8120
8121         operands[1] = gen_lowpart (mode, operands[1]);
8122         if (mode == QImode)
8123           return "movz{bq|x}\t{%1,%0|%0, %1}";
8124         else
8125           return "movz{wq|x}\t{%1,%0|%0, %1}";
8126       }
8127
8128     default:
8129       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8130       if (get_attr_mode (insn) == MODE_SI)
8131         return "and{l}\t{%k2, %k0|%k0, %k2}";
8132       else
8133         return "and{q}\t{%2, %0|%0, %2}";
8134     }
8135 }
8136   [(set_attr "type" "alu,alu,alu,imovx")
8137    (set_attr "length_immediate" "*,*,*,0")
8138    (set_attr "mode" "SI,DI,DI,DI")])
8139
8140 (define_insn "*anddi_2"
8141   [(set (reg FLAGS_REG)
8142         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8143                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8144                  (const_int 0)))
8145    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8146         (and:DI (match_dup 1) (match_dup 2)))]
8147   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8148    && ix86_binary_operator_ok (AND, DImode, operands)"
8149   "@
8150    and{l}\t{%k2, %k0|%k0, %k2}
8151    and{q}\t{%2, %0|%0, %2}
8152    and{q}\t{%2, %0|%0, %2}"
8153   [(set_attr "type" "alu")
8154    (set_attr "mode" "SI,DI,DI")])
8155
8156 (define_expand "andsi3"
8157   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8158         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8159                 (match_operand:SI 2 "general_operand" "")))
8160    (clobber (reg:CC FLAGS_REG))]
8161   ""
8162   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8163
8164 (define_insn "*andsi_1"
8165   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8166         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8167                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8168    (clobber (reg:CC FLAGS_REG))]
8169   "ix86_binary_operator_ok (AND, SImode, operands)"
8170 {
8171   switch (get_attr_type (insn))
8172     {
8173     case TYPE_IMOVX:
8174       {
8175         enum machine_mode mode;
8176
8177         gcc_assert (CONST_INT_P (operands[2]));
8178         if (INTVAL (operands[2]) == 0xff)
8179           mode = QImode;
8180         else
8181           {
8182             gcc_assert (INTVAL (operands[2]) == 0xffff);
8183             mode = HImode;
8184           }
8185
8186         operands[1] = gen_lowpart (mode, operands[1]);
8187         if (mode == QImode)
8188           return "movz{bl|x}\t{%1,%0|%0, %1}";
8189         else
8190           return "movz{wl|x}\t{%1,%0|%0, %1}";
8191       }
8192
8193     default:
8194       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8195       return "and{l}\t{%2, %0|%0, %2}";
8196     }
8197 }
8198   [(set_attr "type" "alu,alu,imovx")
8199    (set_attr "length_immediate" "*,*,0")
8200    (set_attr "mode" "SI")])
8201
8202 (define_split
8203   [(set (match_operand 0 "register_operand" "")
8204         (and (match_dup 0)
8205              (const_int -65536)))
8206    (clobber (reg:CC FLAGS_REG))]
8207   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8208   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8209   "operands[1] = gen_lowpart (HImode, operands[0]);")
8210
8211 (define_split
8212   [(set (match_operand 0 "ext_register_operand" "")
8213         (and (match_dup 0)
8214              (const_int -256)))
8215    (clobber (reg:CC FLAGS_REG))]
8216   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8217   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8218   "operands[1] = gen_lowpart (QImode, operands[0]);")
8219
8220 (define_split
8221   [(set (match_operand 0 "ext_register_operand" "")
8222         (and (match_dup 0)
8223              (const_int -65281)))
8224    (clobber (reg:CC FLAGS_REG))]
8225   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8226   [(parallel [(set (zero_extract:SI (match_dup 0)
8227                                     (const_int 8)
8228                                     (const_int 8))
8229                    (xor:SI
8230                      (zero_extract:SI (match_dup 0)
8231                                       (const_int 8)
8232                                       (const_int 8))
8233                      (zero_extract:SI (match_dup 0)
8234                                       (const_int 8)
8235                                       (const_int 8))))
8236               (clobber (reg:CC FLAGS_REG))])]
8237   "operands[0] = gen_lowpart (SImode, operands[0]);")
8238
8239 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8240 (define_insn "*andsi_1_zext"
8241   [(set (match_operand:DI 0 "register_operand" "=r")
8242         (zero_extend:DI
8243           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8244                   (match_operand:SI 2 "general_operand" "rim"))))
8245    (clobber (reg:CC FLAGS_REG))]
8246   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8247   "and{l}\t{%2, %k0|%k0, %2}"
8248   [(set_attr "type" "alu")
8249    (set_attr "mode" "SI")])
8250
8251 (define_insn "*andsi_2"
8252   [(set (reg FLAGS_REG)
8253         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8254                          (match_operand:SI 2 "general_operand" "rim,ri"))
8255                  (const_int 0)))
8256    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8257         (and:SI (match_dup 1) (match_dup 2)))]
8258   "ix86_match_ccmode (insn, CCNOmode)
8259    && ix86_binary_operator_ok (AND, SImode, operands)"
8260   "and{l}\t{%2, %0|%0, %2}"
8261   [(set_attr "type" "alu")
8262    (set_attr "mode" "SI")])
8263
8264 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8265 (define_insn "*andsi_2_zext"
8266   [(set (reg FLAGS_REG)
8267         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8268                          (match_operand:SI 2 "general_operand" "rim"))
8269                  (const_int 0)))
8270    (set (match_operand:DI 0 "register_operand" "=r")
8271         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8272   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8273    && ix86_binary_operator_ok (AND, SImode, operands)"
8274   "and{l}\t{%2, %k0|%k0, %2}"
8275   [(set_attr "type" "alu")
8276    (set_attr "mode" "SI")])
8277
8278 (define_expand "andhi3"
8279   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8280         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8281                 (match_operand:HI 2 "general_operand" "")))
8282    (clobber (reg:CC FLAGS_REG))]
8283   "TARGET_HIMODE_MATH"
8284   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8285
8286 (define_insn "*andhi_1"
8287   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8288         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8289                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8290    (clobber (reg:CC FLAGS_REG))]
8291   "ix86_binary_operator_ok (AND, HImode, operands)"
8292 {
8293   switch (get_attr_type (insn))
8294     {
8295     case TYPE_IMOVX:
8296       gcc_assert (CONST_INT_P (operands[2]));
8297       gcc_assert (INTVAL (operands[2]) == 0xff);
8298       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8299
8300     default:
8301       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8302
8303       return "and{w}\t{%2, %0|%0, %2}";
8304     }
8305 }
8306   [(set_attr "type" "alu,alu,imovx")
8307    (set_attr "length_immediate" "*,*,0")
8308    (set_attr "mode" "HI,HI,SI")])
8309
8310 (define_insn "*andhi_2"
8311   [(set (reg FLAGS_REG)
8312         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8313                          (match_operand:HI 2 "general_operand" "rim,ri"))
8314                  (const_int 0)))
8315    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8316         (and:HI (match_dup 1) (match_dup 2)))]
8317   "ix86_match_ccmode (insn, CCNOmode)
8318    && ix86_binary_operator_ok (AND, HImode, operands)"
8319   "and{w}\t{%2, %0|%0, %2}"
8320   [(set_attr "type" "alu")
8321    (set_attr "mode" "HI")])
8322
8323 (define_expand "andqi3"
8324   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8325         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8326                 (match_operand:QI 2 "general_operand" "")))
8327    (clobber (reg:CC FLAGS_REG))]
8328   "TARGET_QIMODE_MATH"
8329   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8330
8331 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8332 (define_insn "*andqi_1"
8333   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8334         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8335                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8336    (clobber (reg:CC FLAGS_REG))]
8337   "ix86_binary_operator_ok (AND, QImode, operands)"
8338   "@
8339    and{b}\t{%2, %0|%0, %2}
8340    and{b}\t{%2, %0|%0, %2}
8341    and{l}\t{%k2, %k0|%k0, %k2}"
8342   [(set_attr "type" "alu")
8343    (set_attr "mode" "QI,QI,SI")])
8344
8345 (define_insn "*andqi_1_slp"
8346   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8347         (and:QI (match_dup 0)
8348                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8349    (clobber (reg:CC FLAGS_REG))]
8350   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8351    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8352   "and{b}\t{%1, %0|%0, %1}"
8353   [(set_attr "type" "alu1")
8354    (set_attr "mode" "QI")])
8355
8356 (define_insn "*andqi_2_maybe_si"
8357   [(set (reg FLAGS_REG)
8358         (compare (and:QI
8359                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8360                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8361                  (const_int 0)))
8362    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8363         (and:QI (match_dup 1) (match_dup 2)))]
8364   "ix86_binary_operator_ok (AND, QImode, operands)
8365    && ix86_match_ccmode (insn,
8366                          CONST_INT_P (operands[2])
8367                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8368 {
8369   if (which_alternative == 2)
8370     {
8371       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8372         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8373       return "and{l}\t{%2, %k0|%k0, %2}";
8374     }
8375   return "and{b}\t{%2, %0|%0, %2}";
8376 }
8377   [(set_attr "type" "alu")
8378    (set_attr "mode" "QI,QI,SI")])
8379
8380 (define_insn "*andqi_2"
8381   [(set (reg FLAGS_REG)
8382         (compare (and:QI
8383                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8384                    (match_operand:QI 2 "general_operand" "qim,qi"))
8385                  (const_int 0)))
8386    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8387         (and:QI (match_dup 1) (match_dup 2)))]
8388   "ix86_match_ccmode (insn, CCNOmode)
8389    && ix86_binary_operator_ok (AND, QImode, operands)"
8390   "and{b}\t{%2, %0|%0, %2}"
8391   [(set_attr "type" "alu")
8392    (set_attr "mode" "QI")])
8393
8394 (define_insn "*andqi_2_slp"
8395   [(set (reg FLAGS_REG)
8396         (compare (and:QI
8397                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8398                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8399                  (const_int 0)))
8400    (set (strict_low_part (match_dup 0))
8401         (and:QI (match_dup 0) (match_dup 1)))]
8402   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8403    && ix86_match_ccmode (insn, CCNOmode)
8404    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8405   "and{b}\t{%1, %0|%0, %1}"
8406   [(set_attr "type" "alu1")
8407    (set_attr "mode" "QI")])
8408
8409 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8410 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8411 ;; for a QImode operand, which of course failed.
8412
8413 (define_insn "andqi_ext_0"
8414   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8415                          (const_int 8)
8416                          (const_int 8))
8417         (and:SI
8418           (zero_extract:SI
8419             (match_operand 1 "ext_register_operand" "0")
8420             (const_int 8)
8421             (const_int 8))
8422           (match_operand 2 "const_int_operand" "n")))
8423    (clobber (reg:CC FLAGS_REG))]
8424   ""
8425   "and{b}\t{%2, %h0|%h0, %2}"
8426   [(set_attr "type" "alu")
8427    (set_attr "length_immediate" "1")
8428    (set_attr "mode" "QI")])
8429
8430 ;; Generated by peephole translating test to and.  This shows up
8431 ;; often in fp comparisons.
8432
8433 (define_insn "*andqi_ext_0_cc"
8434   [(set (reg FLAGS_REG)
8435         (compare
8436           (and:SI
8437             (zero_extract:SI
8438               (match_operand 1 "ext_register_operand" "0")
8439               (const_int 8)
8440               (const_int 8))
8441             (match_operand 2 "const_int_operand" "n"))
8442           (const_int 0)))
8443    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8444                          (const_int 8)
8445                          (const_int 8))
8446         (and:SI
8447           (zero_extract:SI
8448             (match_dup 1)
8449             (const_int 8)
8450             (const_int 8))
8451           (match_dup 2)))]
8452   "ix86_match_ccmode (insn, CCNOmode)"
8453   "and{b}\t{%2, %h0|%h0, %2}"
8454   [(set_attr "type" "alu")
8455    (set_attr "length_immediate" "1")
8456    (set_attr "mode" "QI")])
8457
8458 (define_insn "*andqi_ext_1"
8459   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8460                          (const_int 8)
8461                          (const_int 8))
8462         (and:SI
8463           (zero_extract:SI
8464             (match_operand 1 "ext_register_operand" "0")
8465             (const_int 8)
8466             (const_int 8))
8467           (zero_extend:SI
8468             (match_operand:QI 2 "general_operand" "Qm"))))
8469    (clobber (reg:CC FLAGS_REG))]
8470   "!TARGET_64BIT"
8471   "and{b}\t{%2, %h0|%h0, %2}"
8472   [(set_attr "type" "alu")
8473    (set_attr "length_immediate" "0")
8474    (set_attr "mode" "QI")])
8475
8476 (define_insn "*andqi_ext_1_rex64"
8477   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8478                          (const_int 8)
8479                          (const_int 8))
8480         (and:SI
8481           (zero_extract:SI
8482             (match_operand 1 "ext_register_operand" "0")
8483             (const_int 8)
8484             (const_int 8))
8485           (zero_extend:SI
8486             (match_operand 2 "ext_register_operand" "Q"))))
8487    (clobber (reg:CC FLAGS_REG))]
8488   "TARGET_64BIT"
8489   "and{b}\t{%2, %h0|%h0, %2}"
8490   [(set_attr "type" "alu")
8491    (set_attr "length_immediate" "0")
8492    (set_attr "mode" "QI")])
8493
8494 (define_insn "*andqi_ext_2"
8495   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8496                          (const_int 8)
8497                          (const_int 8))
8498         (and:SI
8499           (zero_extract:SI
8500             (match_operand 1 "ext_register_operand" "%0")
8501             (const_int 8)
8502             (const_int 8))
8503           (zero_extract:SI
8504             (match_operand 2 "ext_register_operand" "Q")
8505             (const_int 8)
8506             (const_int 8))))
8507    (clobber (reg:CC FLAGS_REG))]
8508   ""
8509   "and{b}\t{%h2, %h0|%h0, %h2}"
8510   [(set_attr "type" "alu")
8511    (set_attr "length_immediate" "0")
8512    (set_attr "mode" "QI")])
8513
8514 ;; Convert wide AND instructions with immediate operand to shorter QImode
8515 ;; equivalents when possible.
8516 ;; Don't do the splitting with memory operands, since it introduces risk
8517 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8518 ;; for size, but that can (should?) be handled by generic code instead.
8519 (define_split
8520   [(set (match_operand 0 "register_operand" "")
8521         (and (match_operand 1 "register_operand" "")
8522              (match_operand 2 "const_int_operand" "")))
8523    (clobber (reg:CC FLAGS_REG))]
8524    "reload_completed
8525     && QI_REG_P (operands[0])
8526     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8527     && !(~INTVAL (operands[2]) & ~(255 << 8))
8528     && GET_MODE (operands[0]) != QImode"
8529   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8530                    (and:SI (zero_extract:SI (match_dup 1)
8531                                             (const_int 8) (const_int 8))
8532                            (match_dup 2)))
8533               (clobber (reg:CC FLAGS_REG))])]
8534   "operands[0] = gen_lowpart (SImode, operands[0]);
8535    operands[1] = gen_lowpart (SImode, operands[1]);
8536    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8537
8538 ;; Since AND can be encoded with sign extended immediate, this is only
8539 ;; profitable when 7th bit is not set.
8540 (define_split
8541   [(set (match_operand 0 "register_operand" "")
8542         (and (match_operand 1 "general_operand" "")
8543              (match_operand 2 "const_int_operand" "")))
8544    (clobber (reg:CC FLAGS_REG))]
8545    "reload_completed
8546     && ANY_QI_REG_P (operands[0])
8547     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8548     && !(~INTVAL (operands[2]) & ~255)
8549     && !(INTVAL (operands[2]) & 128)
8550     && GET_MODE (operands[0]) != QImode"
8551   [(parallel [(set (strict_low_part (match_dup 0))
8552                    (and:QI (match_dup 1)
8553                            (match_dup 2)))
8554               (clobber (reg:CC FLAGS_REG))])]
8555   "operands[0] = gen_lowpart (QImode, operands[0]);
8556    operands[1] = gen_lowpart (QImode, operands[1]);
8557    operands[2] = gen_lowpart (QImode, operands[2]);")
8558 \f
8559 ;; Logical inclusive OR instructions
8560
8561 ;; %%% This used to optimize known byte-wide and operations to memory.
8562 ;; If this is considered useful, it should be done with splitters.
8563
8564 (define_expand "iordi3"
8565   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8566         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8567                 (match_operand:DI 2 "x86_64_general_operand" "")))
8568    (clobber (reg:CC FLAGS_REG))]
8569   "TARGET_64BIT"
8570   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8571
8572 (define_insn "*iordi_1_rex64"
8573   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8574         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8575                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8576    (clobber (reg:CC FLAGS_REG))]
8577   "TARGET_64BIT
8578    && ix86_binary_operator_ok (IOR, DImode, operands)"
8579   "or{q}\t{%2, %0|%0, %2}"
8580   [(set_attr "type" "alu")
8581    (set_attr "mode" "DI")])
8582
8583 (define_insn "*iordi_2_rex64"
8584   [(set (reg FLAGS_REG)
8585         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8586                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8587                  (const_int 0)))
8588    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8589         (ior:DI (match_dup 1) (match_dup 2)))]
8590   "TARGET_64BIT
8591    && ix86_match_ccmode (insn, CCNOmode)
8592    && ix86_binary_operator_ok (IOR, DImode, operands)"
8593   "or{q}\t{%2, %0|%0, %2}"
8594   [(set_attr "type" "alu")
8595    (set_attr "mode" "DI")])
8596
8597 (define_insn "*iordi_3_rex64"
8598   [(set (reg FLAGS_REG)
8599         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8600                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8601                  (const_int 0)))
8602    (clobber (match_scratch:DI 0 "=r"))]
8603   "TARGET_64BIT
8604    && ix86_match_ccmode (insn, CCNOmode)
8605    && ix86_binary_operator_ok (IOR, DImode, operands)"
8606   "or{q}\t{%2, %0|%0, %2}"
8607   [(set_attr "type" "alu")
8608    (set_attr "mode" "DI")])
8609
8610
8611 (define_expand "iorsi3"
8612   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8613         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8614                 (match_operand:SI 2 "general_operand" "")))
8615    (clobber (reg:CC FLAGS_REG))]
8616   ""
8617   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8618
8619 (define_insn "*iorsi_1"
8620   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8621         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8622                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8623    (clobber (reg:CC FLAGS_REG))]
8624   "ix86_binary_operator_ok (IOR, SImode, operands)"
8625   "or{l}\t{%2, %0|%0, %2}"
8626   [(set_attr "type" "alu")
8627    (set_attr "mode" "SI")])
8628
8629 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8630 (define_insn "*iorsi_1_zext"
8631   [(set (match_operand:DI 0 "register_operand" "=rm")
8632         (zero_extend:DI
8633           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8634                   (match_operand:SI 2 "general_operand" "rim"))))
8635    (clobber (reg:CC FLAGS_REG))]
8636   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8637   "or{l}\t{%2, %k0|%k0, %2}"
8638   [(set_attr "type" "alu")
8639    (set_attr "mode" "SI")])
8640
8641 (define_insn "*iorsi_1_zext_imm"
8642   [(set (match_operand:DI 0 "register_operand" "=rm")
8643         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8644                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8645    (clobber (reg:CC FLAGS_REG))]
8646   "TARGET_64BIT"
8647   "or{l}\t{%2, %k0|%k0, %2}"
8648   [(set_attr "type" "alu")
8649    (set_attr "mode" "SI")])
8650
8651 (define_insn "*iorsi_2"
8652   [(set (reg FLAGS_REG)
8653         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8654                          (match_operand:SI 2 "general_operand" "rim,ri"))
8655                  (const_int 0)))
8656    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8657         (ior:SI (match_dup 1) (match_dup 2)))]
8658   "ix86_match_ccmode (insn, CCNOmode)
8659    && ix86_binary_operator_ok (IOR, SImode, operands)"
8660   "or{l}\t{%2, %0|%0, %2}"
8661   [(set_attr "type" "alu")
8662    (set_attr "mode" "SI")])
8663
8664 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8665 ;; ??? Special case for immediate operand is missing - it is tricky.
8666 (define_insn "*iorsi_2_zext"
8667   [(set (reg FLAGS_REG)
8668         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8669                          (match_operand:SI 2 "general_operand" "rim"))
8670                  (const_int 0)))
8671    (set (match_operand:DI 0 "register_operand" "=r")
8672         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8673   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8674    && ix86_binary_operator_ok (IOR, SImode, operands)"
8675   "or{l}\t{%2, %k0|%k0, %2}"
8676   [(set_attr "type" "alu")
8677    (set_attr "mode" "SI")])
8678
8679 (define_insn "*iorsi_2_zext_imm"
8680   [(set (reg FLAGS_REG)
8681         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8682                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8683                  (const_int 0)))
8684    (set (match_operand:DI 0 "register_operand" "=r")
8685         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8686   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8687    && ix86_binary_operator_ok (IOR, SImode, operands)"
8688   "or{l}\t{%2, %k0|%k0, %2}"
8689   [(set_attr "type" "alu")
8690    (set_attr "mode" "SI")])
8691
8692 (define_insn "*iorsi_3"
8693   [(set (reg FLAGS_REG)
8694         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8695                          (match_operand:SI 2 "general_operand" "rim"))
8696                  (const_int 0)))
8697    (clobber (match_scratch:SI 0 "=r"))]
8698   "ix86_match_ccmode (insn, CCNOmode)
8699    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8700   "or{l}\t{%2, %0|%0, %2}"
8701   [(set_attr "type" "alu")
8702    (set_attr "mode" "SI")])
8703
8704 (define_expand "iorhi3"
8705   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8706         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8707                 (match_operand:HI 2 "general_operand" "")))
8708    (clobber (reg:CC FLAGS_REG))]
8709   "TARGET_HIMODE_MATH"
8710   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8711
8712 (define_insn "*iorhi_1"
8713   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8714         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8715                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8716    (clobber (reg:CC FLAGS_REG))]
8717   "ix86_binary_operator_ok (IOR, HImode, operands)"
8718   "or{w}\t{%2, %0|%0, %2}"
8719   [(set_attr "type" "alu")
8720    (set_attr "mode" "HI")])
8721
8722 (define_insn "*iorhi_2"
8723   [(set (reg FLAGS_REG)
8724         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8725                          (match_operand:HI 2 "general_operand" "rim,ri"))
8726                  (const_int 0)))
8727    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8728         (ior:HI (match_dup 1) (match_dup 2)))]
8729   "ix86_match_ccmode (insn, CCNOmode)
8730    && ix86_binary_operator_ok (IOR, HImode, operands)"
8731   "or{w}\t{%2, %0|%0, %2}"
8732   [(set_attr "type" "alu")
8733    (set_attr "mode" "HI")])
8734
8735 (define_insn "*iorhi_3"
8736   [(set (reg FLAGS_REG)
8737         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8738                          (match_operand:HI 2 "general_operand" "rim"))
8739                  (const_int 0)))
8740    (clobber (match_scratch:HI 0 "=r"))]
8741   "ix86_match_ccmode (insn, CCNOmode)
8742    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8743   "or{w}\t{%2, %0|%0, %2}"
8744   [(set_attr "type" "alu")
8745    (set_attr "mode" "HI")])
8746
8747 (define_expand "iorqi3"
8748   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8749         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8750                 (match_operand:QI 2 "general_operand" "")))
8751    (clobber (reg:CC FLAGS_REG))]
8752   "TARGET_QIMODE_MATH"
8753   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8754
8755 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8756 (define_insn "*iorqi_1"
8757   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8758         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8759                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8760    (clobber (reg:CC FLAGS_REG))]
8761   "ix86_binary_operator_ok (IOR, QImode, operands)"
8762   "@
8763    or{b}\t{%2, %0|%0, %2}
8764    or{b}\t{%2, %0|%0, %2}
8765    or{l}\t{%k2, %k0|%k0, %k2}"
8766   [(set_attr "type" "alu")
8767    (set_attr "mode" "QI,QI,SI")])
8768
8769 (define_insn "*iorqi_1_slp"
8770   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8771         (ior:QI (match_dup 0)
8772                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8773    (clobber (reg:CC FLAGS_REG))]
8774   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8775    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8776   "or{b}\t{%1, %0|%0, %1}"
8777   [(set_attr "type" "alu1")
8778    (set_attr "mode" "QI")])
8779
8780 (define_insn "*iorqi_2"
8781   [(set (reg FLAGS_REG)
8782         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8783                          (match_operand:QI 2 "general_operand" "qim,qi"))
8784                  (const_int 0)))
8785    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8786         (ior:QI (match_dup 1) (match_dup 2)))]
8787   "ix86_match_ccmode (insn, CCNOmode)
8788    && ix86_binary_operator_ok (IOR, QImode, operands)"
8789   "or{b}\t{%2, %0|%0, %2}"
8790   [(set_attr "type" "alu")
8791    (set_attr "mode" "QI")])
8792
8793 (define_insn "*iorqi_2_slp"
8794   [(set (reg FLAGS_REG)
8795         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8796                          (match_operand:QI 1 "general_operand" "qim,qi"))
8797                  (const_int 0)))
8798    (set (strict_low_part (match_dup 0))
8799         (ior:QI (match_dup 0) (match_dup 1)))]
8800   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8801    && ix86_match_ccmode (insn, CCNOmode)
8802    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8803   "or{b}\t{%1, %0|%0, %1}"
8804   [(set_attr "type" "alu1")
8805    (set_attr "mode" "QI")])
8806
8807 (define_insn "*iorqi_3"
8808   [(set (reg FLAGS_REG)
8809         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8810                          (match_operand:QI 2 "general_operand" "qim"))
8811                  (const_int 0)))
8812    (clobber (match_scratch:QI 0 "=q"))]
8813   "ix86_match_ccmode (insn, CCNOmode)
8814    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8815   "or{b}\t{%2, %0|%0, %2}"
8816   [(set_attr "type" "alu")
8817    (set_attr "mode" "QI")])
8818
8819 (define_insn "iorqi_ext_0"
8820   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8821                          (const_int 8)
8822                          (const_int 8))
8823         (ior:SI
8824           (zero_extract:SI
8825             (match_operand 1 "ext_register_operand" "0")
8826             (const_int 8)
8827             (const_int 8))
8828           (match_operand 2 "const_int_operand" "n")))
8829    (clobber (reg:CC FLAGS_REG))]
8830   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8831   "or{b}\t{%2, %h0|%h0, %2}"
8832   [(set_attr "type" "alu")
8833    (set_attr "length_immediate" "1")
8834    (set_attr "mode" "QI")])
8835
8836 (define_insn "*iorqi_ext_1"
8837   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8838                          (const_int 8)
8839                          (const_int 8))
8840         (ior:SI
8841           (zero_extract:SI
8842             (match_operand 1 "ext_register_operand" "0")
8843             (const_int 8)
8844             (const_int 8))
8845           (zero_extend:SI
8846             (match_operand:QI 2 "general_operand" "Qm"))))
8847    (clobber (reg:CC FLAGS_REG))]
8848   "!TARGET_64BIT
8849    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8850   "or{b}\t{%2, %h0|%h0, %2}"
8851   [(set_attr "type" "alu")
8852    (set_attr "length_immediate" "0")
8853    (set_attr "mode" "QI")])
8854
8855 (define_insn "*iorqi_ext_1_rex64"
8856   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8857                          (const_int 8)
8858                          (const_int 8))
8859         (ior:SI
8860           (zero_extract:SI
8861             (match_operand 1 "ext_register_operand" "0")
8862             (const_int 8)
8863             (const_int 8))
8864           (zero_extend:SI
8865             (match_operand 2 "ext_register_operand" "Q"))))
8866    (clobber (reg:CC FLAGS_REG))]
8867   "TARGET_64BIT
8868    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8869   "or{b}\t{%2, %h0|%h0, %2}"
8870   [(set_attr "type" "alu")
8871    (set_attr "length_immediate" "0")
8872    (set_attr "mode" "QI")])
8873
8874 (define_insn "*iorqi_ext_2"
8875   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8876                          (const_int 8)
8877                          (const_int 8))
8878         (ior:SI
8879           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8880                            (const_int 8)
8881                            (const_int 8))
8882           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8883                            (const_int 8)
8884                            (const_int 8))))
8885    (clobber (reg:CC FLAGS_REG))]
8886   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8887   "ior{b}\t{%h2, %h0|%h0, %h2}"
8888   [(set_attr "type" "alu")
8889    (set_attr "length_immediate" "0")
8890    (set_attr "mode" "QI")])
8891
8892 (define_split
8893   [(set (match_operand 0 "register_operand" "")
8894         (ior (match_operand 1 "register_operand" "")
8895              (match_operand 2 "const_int_operand" "")))
8896    (clobber (reg:CC FLAGS_REG))]
8897    "reload_completed
8898     && QI_REG_P (operands[0])
8899     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8900     && !(INTVAL (operands[2]) & ~(255 << 8))
8901     && GET_MODE (operands[0]) != QImode"
8902   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8903                    (ior:SI (zero_extract:SI (match_dup 1)
8904                                             (const_int 8) (const_int 8))
8905                            (match_dup 2)))
8906               (clobber (reg:CC FLAGS_REG))])]
8907   "operands[0] = gen_lowpart (SImode, operands[0]);
8908    operands[1] = gen_lowpart (SImode, operands[1]);
8909    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8910
8911 ;; Since OR can be encoded with sign extended immediate, this is only
8912 ;; profitable when 7th bit is set.
8913 (define_split
8914   [(set (match_operand 0 "register_operand" "")
8915         (ior (match_operand 1 "general_operand" "")
8916              (match_operand 2 "const_int_operand" "")))
8917    (clobber (reg:CC FLAGS_REG))]
8918    "reload_completed
8919     && ANY_QI_REG_P (operands[0])
8920     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8921     && !(INTVAL (operands[2]) & ~255)
8922     && (INTVAL (operands[2]) & 128)
8923     && GET_MODE (operands[0]) != QImode"
8924   [(parallel [(set (strict_low_part (match_dup 0))
8925                    (ior:QI (match_dup 1)
8926                            (match_dup 2)))
8927               (clobber (reg:CC FLAGS_REG))])]
8928   "operands[0] = gen_lowpart (QImode, operands[0]);
8929    operands[1] = gen_lowpart (QImode, operands[1]);
8930    operands[2] = gen_lowpart (QImode, operands[2]);")
8931 \f
8932 ;; Logical XOR instructions
8933
8934 ;; %%% This used to optimize known byte-wide and operations to memory.
8935 ;; If this is considered useful, it should be done with splitters.
8936
8937 (define_expand "xordi3"
8938   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8939         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8940                 (match_operand:DI 2 "x86_64_general_operand" "")))
8941    (clobber (reg:CC FLAGS_REG))]
8942   "TARGET_64BIT"
8943   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8944
8945 (define_insn "*xordi_1_rex64"
8946   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8947         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8948                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8949    (clobber (reg:CC FLAGS_REG))]
8950   "TARGET_64BIT
8951    && ix86_binary_operator_ok (XOR, DImode, operands)"
8952   "@
8953    xor{q}\t{%2, %0|%0, %2}
8954    xor{q}\t{%2, %0|%0, %2}"
8955   [(set_attr "type" "alu")
8956    (set_attr "mode" "DI,DI")])
8957
8958 (define_insn "*xordi_2_rex64"
8959   [(set (reg FLAGS_REG)
8960         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8961                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8962                  (const_int 0)))
8963    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8964         (xor:DI (match_dup 1) (match_dup 2)))]
8965   "TARGET_64BIT
8966    && ix86_match_ccmode (insn, CCNOmode)
8967    && ix86_binary_operator_ok (XOR, DImode, operands)"
8968   "@
8969    xor{q}\t{%2, %0|%0, %2}
8970    xor{q}\t{%2, %0|%0, %2}"
8971   [(set_attr "type" "alu")
8972    (set_attr "mode" "DI,DI")])
8973
8974 (define_insn "*xordi_3_rex64"
8975   [(set (reg FLAGS_REG)
8976         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8977                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8978                  (const_int 0)))
8979    (clobber (match_scratch:DI 0 "=r"))]
8980   "TARGET_64BIT
8981    && ix86_match_ccmode (insn, CCNOmode)
8982    && ix86_binary_operator_ok (XOR, DImode, operands)"
8983   "xor{q}\t{%2, %0|%0, %2}"
8984   [(set_attr "type" "alu")
8985    (set_attr "mode" "DI")])
8986
8987 (define_expand "xorsi3"
8988   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8989         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8990                 (match_operand:SI 2 "general_operand" "")))
8991    (clobber (reg:CC FLAGS_REG))]
8992   ""
8993   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8994
8995 (define_insn "*xorsi_1"
8996   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8997         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8998                 (match_operand:SI 2 "general_operand" "ri,rm")))
8999    (clobber (reg:CC FLAGS_REG))]
9000   "ix86_binary_operator_ok (XOR, SImode, operands)"
9001   "xor{l}\t{%2, %0|%0, %2}"
9002   [(set_attr "type" "alu")
9003    (set_attr "mode" "SI")])
9004
9005 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9006 ;; Add speccase for immediates
9007 (define_insn "*xorsi_1_zext"
9008   [(set (match_operand:DI 0 "register_operand" "=r")
9009         (zero_extend:DI
9010           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9011                   (match_operand:SI 2 "general_operand" "rim"))))
9012    (clobber (reg:CC FLAGS_REG))]
9013   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9014   "xor{l}\t{%2, %k0|%k0, %2}"
9015   [(set_attr "type" "alu")
9016    (set_attr "mode" "SI")])
9017
9018 (define_insn "*xorsi_1_zext_imm"
9019   [(set (match_operand:DI 0 "register_operand" "=r")
9020         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9021                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9022    (clobber (reg:CC FLAGS_REG))]
9023   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9024   "xor{l}\t{%2, %k0|%k0, %2}"
9025   [(set_attr "type" "alu")
9026    (set_attr "mode" "SI")])
9027
9028 (define_insn "*xorsi_2"
9029   [(set (reg FLAGS_REG)
9030         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9031                          (match_operand:SI 2 "general_operand" "rim,ri"))
9032                  (const_int 0)))
9033    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9034         (xor:SI (match_dup 1) (match_dup 2)))]
9035   "ix86_match_ccmode (insn, CCNOmode)
9036    && ix86_binary_operator_ok (XOR, SImode, operands)"
9037   "xor{l}\t{%2, %0|%0, %2}"
9038   [(set_attr "type" "alu")
9039    (set_attr "mode" "SI")])
9040
9041 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9042 ;; ??? Special case for immediate operand is missing - it is tricky.
9043 (define_insn "*xorsi_2_zext"
9044   [(set (reg FLAGS_REG)
9045         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9046                          (match_operand:SI 2 "general_operand" "rim"))
9047                  (const_int 0)))
9048    (set (match_operand:DI 0 "register_operand" "=r")
9049         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9050   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9051    && ix86_binary_operator_ok (XOR, SImode, operands)"
9052   "xor{l}\t{%2, %k0|%k0, %2}"
9053   [(set_attr "type" "alu")
9054    (set_attr "mode" "SI")])
9055
9056 (define_insn "*xorsi_2_zext_imm"
9057   [(set (reg FLAGS_REG)
9058         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9059                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9060                  (const_int 0)))
9061    (set (match_operand:DI 0 "register_operand" "=r")
9062         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9063   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9064    && ix86_binary_operator_ok (XOR, SImode, operands)"
9065   "xor{l}\t{%2, %k0|%k0, %2}"
9066   [(set_attr "type" "alu")
9067    (set_attr "mode" "SI")])
9068
9069 (define_insn "*xorsi_3"
9070   [(set (reg FLAGS_REG)
9071         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9072                          (match_operand:SI 2 "general_operand" "rim"))
9073                  (const_int 0)))
9074    (clobber (match_scratch:SI 0 "=r"))]
9075   "ix86_match_ccmode (insn, CCNOmode)
9076    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9077   "xor{l}\t{%2, %0|%0, %2}"
9078   [(set_attr "type" "alu")
9079    (set_attr "mode" "SI")])
9080
9081 (define_expand "xorhi3"
9082   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9083         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9084                 (match_operand:HI 2 "general_operand" "")))
9085    (clobber (reg:CC FLAGS_REG))]
9086   "TARGET_HIMODE_MATH"
9087   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9088
9089 (define_insn "*xorhi_1"
9090   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9091         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9092                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9093    (clobber (reg:CC FLAGS_REG))]
9094   "ix86_binary_operator_ok (XOR, HImode, operands)"
9095   "xor{w}\t{%2, %0|%0, %2}"
9096   [(set_attr "type" "alu")
9097    (set_attr "mode" "HI")])
9098
9099 (define_insn "*xorhi_2"
9100   [(set (reg FLAGS_REG)
9101         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9102                          (match_operand:HI 2 "general_operand" "rim,ri"))
9103                  (const_int 0)))
9104    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9105         (xor:HI (match_dup 1) (match_dup 2)))]
9106   "ix86_match_ccmode (insn, CCNOmode)
9107    && ix86_binary_operator_ok (XOR, HImode, operands)"
9108   "xor{w}\t{%2, %0|%0, %2}"
9109   [(set_attr "type" "alu")
9110    (set_attr "mode" "HI")])
9111
9112 (define_insn "*xorhi_3"
9113   [(set (reg FLAGS_REG)
9114         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9115                          (match_operand:HI 2 "general_operand" "rim"))
9116                  (const_int 0)))
9117    (clobber (match_scratch:HI 0 "=r"))]
9118   "ix86_match_ccmode (insn, CCNOmode)
9119    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9120   "xor{w}\t{%2, %0|%0, %2}"
9121   [(set_attr "type" "alu")
9122    (set_attr "mode" "HI")])
9123
9124 (define_expand "xorqi3"
9125   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9126         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9127                 (match_operand:QI 2 "general_operand" "")))
9128    (clobber (reg:CC FLAGS_REG))]
9129   "TARGET_QIMODE_MATH"
9130   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9131
9132 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9133 (define_insn "*xorqi_1"
9134   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9135         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9136                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9137    (clobber (reg:CC FLAGS_REG))]
9138   "ix86_binary_operator_ok (XOR, QImode, operands)"
9139   "@
9140    xor{b}\t{%2, %0|%0, %2}
9141    xor{b}\t{%2, %0|%0, %2}
9142    xor{l}\t{%k2, %k0|%k0, %k2}"
9143   [(set_attr "type" "alu")
9144    (set_attr "mode" "QI,QI,SI")])
9145
9146 (define_insn "*xorqi_1_slp"
9147   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9148         (xor:QI (match_dup 0)
9149                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9150    (clobber (reg:CC FLAGS_REG))]
9151   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9152    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9153   "xor{b}\t{%1, %0|%0, %1}"
9154   [(set_attr "type" "alu1")
9155    (set_attr "mode" "QI")])
9156
9157 (define_insn "xorqi_ext_0"
9158   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9159                          (const_int 8)
9160                          (const_int 8))
9161         (xor:SI
9162           (zero_extract:SI
9163             (match_operand 1 "ext_register_operand" "0")
9164             (const_int 8)
9165             (const_int 8))
9166           (match_operand 2 "const_int_operand" "n")))
9167    (clobber (reg:CC FLAGS_REG))]
9168   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9169   "xor{b}\t{%2, %h0|%h0, %2}"
9170   [(set_attr "type" "alu")
9171    (set_attr "length_immediate" "1")
9172    (set_attr "mode" "QI")])
9173
9174 (define_insn "*xorqi_ext_1"
9175   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9176                          (const_int 8)
9177                          (const_int 8))
9178         (xor:SI
9179           (zero_extract:SI
9180             (match_operand 1 "ext_register_operand" "0")
9181             (const_int 8)
9182             (const_int 8))
9183           (zero_extend:SI
9184             (match_operand:QI 2 "general_operand" "Qm"))))
9185    (clobber (reg:CC FLAGS_REG))]
9186   "!TARGET_64BIT
9187    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9188   "xor{b}\t{%2, %h0|%h0, %2}"
9189   [(set_attr "type" "alu")
9190    (set_attr "length_immediate" "0")
9191    (set_attr "mode" "QI")])
9192
9193 (define_insn "*xorqi_ext_1_rex64"
9194   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9195                          (const_int 8)
9196                          (const_int 8))
9197         (xor:SI
9198           (zero_extract:SI
9199             (match_operand 1 "ext_register_operand" "0")
9200             (const_int 8)
9201             (const_int 8))
9202           (zero_extend:SI
9203             (match_operand 2 "ext_register_operand" "Q"))))
9204    (clobber (reg:CC FLAGS_REG))]
9205   "TARGET_64BIT
9206    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9207   "xor{b}\t{%2, %h0|%h0, %2}"
9208   [(set_attr "type" "alu")
9209    (set_attr "length_immediate" "0")
9210    (set_attr "mode" "QI")])
9211
9212 (define_insn "*xorqi_ext_2"
9213   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9214                          (const_int 8)
9215                          (const_int 8))
9216         (xor:SI
9217           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9218                            (const_int 8)
9219                            (const_int 8))
9220           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9221                            (const_int 8)
9222                            (const_int 8))))
9223    (clobber (reg:CC FLAGS_REG))]
9224   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9225   "xor{b}\t{%h2, %h0|%h0, %h2}"
9226   [(set_attr "type" "alu")
9227    (set_attr "length_immediate" "0")
9228    (set_attr "mode" "QI")])
9229
9230 (define_insn "*xorqi_cc_1"
9231   [(set (reg FLAGS_REG)
9232         (compare
9233           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9234                   (match_operand:QI 2 "general_operand" "qim,qi"))
9235           (const_int 0)))
9236    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9237         (xor:QI (match_dup 1) (match_dup 2)))]
9238   "ix86_match_ccmode (insn, CCNOmode)
9239    && ix86_binary_operator_ok (XOR, QImode, operands)"
9240   "xor{b}\t{%2, %0|%0, %2}"
9241   [(set_attr "type" "alu")
9242    (set_attr "mode" "QI")])
9243
9244 (define_insn "*xorqi_2_slp"
9245   [(set (reg FLAGS_REG)
9246         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9247                          (match_operand:QI 1 "general_operand" "qim,qi"))
9248                  (const_int 0)))
9249    (set (strict_low_part (match_dup 0))
9250         (xor:QI (match_dup 0) (match_dup 1)))]
9251   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9252    && ix86_match_ccmode (insn, CCNOmode)
9253    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9254   "xor{b}\t{%1, %0|%0, %1}"
9255   [(set_attr "type" "alu1")
9256    (set_attr "mode" "QI")])
9257
9258 (define_insn "*xorqi_cc_2"
9259   [(set (reg FLAGS_REG)
9260         (compare
9261           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9262                   (match_operand:QI 2 "general_operand" "qim"))
9263           (const_int 0)))
9264    (clobber (match_scratch:QI 0 "=q"))]
9265   "ix86_match_ccmode (insn, CCNOmode)
9266    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9267   "xor{b}\t{%2, %0|%0, %2}"
9268   [(set_attr "type" "alu")
9269    (set_attr "mode" "QI")])
9270
9271 (define_insn "*xorqi_cc_ext_1"
9272   [(set (reg FLAGS_REG)
9273         (compare
9274           (xor:SI
9275             (zero_extract:SI
9276               (match_operand 1 "ext_register_operand" "0")
9277               (const_int 8)
9278               (const_int 8))
9279             (match_operand:QI 2 "general_operand" "qmn"))
9280           (const_int 0)))
9281    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9282                          (const_int 8)
9283                          (const_int 8))
9284         (xor:SI
9285           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9286           (match_dup 2)))]
9287   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9288   "xor{b}\t{%2, %h0|%h0, %2}"
9289   [(set_attr "type" "alu")
9290    (set_attr "mode" "QI")])
9291
9292 (define_insn "*xorqi_cc_ext_1_rex64"
9293   [(set (reg FLAGS_REG)
9294         (compare
9295           (xor:SI
9296             (zero_extract:SI
9297               (match_operand 1 "ext_register_operand" "0")
9298               (const_int 8)
9299               (const_int 8))
9300             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9301           (const_int 0)))
9302    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9303                          (const_int 8)
9304                          (const_int 8))
9305         (xor:SI
9306           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9307           (match_dup 2)))]
9308   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9309   "xor{b}\t{%2, %h0|%h0, %2}"
9310   [(set_attr "type" "alu")
9311    (set_attr "mode" "QI")])
9312
9313 (define_expand "xorqi_cc_ext_1"
9314   [(parallel [
9315      (set (reg:CCNO FLAGS_REG)
9316           (compare:CCNO
9317             (xor:SI
9318               (zero_extract:SI
9319                 (match_operand 1 "ext_register_operand" "")
9320                 (const_int 8)
9321                 (const_int 8))
9322               (match_operand:QI 2 "general_operand" ""))
9323             (const_int 0)))
9324      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9325                            (const_int 8)
9326                            (const_int 8))
9327           (xor:SI
9328             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9329             (match_dup 2)))])]
9330   ""
9331   "")
9332
9333 (define_split
9334   [(set (match_operand 0 "register_operand" "")
9335         (xor (match_operand 1 "register_operand" "")
9336              (match_operand 2 "const_int_operand" "")))
9337    (clobber (reg:CC FLAGS_REG))]
9338    "reload_completed
9339     && QI_REG_P (operands[0])
9340     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9341     && !(INTVAL (operands[2]) & ~(255 << 8))
9342     && GET_MODE (operands[0]) != QImode"
9343   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9344                    (xor:SI (zero_extract:SI (match_dup 1)
9345                                             (const_int 8) (const_int 8))
9346                            (match_dup 2)))
9347               (clobber (reg:CC FLAGS_REG))])]
9348   "operands[0] = gen_lowpart (SImode, operands[0]);
9349    operands[1] = gen_lowpart (SImode, operands[1]);
9350    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9351
9352 ;; Since XOR can be encoded with sign extended immediate, this is only
9353 ;; profitable when 7th bit is set.
9354 (define_split
9355   [(set (match_operand 0 "register_operand" "")
9356         (xor (match_operand 1 "general_operand" "")
9357              (match_operand 2 "const_int_operand" "")))
9358    (clobber (reg:CC FLAGS_REG))]
9359    "reload_completed
9360     && ANY_QI_REG_P (operands[0])
9361     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9362     && !(INTVAL (operands[2]) & ~255)
9363     && (INTVAL (operands[2]) & 128)
9364     && GET_MODE (operands[0]) != QImode"
9365   [(parallel [(set (strict_low_part (match_dup 0))
9366                    (xor:QI (match_dup 1)
9367                            (match_dup 2)))
9368               (clobber (reg:CC FLAGS_REG))])]
9369   "operands[0] = gen_lowpart (QImode, operands[0]);
9370    operands[1] = gen_lowpart (QImode, operands[1]);
9371    operands[2] = gen_lowpart (QImode, operands[2]);")
9372 \f
9373 ;; Negation instructions
9374
9375 (define_expand "negti2"
9376   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9377                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9378               (clobber (reg:CC FLAGS_REG))])]
9379   "TARGET_64BIT"
9380   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9381
9382 (define_insn "*negti2_1"
9383   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9384         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9385    (clobber (reg:CC FLAGS_REG))]
9386   "TARGET_64BIT
9387    && ix86_unary_operator_ok (NEG, TImode, operands)"
9388   "#")
9389
9390 (define_split
9391   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9392         (neg:TI (match_operand:TI 1 "general_operand" "")))
9393    (clobber (reg:CC FLAGS_REG))]
9394   "TARGET_64BIT && reload_completed"
9395   [(parallel
9396     [(set (reg:CCZ FLAGS_REG)
9397           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9398      (set (match_dup 0) (neg:DI (match_dup 2)))])
9399    (parallel
9400     [(set (match_dup 1)
9401           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9402                             (match_dup 3))
9403                    (const_int 0)))
9404      (clobber (reg:CC FLAGS_REG))])
9405    (parallel
9406     [(set (match_dup 1)
9407           (neg:DI (match_dup 1)))
9408      (clobber (reg:CC FLAGS_REG))])]
9409   "split_ti (operands+1, 1, operands+2, operands+3);
9410    split_ti (operands+0, 1, operands+0, operands+1);")
9411
9412 (define_expand "negdi2"
9413   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9414                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9415               (clobber (reg:CC FLAGS_REG))])]
9416   ""
9417   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9418
9419 (define_insn "*negdi2_1"
9420   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9421         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9422    (clobber (reg:CC FLAGS_REG))]
9423   "!TARGET_64BIT
9424    && ix86_unary_operator_ok (NEG, DImode, operands)"
9425   "#")
9426
9427 (define_split
9428   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9429         (neg:DI (match_operand:DI 1 "general_operand" "")))
9430    (clobber (reg:CC FLAGS_REG))]
9431   "!TARGET_64BIT && reload_completed"
9432   [(parallel
9433     [(set (reg:CCZ FLAGS_REG)
9434           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9435      (set (match_dup 0) (neg:SI (match_dup 2)))])
9436    (parallel
9437     [(set (match_dup 1)
9438           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9439                             (match_dup 3))
9440                    (const_int 0)))
9441      (clobber (reg:CC FLAGS_REG))])
9442    (parallel
9443     [(set (match_dup 1)
9444           (neg:SI (match_dup 1)))
9445      (clobber (reg:CC FLAGS_REG))])]
9446   "split_di (operands+1, 1, operands+2, operands+3);
9447    split_di (operands+0, 1, operands+0, operands+1);")
9448
9449 (define_insn "*negdi2_1_rex64"
9450   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9451         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9452    (clobber (reg:CC FLAGS_REG))]
9453   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9454   "neg{q}\t%0"
9455   [(set_attr "type" "negnot")
9456    (set_attr "mode" "DI")])
9457
9458 ;; The problem with neg is that it does not perform (compare x 0),
9459 ;; it really performs (compare 0 x), which leaves us with the zero
9460 ;; flag being the only useful item.
9461
9462 (define_insn "*negdi2_cmpz_rex64"
9463   [(set (reg:CCZ FLAGS_REG)
9464         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9465                      (const_int 0)))
9466    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9467         (neg:DI (match_dup 1)))]
9468   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9469   "neg{q}\t%0"
9470   [(set_attr "type" "negnot")
9471    (set_attr "mode" "DI")])
9472
9473
9474 (define_expand "negsi2"
9475   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9476                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9477               (clobber (reg:CC FLAGS_REG))])]
9478   ""
9479   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9480
9481 (define_insn "*negsi2_1"
9482   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9483         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9484    (clobber (reg:CC FLAGS_REG))]
9485   "ix86_unary_operator_ok (NEG, SImode, operands)"
9486   "neg{l}\t%0"
9487   [(set_attr "type" "negnot")
9488    (set_attr "mode" "SI")])
9489
9490 ;; Combine is quite creative about this pattern.
9491 (define_insn "*negsi2_1_zext"
9492   [(set (match_operand:DI 0 "register_operand" "=r")
9493         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9494                                         (const_int 32)))
9495                      (const_int 32)))
9496    (clobber (reg:CC FLAGS_REG))]
9497   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9498   "neg{l}\t%k0"
9499   [(set_attr "type" "negnot")
9500    (set_attr "mode" "SI")])
9501
9502 ;; The problem with neg is that it does not perform (compare x 0),
9503 ;; it really performs (compare 0 x), which leaves us with the zero
9504 ;; flag being the only useful item.
9505
9506 (define_insn "*negsi2_cmpz"
9507   [(set (reg:CCZ FLAGS_REG)
9508         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9509                      (const_int 0)))
9510    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9511         (neg:SI (match_dup 1)))]
9512   "ix86_unary_operator_ok (NEG, SImode, operands)"
9513   "neg{l}\t%0"
9514   [(set_attr "type" "negnot")
9515    (set_attr "mode" "SI")])
9516
9517 (define_insn "*negsi2_cmpz_zext"
9518   [(set (reg:CCZ FLAGS_REG)
9519         (compare:CCZ (lshiftrt:DI
9520                        (neg:DI (ashift:DI
9521                                  (match_operand:DI 1 "register_operand" "0")
9522                                  (const_int 32)))
9523                        (const_int 32))
9524                      (const_int 0)))
9525    (set (match_operand:DI 0 "register_operand" "=r")
9526         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9527                                         (const_int 32)))
9528                      (const_int 32)))]
9529   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9530   "neg{l}\t%k0"
9531   [(set_attr "type" "negnot")
9532    (set_attr "mode" "SI")])
9533
9534 (define_expand "neghi2"
9535   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9536                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9537               (clobber (reg:CC FLAGS_REG))])]
9538   "TARGET_HIMODE_MATH"
9539   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9540
9541 (define_insn "*neghi2_1"
9542   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9543         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9544    (clobber (reg:CC FLAGS_REG))]
9545   "ix86_unary_operator_ok (NEG, HImode, operands)"
9546   "neg{w}\t%0"
9547   [(set_attr "type" "negnot")
9548    (set_attr "mode" "HI")])
9549
9550 (define_insn "*neghi2_cmpz"
9551   [(set (reg:CCZ FLAGS_REG)
9552         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9553                      (const_int 0)))
9554    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9555         (neg:HI (match_dup 1)))]
9556   "ix86_unary_operator_ok (NEG, HImode, operands)"
9557   "neg{w}\t%0"
9558   [(set_attr "type" "negnot")
9559    (set_attr "mode" "HI")])
9560
9561 (define_expand "negqi2"
9562   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9563                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9564               (clobber (reg:CC FLAGS_REG))])]
9565   "TARGET_QIMODE_MATH"
9566   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9567
9568 (define_insn "*negqi2_1"
9569   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9570         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9571    (clobber (reg:CC FLAGS_REG))]
9572   "ix86_unary_operator_ok (NEG, QImode, operands)"
9573   "neg{b}\t%0"
9574   [(set_attr "type" "negnot")
9575    (set_attr "mode" "QI")])
9576
9577 (define_insn "*negqi2_cmpz"
9578   [(set (reg:CCZ FLAGS_REG)
9579         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9580                      (const_int 0)))
9581    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9582         (neg:QI (match_dup 1)))]
9583   "ix86_unary_operator_ok (NEG, QImode, operands)"
9584   "neg{b}\t%0"
9585   [(set_attr "type" "negnot")
9586    (set_attr "mode" "QI")])
9587
9588 ;; Changing of sign for FP values is doable using integer unit too.
9589
9590 (define_expand "negsf2"
9591   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9592         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9593   "TARGET_80387 || TARGET_SSE_MATH"
9594   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9595
9596 (define_expand "abssf2"
9597   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9598         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9599   "TARGET_80387 || TARGET_SSE_MATH"
9600   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9601
9602 (define_insn "*absnegsf2_mixed"
9603   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9604         (match_operator:SF 3 "absneg_operator"
9605           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9606    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9607    (clobber (reg:CC FLAGS_REG))]
9608   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9609    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9610   "#")
9611
9612 (define_insn "*absnegsf2_sse"
9613   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9614         (match_operator:SF 3 "absneg_operator"
9615           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9616    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9617    (clobber (reg:CC FLAGS_REG))]
9618   "TARGET_SSE_MATH
9619    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9620   "#")
9621
9622 (define_insn "*absnegsf2_i387"
9623   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9624         (match_operator:SF 3 "absneg_operator"
9625           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9626    (use (match_operand 2 "" ""))
9627    (clobber (reg:CC FLAGS_REG))]
9628   "TARGET_80387 && !TARGET_SSE_MATH
9629    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9630   "#")
9631
9632 (define_expand "copysignsf3"
9633   [(match_operand:SF 0 "register_operand" "")
9634    (match_operand:SF 1 "nonmemory_operand" "")
9635    (match_operand:SF 2 "register_operand" "")]
9636   "TARGET_SSE_MATH"
9637 {
9638   ix86_expand_copysign (operands);
9639   DONE;
9640 })
9641
9642 (define_insn_and_split "copysignsf3_const"
9643   [(set (match_operand:SF 0 "register_operand"          "=x")
9644         (unspec:SF
9645           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9646            (match_operand:SF 2 "register_operand"       "0")
9647            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9648           UNSPEC_COPYSIGN))]
9649   "TARGET_SSE_MATH"
9650   "#"
9651   "&& reload_completed"
9652   [(const_int 0)]
9653 {
9654   ix86_split_copysign_const (operands);
9655   DONE;
9656 })
9657
9658 (define_insn "copysignsf3_var"
9659   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9660         (unspec:SF
9661           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9662            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9663            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9664            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9665           UNSPEC_COPYSIGN))
9666    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9667   "TARGET_SSE_MATH"
9668   "#")
9669
9670 (define_split
9671   [(set (match_operand:SF 0 "register_operand" "")
9672         (unspec:SF
9673           [(match_operand:SF 2 "register_operand" "")
9674            (match_operand:SF 3 "register_operand" "")
9675            (match_operand:V4SF 4 "" "")
9676            (match_operand:V4SF 5 "" "")]
9677           UNSPEC_COPYSIGN))
9678    (clobber (match_scratch:V4SF 1 ""))]
9679   "TARGET_SSE_MATH && reload_completed"
9680   [(const_int 0)]
9681 {
9682   ix86_split_copysign_var (operands);
9683   DONE;
9684 })
9685
9686 (define_expand "negdf2"
9687   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9688         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9689   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9690   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9691
9692 (define_expand "absdf2"
9693   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9694         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9695   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9696   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9697
9698 (define_insn "*absnegdf2_mixed"
9699   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,f,rm")
9700         (match_operator:DF 3 "absneg_operator"
9701           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9702    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X,X"))
9703    (clobber (reg:CC FLAGS_REG))]
9704   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9705    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9706   "#")
9707
9708 (define_insn "*absnegdf2_sse"
9709   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9710         (match_operator:DF 3 "absneg_operator"
9711           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9712    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X "))
9713    (clobber (reg:CC FLAGS_REG))]
9714   "TARGET_SSE2 && TARGET_SSE_MATH
9715    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9716   "#")
9717
9718 (define_insn "*absnegdf2_i387"
9719   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9720         (match_operator:DF 3 "absneg_operator"
9721           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9722    (use (match_operand 2 "" ""))
9723    (clobber (reg:CC FLAGS_REG))]
9724   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9725    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9726   "#")
9727
9728 (define_expand "copysigndf3"
9729   [(match_operand:DF 0 "register_operand" "")
9730    (match_operand:DF 1 "nonmemory_operand" "")
9731    (match_operand:DF 2 "register_operand" "")]
9732   "TARGET_SSE2 && TARGET_SSE_MATH"
9733 {
9734   ix86_expand_copysign (operands);
9735   DONE;
9736 })
9737
9738 (define_insn_and_split "copysigndf3_const"
9739   [(set (match_operand:DF 0 "register_operand"          "=x")
9740         (unspec:DF
9741           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9742            (match_operand:DF 2 "register_operand"       "0")
9743            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9744           UNSPEC_COPYSIGN))]
9745   "TARGET_SSE2 && TARGET_SSE_MATH"
9746   "#"
9747   "&& reload_completed"
9748   [(const_int 0)]
9749 {
9750   ix86_split_copysign_const (operands);
9751   DONE;
9752 })
9753
9754 (define_insn "copysigndf3_var"
9755   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9756         (unspec:DF
9757           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9758            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9759            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9760            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9761           UNSPEC_COPYSIGN))
9762    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9763   "TARGET_SSE2 && TARGET_SSE_MATH"
9764   "#")
9765
9766 (define_split
9767   [(set (match_operand:DF 0 "register_operand" "")
9768         (unspec:DF
9769           [(match_operand:DF 2 "register_operand" "")
9770            (match_operand:DF 3 "register_operand" "")
9771            (match_operand:V2DF 4 "" "")
9772            (match_operand:V2DF 5 "" "")]
9773           UNSPEC_COPYSIGN))
9774    (clobber (match_scratch:V2DF 1 ""))]
9775   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9776   [(const_int 0)]
9777 {
9778   ix86_split_copysign_var (operands);
9779   DONE;
9780 })
9781
9782 (define_expand "negxf2"
9783   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9784         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9785   "TARGET_80387"
9786   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9787
9788 (define_expand "absxf2"
9789   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9790         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9791   "TARGET_80387"
9792   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9793
9794 (define_insn "*absnegxf2_i387"
9795   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9796         (match_operator:XF 3 "absneg_operator"
9797           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9798    (use (match_operand 2 "" ""))
9799    (clobber (reg:CC FLAGS_REG))]
9800   "TARGET_80387
9801    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9802   "#")
9803
9804 ;; Splitters for fp abs and neg.
9805
9806 (define_split
9807   [(set (match_operand 0 "fp_register_operand" "")
9808         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9809    (use (match_operand 2 "" ""))
9810    (clobber (reg:CC FLAGS_REG))]
9811   "reload_completed"
9812   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9813
9814 (define_split
9815   [(set (match_operand 0 "register_operand" "")
9816         (match_operator 3 "absneg_operator"
9817           [(match_operand 1 "register_operand" "")]))
9818    (use (match_operand 2 "nonimmediate_operand" ""))
9819    (clobber (reg:CC FLAGS_REG))]
9820   "reload_completed && SSE_REG_P (operands[0])"
9821   [(set (match_dup 0) (match_dup 3))]
9822 {
9823   enum machine_mode mode = GET_MODE (operands[0]);
9824   enum machine_mode vmode = GET_MODE (operands[2]);
9825   rtx tmp;
9826
9827   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9828   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9829   if (operands_match_p (operands[0], operands[2]))
9830     {
9831       tmp = operands[1];
9832       operands[1] = operands[2];
9833       operands[2] = tmp;
9834     }
9835   if (GET_CODE (operands[3]) == ABS)
9836     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9837   else
9838     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9839   operands[3] = tmp;
9840 })
9841
9842 (define_split
9843   [(set (match_operand:SF 0 "register_operand" "")
9844         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9845    (use (match_operand:V4SF 2 "" ""))
9846    (clobber (reg:CC FLAGS_REG))]
9847   "reload_completed"
9848   [(parallel [(set (match_dup 0) (match_dup 1))
9849               (clobber (reg:CC FLAGS_REG))])]
9850 {
9851   rtx tmp;
9852   operands[0] = gen_lowpart (SImode, operands[0]);
9853   if (GET_CODE (operands[1]) == ABS)
9854     {
9855       tmp = gen_int_mode (0x7fffffff, SImode);
9856       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9857     }
9858   else
9859     {
9860       tmp = gen_int_mode (0x80000000, SImode);
9861       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9862     }
9863   operands[1] = tmp;
9864 })
9865
9866 (define_split
9867   [(set (match_operand:DF 0 "register_operand" "")
9868         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9869    (use (match_operand 2 "" ""))
9870    (clobber (reg:CC FLAGS_REG))]
9871   "reload_completed"
9872   [(parallel [(set (match_dup 0) (match_dup 1))
9873               (clobber (reg:CC FLAGS_REG))])]
9874 {
9875   rtx tmp;
9876   if (TARGET_64BIT)
9877     {
9878       tmp = gen_lowpart (DImode, operands[0]);
9879       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9880       operands[0] = tmp;
9881
9882       if (GET_CODE (operands[1]) == ABS)
9883         tmp = const0_rtx;
9884       else
9885         tmp = gen_rtx_NOT (DImode, tmp);
9886     }
9887   else
9888     {
9889       operands[0] = gen_highpart (SImode, operands[0]);
9890       if (GET_CODE (operands[1]) == ABS)
9891         {
9892           tmp = gen_int_mode (0x7fffffff, SImode);
9893           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9894         }
9895       else
9896         {
9897           tmp = gen_int_mode (0x80000000, SImode);
9898           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9899         }
9900     }
9901   operands[1] = tmp;
9902 })
9903
9904 (define_split
9905   [(set (match_operand:XF 0 "register_operand" "")
9906         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9907    (use (match_operand 2 "" ""))
9908    (clobber (reg:CC FLAGS_REG))]
9909   "reload_completed"
9910   [(parallel [(set (match_dup 0) (match_dup 1))
9911               (clobber (reg:CC FLAGS_REG))])]
9912 {
9913   rtx tmp;
9914   operands[0] = gen_rtx_REG (SImode,
9915                              true_regnum (operands[0])
9916                              + (TARGET_64BIT ? 1 : 2));
9917   if (GET_CODE (operands[1]) == ABS)
9918     {
9919       tmp = GEN_INT (0x7fff);
9920       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9921     }
9922   else
9923     {
9924       tmp = GEN_INT (0x8000);
9925       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9926     }
9927   operands[1] = tmp;
9928 })
9929
9930 (define_split
9931   [(set (match_operand 0 "memory_operand" "")
9932         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9933    (use (match_operand 2 "" ""))
9934    (clobber (reg:CC FLAGS_REG))]
9935   "reload_completed"
9936   [(parallel [(set (match_dup 0) (match_dup 1))
9937               (clobber (reg:CC FLAGS_REG))])]
9938 {
9939   enum machine_mode mode = GET_MODE (operands[0]);
9940   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9941   rtx tmp;
9942
9943   operands[0] = adjust_address (operands[0], QImode, size - 1);
9944   if (GET_CODE (operands[1]) == ABS)
9945     {
9946       tmp = gen_int_mode (0x7f, QImode);
9947       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9948     }
9949   else
9950     {
9951       tmp = gen_int_mode (0x80, QImode);
9952       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9953     }
9954   operands[1] = tmp;
9955 })
9956
9957 ;; Conditionalize these after reload. If they match before reload, we
9958 ;; lose the clobber and ability to use integer instructions.
9959
9960 (define_insn "*negsf2_1"
9961   [(set (match_operand:SF 0 "register_operand" "=f")
9962         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9963   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9964   "fchs"
9965   [(set_attr "type" "fsgn")
9966    (set_attr "mode" "SF")])
9967
9968 (define_insn "*negdf2_1"
9969   [(set (match_operand:DF 0 "register_operand" "=f")
9970         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9971   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9972   "fchs"
9973   [(set_attr "type" "fsgn")
9974    (set_attr "mode" "DF")])
9975
9976 (define_insn "*negxf2_1"
9977   [(set (match_operand:XF 0 "register_operand" "=f")
9978         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9979   "TARGET_80387"
9980   "fchs"
9981   [(set_attr "type" "fsgn")
9982    (set_attr "mode" "XF")])
9983
9984 (define_insn "*abssf2_1"
9985   [(set (match_operand:SF 0 "register_operand" "=f")
9986         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9987   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9988   "fabs"
9989   [(set_attr "type" "fsgn")
9990    (set_attr "mode" "SF")])
9991
9992 (define_insn "*absdf2_1"
9993   [(set (match_operand:DF 0 "register_operand" "=f")
9994         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9995   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9996   "fabs"
9997   [(set_attr "type" "fsgn")
9998    (set_attr "mode" "DF")])
9999
10000 (define_insn "*absxf2_1"
10001   [(set (match_operand:XF 0 "register_operand" "=f")
10002         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10003   "TARGET_80387"
10004   "fabs"
10005   [(set_attr "type" "fsgn")
10006    (set_attr "mode" "DF")])
10007
10008 (define_insn "*negextendsfdf2"
10009   [(set (match_operand:DF 0 "register_operand" "=f")
10010         (neg:DF (float_extend:DF
10011                   (match_operand:SF 1 "register_operand" "0"))))]
10012   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10013   "fchs"
10014   [(set_attr "type" "fsgn")
10015    (set_attr "mode" "DF")])
10016
10017 (define_insn "*negextenddfxf2"
10018   [(set (match_operand:XF 0 "register_operand" "=f")
10019         (neg:XF (float_extend:XF
10020                   (match_operand:DF 1 "register_operand" "0"))))]
10021   "TARGET_80387"
10022   "fchs"
10023   [(set_attr "type" "fsgn")
10024    (set_attr "mode" "XF")])
10025
10026 (define_insn "*negextendsfxf2"
10027   [(set (match_operand:XF 0 "register_operand" "=f")
10028         (neg:XF (float_extend:XF
10029                   (match_operand:SF 1 "register_operand" "0"))))]
10030   "TARGET_80387"
10031   "fchs"
10032   [(set_attr "type" "fsgn")
10033    (set_attr "mode" "XF")])
10034
10035 (define_insn "*absextendsfdf2"
10036   [(set (match_operand:DF 0 "register_operand" "=f")
10037         (abs:DF (float_extend:DF
10038                   (match_operand:SF 1 "register_operand" "0"))))]
10039   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10040   "fabs"
10041   [(set_attr "type" "fsgn")
10042    (set_attr "mode" "DF")])
10043
10044 (define_insn "*absextenddfxf2"
10045   [(set (match_operand:XF 0 "register_operand" "=f")
10046         (abs:XF (float_extend:XF
10047           (match_operand:DF 1 "register_operand" "0"))))]
10048   "TARGET_80387"
10049   "fabs"
10050   [(set_attr "type" "fsgn")
10051    (set_attr "mode" "XF")])
10052
10053 (define_insn "*absextendsfxf2"
10054   [(set (match_operand:XF 0 "register_operand" "=f")
10055         (abs:XF (float_extend:XF
10056           (match_operand:SF 1 "register_operand" "0"))))]
10057   "TARGET_80387"
10058   "fabs"
10059   [(set_attr "type" "fsgn")
10060    (set_attr "mode" "XF")])
10061 \f
10062 ;; One complement instructions
10063
10064 (define_expand "one_cmpldi2"
10065   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10066         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10067   "TARGET_64BIT"
10068   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10069
10070 (define_insn "*one_cmpldi2_1_rex64"
10071   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10072         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10073   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10074   "not{q}\t%0"
10075   [(set_attr "type" "negnot")
10076    (set_attr "mode" "DI")])
10077
10078 (define_insn "*one_cmpldi2_2_rex64"
10079   [(set (reg FLAGS_REG)
10080         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10081                  (const_int 0)))
10082    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10083         (not:DI (match_dup 1)))]
10084   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10085    && ix86_unary_operator_ok (NOT, DImode, operands)"
10086   "#"
10087   [(set_attr "type" "alu1")
10088    (set_attr "mode" "DI")])
10089
10090 (define_split
10091   [(set (match_operand 0 "flags_reg_operand" "")
10092         (match_operator 2 "compare_operator"
10093           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10094            (const_int 0)]))
10095    (set (match_operand:DI 1 "nonimmediate_operand" "")
10096         (not:DI (match_dup 3)))]
10097   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10098   [(parallel [(set (match_dup 0)
10099                    (match_op_dup 2
10100                      [(xor:DI (match_dup 3) (const_int -1))
10101                       (const_int 0)]))
10102               (set (match_dup 1)
10103                    (xor:DI (match_dup 3) (const_int -1)))])]
10104   "")
10105
10106 (define_expand "one_cmplsi2"
10107   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10108         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10109   ""
10110   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10111
10112 (define_insn "*one_cmplsi2_1"
10113   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10114         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10115   "ix86_unary_operator_ok (NOT, SImode, operands)"
10116   "not{l}\t%0"
10117   [(set_attr "type" "negnot")
10118    (set_attr "mode" "SI")])
10119
10120 ;; ??? Currently never generated - xor is used instead.
10121 (define_insn "*one_cmplsi2_1_zext"
10122   [(set (match_operand:DI 0 "register_operand" "=r")
10123         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10124   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10125   "not{l}\t%k0"
10126   [(set_attr "type" "negnot")
10127    (set_attr "mode" "SI")])
10128
10129 (define_insn "*one_cmplsi2_2"
10130   [(set (reg FLAGS_REG)
10131         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10132                  (const_int 0)))
10133    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10134         (not:SI (match_dup 1)))]
10135   "ix86_match_ccmode (insn, CCNOmode)
10136    && ix86_unary_operator_ok (NOT, SImode, operands)"
10137   "#"
10138   [(set_attr "type" "alu1")
10139    (set_attr "mode" "SI")])
10140
10141 (define_split
10142   [(set (match_operand 0 "flags_reg_operand" "")
10143         (match_operator 2 "compare_operator"
10144           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10145            (const_int 0)]))
10146    (set (match_operand:SI 1 "nonimmediate_operand" "")
10147         (not:SI (match_dup 3)))]
10148   "ix86_match_ccmode (insn, CCNOmode)"
10149   [(parallel [(set (match_dup 0)
10150                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10151                                     (const_int 0)]))
10152               (set (match_dup 1)
10153                    (xor:SI (match_dup 3) (const_int -1)))])]
10154   "")
10155
10156 ;; ??? Currently never generated - xor is used instead.
10157 (define_insn "*one_cmplsi2_2_zext"
10158   [(set (reg FLAGS_REG)
10159         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10160                  (const_int 0)))
10161    (set (match_operand:DI 0 "register_operand" "=r")
10162         (zero_extend:DI (not:SI (match_dup 1))))]
10163   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10164    && ix86_unary_operator_ok (NOT, SImode, operands)"
10165   "#"
10166   [(set_attr "type" "alu1")
10167    (set_attr "mode" "SI")])
10168
10169 (define_split
10170   [(set (match_operand 0 "flags_reg_operand" "")
10171         (match_operator 2 "compare_operator"
10172           [(not:SI (match_operand:SI 3 "register_operand" ""))
10173            (const_int 0)]))
10174    (set (match_operand:DI 1 "register_operand" "")
10175         (zero_extend:DI (not:SI (match_dup 3))))]
10176   "ix86_match_ccmode (insn, CCNOmode)"
10177   [(parallel [(set (match_dup 0)
10178                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10179                                     (const_int 0)]))
10180               (set (match_dup 1)
10181                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10182   "")
10183
10184 (define_expand "one_cmplhi2"
10185   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10186         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10187   "TARGET_HIMODE_MATH"
10188   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10189
10190 (define_insn "*one_cmplhi2_1"
10191   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10192         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10193   "ix86_unary_operator_ok (NOT, HImode, operands)"
10194   "not{w}\t%0"
10195   [(set_attr "type" "negnot")
10196    (set_attr "mode" "HI")])
10197
10198 (define_insn "*one_cmplhi2_2"
10199   [(set (reg FLAGS_REG)
10200         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10201                  (const_int 0)))
10202    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10203         (not:HI (match_dup 1)))]
10204   "ix86_match_ccmode (insn, CCNOmode)
10205    && ix86_unary_operator_ok (NEG, HImode, operands)"
10206   "#"
10207   [(set_attr "type" "alu1")
10208    (set_attr "mode" "HI")])
10209
10210 (define_split
10211   [(set (match_operand 0 "flags_reg_operand" "")
10212         (match_operator 2 "compare_operator"
10213           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10214            (const_int 0)]))
10215    (set (match_operand:HI 1 "nonimmediate_operand" "")
10216         (not:HI (match_dup 3)))]
10217   "ix86_match_ccmode (insn, CCNOmode)"
10218   [(parallel [(set (match_dup 0)
10219                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10220                                     (const_int 0)]))
10221               (set (match_dup 1)
10222                    (xor:HI (match_dup 3) (const_int -1)))])]
10223   "")
10224
10225 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10226 (define_expand "one_cmplqi2"
10227   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10228         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10229   "TARGET_QIMODE_MATH"
10230   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10231
10232 (define_insn "*one_cmplqi2_1"
10233   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10234         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10235   "ix86_unary_operator_ok (NOT, QImode, operands)"
10236   "@
10237    not{b}\t%0
10238    not{l}\t%k0"
10239   [(set_attr "type" "negnot")
10240    (set_attr "mode" "QI,SI")])
10241
10242 (define_insn "*one_cmplqi2_2"
10243   [(set (reg FLAGS_REG)
10244         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10245                  (const_int 0)))
10246    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10247         (not:QI (match_dup 1)))]
10248   "ix86_match_ccmode (insn, CCNOmode)
10249    && ix86_unary_operator_ok (NOT, QImode, operands)"
10250   "#"
10251   [(set_attr "type" "alu1")
10252    (set_attr "mode" "QI")])
10253
10254 (define_split
10255   [(set (match_operand 0 "flags_reg_operand" "")
10256         (match_operator 2 "compare_operator"
10257           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10258            (const_int 0)]))
10259    (set (match_operand:QI 1 "nonimmediate_operand" "")
10260         (not:QI (match_dup 3)))]
10261   "ix86_match_ccmode (insn, CCNOmode)"
10262   [(parallel [(set (match_dup 0)
10263                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10264                                     (const_int 0)]))
10265               (set (match_dup 1)
10266                    (xor:QI (match_dup 3) (const_int -1)))])]
10267   "")
10268 \f
10269 ;; Arithmetic shift instructions
10270
10271 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10272 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10273 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10274 ;; from the assembler input.
10275 ;;
10276 ;; This instruction shifts the target reg/mem as usual, but instead of
10277 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10278 ;; is a left shift double, bits are taken from the high order bits of
10279 ;; reg, else if the insn is a shift right double, bits are taken from the
10280 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10281 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10282 ;;
10283 ;; Since sh[lr]d does not change the `reg' operand, that is done
10284 ;; separately, making all shifts emit pairs of shift double and normal
10285 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10286 ;; support a 63 bit shift, each shift where the count is in a reg expands
10287 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10288 ;;
10289 ;; If the shift count is a constant, we need never emit more than one
10290 ;; shift pair, instead using moves and sign extension for counts greater
10291 ;; than 31.
10292
10293 (define_expand "ashlti3"
10294   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10295                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10296                               (match_operand:QI 2 "nonmemory_operand" "")))
10297               (clobber (reg:CC FLAGS_REG))])]
10298   "TARGET_64BIT"
10299 {
10300   if (! immediate_operand (operands[2], QImode))
10301     {
10302       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10303       DONE;
10304     }
10305   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10306   DONE;
10307 })
10308
10309 (define_insn "ashlti3_1"
10310   [(set (match_operand:TI 0 "register_operand" "=r")
10311         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10312                    (match_operand:QI 2 "register_operand" "c")))
10313    (clobber (match_scratch:DI 3 "=&r"))
10314    (clobber (reg:CC FLAGS_REG))]
10315   "TARGET_64BIT"
10316   "#"
10317   [(set_attr "type" "multi")])
10318
10319 (define_insn "*ashlti3_2"
10320   [(set (match_operand:TI 0 "register_operand" "=r")
10321         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10322                    (match_operand:QI 2 "immediate_operand" "O")))
10323    (clobber (reg:CC FLAGS_REG))]
10324   "TARGET_64BIT"
10325   "#"
10326   [(set_attr "type" "multi")])
10327
10328 (define_split
10329   [(set (match_operand:TI 0 "register_operand" "")
10330         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10331                    (match_operand:QI 2 "register_operand" "")))
10332    (clobber (match_scratch:DI 3 ""))
10333    (clobber (reg:CC FLAGS_REG))]
10334   "TARGET_64BIT && reload_completed"
10335   [(const_int 0)]
10336   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10337
10338 (define_split
10339   [(set (match_operand:TI 0 "register_operand" "")
10340         (ashift:TI (match_operand:TI 1 "register_operand" "")
10341                    (match_operand:QI 2 "immediate_operand" "")))
10342    (clobber (reg:CC FLAGS_REG))]
10343   "TARGET_64BIT && reload_completed"
10344   [(const_int 0)]
10345   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10346
10347 (define_insn "x86_64_shld"
10348   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10349         (ior:DI (ashift:DI (match_dup 0)
10350                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10351                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10352                   (minus:QI (const_int 64) (match_dup 2)))))
10353    (clobber (reg:CC FLAGS_REG))]
10354   "TARGET_64BIT"
10355   "@
10356    shld{q}\t{%2, %1, %0|%0, %1, %2}
10357    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10358   [(set_attr "type" "ishift")
10359    (set_attr "prefix_0f" "1")
10360    (set_attr "mode" "DI")
10361    (set_attr "athlon_decode" "vector")])
10362
10363 (define_expand "x86_64_shift_adj"
10364   [(set (reg:CCZ FLAGS_REG)
10365         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10366                              (const_int 64))
10367                      (const_int 0)))
10368    (set (match_operand:DI 0 "register_operand" "")
10369         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10370                          (match_operand:DI 1 "register_operand" "")
10371                          (match_dup 0)))
10372    (set (match_dup 1)
10373         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10374                          (match_operand:DI 3 "register_operand" "r")
10375                          (match_dup 1)))]
10376   "TARGET_64BIT"
10377   "")
10378
10379 (define_expand "ashldi3"
10380   [(set (match_operand:DI 0 "shiftdi_operand" "")
10381         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10382                    (match_operand:QI 2 "nonmemory_operand" "")))]
10383   ""
10384   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10385
10386 (define_insn "*ashldi3_1_rex64"
10387   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10388         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10389                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10390    (clobber (reg:CC FLAGS_REG))]
10391   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10392 {
10393   switch (get_attr_type (insn))
10394     {
10395     case TYPE_ALU:
10396       gcc_assert (operands[2] == const1_rtx);
10397       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10398       return "add{q}\t{%0, %0|%0, %0}";
10399
10400     case TYPE_LEA:
10401       gcc_assert (CONST_INT_P (operands[2]));
10402       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10403       operands[1] = gen_rtx_MULT (DImode, operands[1],
10404                                   GEN_INT (1 << INTVAL (operands[2])));
10405       return "lea{q}\t{%a1, %0|%0, %a1}";
10406
10407     default:
10408       if (REG_P (operands[2]))
10409         return "sal{q}\t{%b2, %0|%0, %b2}";
10410       else if (operands[2] == const1_rtx
10411                && (TARGET_SHIFT1 || optimize_size))
10412         return "sal{q}\t%0";
10413       else
10414         return "sal{q}\t{%2, %0|%0, %2}";
10415     }
10416 }
10417   [(set (attr "type")
10418      (cond [(eq_attr "alternative" "1")
10419               (const_string "lea")
10420             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10421                           (const_int 0))
10422                       (match_operand 0 "register_operand" ""))
10423                  (match_operand 2 "const1_operand" ""))
10424               (const_string "alu")
10425            ]
10426            (const_string "ishift")))
10427    (set_attr "mode" "DI")])
10428
10429 ;; Convert lea to the lea pattern to avoid flags dependency.
10430 (define_split
10431   [(set (match_operand:DI 0 "register_operand" "")
10432         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10433                    (match_operand:QI 2 "immediate_operand" "")))
10434    (clobber (reg:CC FLAGS_REG))]
10435   "TARGET_64BIT && reload_completed
10436    && true_regnum (operands[0]) != true_regnum (operands[1])"
10437   [(set (match_dup 0)
10438         (mult:DI (match_dup 1)
10439                  (match_dup 2)))]
10440   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10441
10442 ;; This pattern can't accept a variable shift count, since shifts by
10443 ;; zero don't affect the flags.  We assume that shifts by constant
10444 ;; zero are optimized away.
10445 (define_insn "*ashldi3_cmp_rex64"
10446   [(set (reg FLAGS_REG)
10447         (compare
10448           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10449                      (match_operand:QI 2 "immediate_operand" "e"))
10450           (const_int 0)))
10451    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10452         (ashift:DI (match_dup 1) (match_dup 2)))]
10453   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10454    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10455    && (optimize_size
10456        || !TARGET_PARTIAL_FLAG_REG_STALL
10457        || (operands[2] == const1_rtx
10458            && (TARGET_SHIFT1
10459                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10460 {
10461   switch (get_attr_type (insn))
10462     {
10463     case TYPE_ALU:
10464       gcc_assert (operands[2] == const1_rtx);
10465       return "add{q}\t{%0, %0|%0, %0}";
10466
10467     default:
10468       if (REG_P (operands[2]))
10469         return "sal{q}\t{%b2, %0|%0, %b2}";
10470       else if (operands[2] == const1_rtx
10471                && (TARGET_SHIFT1 || optimize_size))
10472         return "sal{q}\t%0";
10473       else
10474         return "sal{q}\t{%2, %0|%0, %2}";
10475     }
10476 }
10477   [(set (attr "type")
10478      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10479                           (const_int 0))
10480                       (match_operand 0 "register_operand" ""))
10481                  (match_operand 2 "const1_operand" ""))
10482               (const_string "alu")
10483            ]
10484            (const_string "ishift")))
10485    (set_attr "mode" "DI")])
10486
10487 (define_insn "*ashldi3_cconly_rex64"
10488   [(set (reg FLAGS_REG)
10489         (compare
10490           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10491                      (match_operand:QI 2 "immediate_operand" "e"))
10492           (const_int 0)))
10493    (clobber (match_scratch:DI 0 "=r"))]
10494   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10495    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10496    && (optimize_size
10497        || !TARGET_PARTIAL_FLAG_REG_STALL
10498        || (operands[2] == const1_rtx
10499            && (TARGET_SHIFT1
10500                || TARGET_DOUBLE_WITH_ADD)))"
10501 {
10502   switch (get_attr_type (insn))
10503     {
10504     case TYPE_ALU:
10505       gcc_assert (operands[2] == const1_rtx);
10506       return "add{q}\t{%0, %0|%0, %0}";
10507
10508     default:
10509       if (REG_P (operands[2]))
10510         return "sal{q}\t{%b2, %0|%0, %b2}";
10511       else if (operands[2] == const1_rtx
10512                && (TARGET_SHIFT1 || optimize_size))
10513         return "sal{q}\t%0";
10514       else
10515         return "sal{q}\t{%2, %0|%0, %2}";
10516     }
10517 }
10518   [(set (attr "type")
10519      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10520                           (const_int 0))
10521                       (match_operand 0 "register_operand" ""))
10522                  (match_operand 2 "const1_operand" ""))
10523               (const_string "alu")
10524            ]
10525            (const_string "ishift")))
10526    (set_attr "mode" "DI")])
10527
10528 (define_insn "*ashldi3_1"
10529   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10530         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10531                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10532    (clobber (reg:CC FLAGS_REG))]
10533   "!TARGET_64BIT"
10534   "#"
10535   [(set_attr "type" "multi")])
10536
10537 ;; By default we don't ask for a scratch register, because when DImode
10538 ;; values are manipulated, registers are already at a premium.  But if
10539 ;; we have one handy, we won't turn it away.
10540 (define_peephole2
10541   [(match_scratch:SI 3 "r")
10542    (parallel [(set (match_operand:DI 0 "register_operand" "")
10543                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10544                               (match_operand:QI 2 "nonmemory_operand" "")))
10545               (clobber (reg:CC FLAGS_REG))])
10546    (match_dup 3)]
10547   "!TARGET_64BIT && TARGET_CMOVE"
10548   [(const_int 0)]
10549   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10550
10551 (define_split
10552   [(set (match_operand:DI 0 "register_operand" "")
10553         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10554                    (match_operand:QI 2 "nonmemory_operand" "")))
10555    (clobber (reg:CC FLAGS_REG))]
10556   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10557                      ? flow2_completed : reload_completed)"
10558   [(const_int 0)]
10559   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10560
10561 (define_insn "x86_shld_1"
10562   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10563         (ior:SI (ashift:SI (match_dup 0)
10564                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10565                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10566                   (minus:QI (const_int 32) (match_dup 2)))))
10567    (clobber (reg:CC FLAGS_REG))]
10568   ""
10569   "@
10570    shld{l}\t{%2, %1, %0|%0, %1, %2}
10571    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10572   [(set_attr "type" "ishift")
10573    (set_attr "prefix_0f" "1")
10574    (set_attr "mode" "SI")
10575    (set_attr "pent_pair" "np")
10576    (set_attr "athlon_decode" "vector")])
10577
10578 (define_expand "x86_shift_adj_1"
10579   [(set (reg:CCZ FLAGS_REG)
10580         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10581                              (const_int 32))
10582                      (const_int 0)))
10583    (set (match_operand:SI 0 "register_operand" "")
10584         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10585                          (match_operand:SI 1 "register_operand" "")
10586                          (match_dup 0)))
10587    (set (match_dup 1)
10588         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10589                          (match_operand:SI 3 "register_operand" "r")
10590                          (match_dup 1)))]
10591   "TARGET_CMOVE"
10592   "")
10593
10594 (define_expand "x86_shift_adj_2"
10595   [(use (match_operand:SI 0 "register_operand" ""))
10596    (use (match_operand:SI 1 "register_operand" ""))
10597    (use (match_operand:QI 2 "register_operand" ""))]
10598   ""
10599 {
10600   rtx label = gen_label_rtx ();
10601   rtx tmp;
10602
10603   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10604
10605   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10606   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10607   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10608                               gen_rtx_LABEL_REF (VOIDmode, label),
10609                               pc_rtx);
10610   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10611   JUMP_LABEL (tmp) = label;
10612
10613   emit_move_insn (operands[0], operands[1]);
10614   ix86_expand_clear (operands[1]);
10615
10616   emit_label (label);
10617   LABEL_NUSES (label) = 1;
10618
10619   DONE;
10620 })
10621
10622 (define_expand "ashlsi3"
10623   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10624         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10625                    (match_operand:QI 2 "nonmemory_operand" "")))
10626    (clobber (reg:CC FLAGS_REG))]
10627   ""
10628   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10629
10630 (define_insn "*ashlsi3_1"
10631   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10632         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10633                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10634    (clobber (reg:CC FLAGS_REG))]
10635   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10636 {
10637   switch (get_attr_type (insn))
10638     {
10639     case TYPE_ALU:
10640       gcc_assert (operands[2] == const1_rtx);
10641       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10642       return "add{l}\t{%0, %0|%0, %0}";
10643
10644     case TYPE_LEA:
10645       return "#";
10646
10647     default:
10648       if (REG_P (operands[2]))
10649         return "sal{l}\t{%b2, %0|%0, %b2}";
10650       else if (operands[2] == const1_rtx
10651                && (TARGET_SHIFT1 || optimize_size))
10652         return "sal{l}\t%0";
10653       else
10654         return "sal{l}\t{%2, %0|%0, %2}";
10655     }
10656 }
10657   [(set (attr "type")
10658      (cond [(eq_attr "alternative" "1")
10659               (const_string "lea")
10660             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10661                           (const_int 0))
10662                       (match_operand 0 "register_operand" ""))
10663                  (match_operand 2 "const1_operand" ""))
10664               (const_string "alu")
10665            ]
10666            (const_string "ishift")))
10667    (set_attr "mode" "SI")])
10668
10669 ;; Convert lea to the lea pattern to avoid flags dependency.
10670 (define_split
10671   [(set (match_operand 0 "register_operand" "")
10672         (ashift (match_operand 1 "index_register_operand" "")
10673                 (match_operand:QI 2 "const_int_operand" "")))
10674    (clobber (reg:CC FLAGS_REG))]
10675   "reload_completed
10676    && true_regnum (operands[0]) != true_regnum (operands[1])
10677    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10678   [(const_int 0)]
10679 {
10680   rtx pat;
10681   enum machine_mode mode = GET_MODE (operands[0]);
10682
10683   if (GET_MODE_SIZE (mode) < 4)
10684     operands[0] = gen_lowpart (SImode, operands[0]);
10685   if (mode != Pmode)
10686     operands[1] = gen_lowpart (Pmode, operands[1]);
10687   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10688
10689   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10690   if (Pmode != SImode)
10691     pat = gen_rtx_SUBREG (SImode, pat, 0);
10692   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10693   DONE;
10694 })
10695
10696 ;; Rare case of shifting RSP is handled by generating move and shift
10697 (define_split
10698   [(set (match_operand 0 "register_operand" "")
10699         (ashift (match_operand 1 "register_operand" "")
10700                 (match_operand:QI 2 "const_int_operand" "")))
10701    (clobber (reg:CC FLAGS_REG))]
10702   "reload_completed
10703    && true_regnum (operands[0]) != true_regnum (operands[1])"
10704   [(const_int 0)]
10705 {
10706   rtx pat, clob;
10707   emit_move_insn (operands[0], operands[1]);
10708   pat = gen_rtx_SET (VOIDmode, operands[0],
10709                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10710                                      operands[0], operands[2]));
10711   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10712   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10713   DONE;
10714 })
10715
10716 (define_insn "*ashlsi3_1_zext"
10717   [(set (match_operand:DI 0 "register_operand" "=r,r")
10718         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10719                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10720    (clobber (reg:CC FLAGS_REG))]
10721   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10722 {
10723   switch (get_attr_type (insn))
10724     {
10725     case TYPE_ALU:
10726       gcc_assert (operands[2] == const1_rtx);
10727       return "add{l}\t{%k0, %k0|%k0, %k0}";
10728
10729     case TYPE_LEA:
10730       return "#";
10731
10732     default:
10733       if (REG_P (operands[2]))
10734         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10735       else if (operands[2] == const1_rtx
10736                && (TARGET_SHIFT1 || optimize_size))
10737         return "sal{l}\t%k0";
10738       else
10739         return "sal{l}\t{%2, %k0|%k0, %2}";
10740     }
10741 }
10742   [(set (attr "type")
10743      (cond [(eq_attr "alternative" "1")
10744               (const_string "lea")
10745             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10746                      (const_int 0))
10747                  (match_operand 2 "const1_operand" ""))
10748               (const_string "alu")
10749            ]
10750            (const_string "ishift")))
10751    (set_attr "mode" "SI")])
10752
10753 ;; Convert lea to the lea pattern to avoid flags dependency.
10754 (define_split
10755   [(set (match_operand:DI 0 "register_operand" "")
10756         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10757                                 (match_operand:QI 2 "const_int_operand" ""))))
10758    (clobber (reg:CC FLAGS_REG))]
10759   "TARGET_64BIT && reload_completed
10760    && true_regnum (operands[0]) != true_regnum (operands[1])"
10761   [(set (match_dup 0) (zero_extend:DI
10762                         (subreg:SI (mult:SI (match_dup 1)
10763                                             (match_dup 2)) 0)))]
10764 {
10765   operands[1] = gen_lowpart (Pmode, operands[1]);
10766   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10767 })
10768
10769 ;; This pattern can't accept a variable shift count, since shifts by
10770 ;; zero don't affect the flags.  We assume that shifts by constant
10771 ;; zero are optimized away.
10772 (define_insn "*ashlsi3_cmp"
10773   [(set (reg FLAGS_REG)
10774         (compare
10775           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10776                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10777           (const_int 0)))
10778    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10779         (ashift:SI (match_dup 1) (match_dup 2)))]
10780   "ix86_match_ccmode (insn, CCGOCmode)
10781    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10782    && (optimize_size
10783        || !TARGET_PARTIAL_FLAG_REG_STALL
10784        || (operands[2] == const1_rtx
10785            && (TARGET_SHIFT1
10786                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10787 {
10788   switch (get_attr_type (insn))
10789     {
10790     case TYPE_ALU:
10791       gcc_assert (operands[2] == const1_rtx);
10792       return "add{l}\t{%0, %0|%0, %0}";
10793
10794     default:
10795       if (REG_P (operands[2]))
10796         return "sal{l}\t{%b2, %0|%0, %b2}";
10797       else if (operands[2] == const1_rtx
10798                && (TARGET_SHIFT1 || optimize_size))
10799         return "sal{l}\t%0";
10800       else
10801         return "sal{l}\t{%2, %0|%0, %2}";
10802     }
10803 }
10804   [(set (attr "type")
10805      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10806                           (const_int 0))
10807                       (match_operand 0 "register_operand" ""))
10808                  (match_operand 2 "const1_operand" ""))
10809               (const_string "alu")
10810            ]
10811            (const_string "ishift")))
10812    (set_attr "mode" "SI")])
10813
10814 (define_insn "*ashlsi3_cconly"
10815   [(set (reg FLAGS_REG)
10816         (compare
10817           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10818                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10819           (const_int 0)))
10820    (clobber (match_scratch:SI 0 "=r"))]
10821   "ix86_match_ccmode (insn, CCGOCmode)
10822    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10823    && (optimize_size
10824        || !TARGET_PARTIAL_FLAG_REG_STALL
10825        || (operands[2] == const1_rtx
10826            && (TARGET_SHIFT1
10827                || TARGET_DOUBLE_WITH_ADD)))"
10828 {
10829   switch (get_attr_type (insn))
10830     {
10831     case TYPE_ALU:
10832       gcc_assert (operands[2] == const1_rtx);
10833       return "add{l}\t{%0, %0|%0, %0}";
10834
10835     default:
10836       if (REG_P (operands[2]))
10837         return "sal{l}\t{%b2, %0|%0, %b2}";
10838       else if (operands[2] == const1_rtx
10839                && (TARGET_SHIFT1 || optimize_size))
10840         return "sal{l}\t%0";
10841       else
10842         return "sal{l}\t{%2, %0|%0, %2}";
10843     }
10844 }
10845   [(set (attr "type")
10846      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10847                           (const_int 0))
10848                       (match_operand 0 "register_operand" ""))
10849                  (match_operand 2 "const1_operand" ""))
10850               (const_string "alu")
10851            ]
10852            (const_string "ishift")))
10853    (set_attr "mode" "SI")])
10854
10855 (define_insn "*ashlsi3_cmp_zext"
10856   [(set (reg FLAGS_REG)
10857         (compare
10858           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10859                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10860           (const_int 0)))
10861    (set (match_operand:DI 0 "register_operand" "=r")
10862         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10863   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10864    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10865    && (optimize_size
10866        || !TARGET_PARTIAL_FLAG_REG_STALL
10867        || (operands[2] == const1_rtx
10868            && (TARGET_SHIFT1
10869                || TARGET_DOUBLE_WITH_ADD)))"
10870 {
10871   switch (get_attr_type (insn))
10872     {
10873     case TYPE_ALU:
10874       gcc_assert (operands[2] == const1_rtx);
10875       return "add{l}\t{%k0, %k0|%k0, %k0}";
10876
10877     default:
10878       if (REG_P (operands[2]))
10879         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10880       else if (operands[2] == const1_rtx
10881                && (TARGET_SHIFT1 || optimize_size))
10882         return "sal{l}\t%k0";
10883       else
10884         return "sal{l}\t{%2, %k0|%k0, %2}";
10885     }
10886 }
10887   [(set (attr "type")
10888      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10889                      (const_int 0))
10890                  (match_operand 2 "const1_operand" ""))
10891               (const_string "alu")
10892            ]
10893            (const_string "ishift")))
10894    (set_attr "mode" "SI")])
10895
10896 (define_expand "ashlhi3"
10897   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10898         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10899                    (match_operand:QI 2 "nonmemory_operand" "")))
10900    (clobber (reg:CC FLAGS_REG))]
10901   "TARGET_HIMODE_MATH"
10902   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10903
10904 (define_insn "*ashlhi3_1_lea"
10905   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10906         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10907                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10908    (clobber (reg:CC FLAGS_REG))]
10909   "!TARGET_PARTIAL_REG_STALL
10910    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10911 {
10912   switch (get_attr_type (insn))
10913     {
10914     case TYPE_LEA:
10915       return "#";
10916     case TYPE_ALU:
10917       gcc_assert (operands[2] == const1_rtx);
10918       return "add{w}\t{%0, %0|%0, %0}";
10919
10920     default:
10921       if (REG_P (operands[2]))
10922         return "sal{w}\t{%b2, %0|%0, %b2}";
10923       else if (operands[2] == const1_rtx
10924                && (TARGET_SHIFT1 || optimize_size))
10925         return "sal{w}\t%0";
10926       else
10927         return "sal{w}\t{%2, %0|%0, %2}";
10928     }
10929 }
10930   [(set (attr "type")
10931      (cond [(eq_attr "alternative" "1")
10932               (const_string "lea")
10933             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10934                           (const_int 0))
10935                       (match_operand 0 "register_operand" ""))
10936                  (match_operand 2 "const1_operand" ""))
10937               (const_string "alu")
10938            ]
10939            (const_string "ishift")))
10940    (set_attr "mode" "HI,SI")])
10941
10942 (define_insn "*ashlhi3_1"
10943   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10944         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10945                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10946    (clobber (reg:CC FLAGS_REG))]
10947   "TARGET_PARTIAL_REG_STALL
10948    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10949 {
10950   switch (get_attr_type (insn))
10951     {
10952     case TYPE_ALU:
10953       gcc_assert (operands[2] == const1_rtx);
10954       return "add{w}\t{%0, %0|%0, %0}";
10955
10956     default:
10957       if (REG_P (operands[2]))
10958         return "sal{w}\t{%b2, %0|%0, %b2}";
10959       else if (operands[2] == const1_rtx
10960                && (TARGET_SHIFT1 || optimize_size))
10961         return "sal{w}\t%0";
10962       else
10963         return "sal{w}\t{%2, %0|%0, %2}";
10964     }
10965 }
10966   [(set (attr "type")
10967      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10968                           (const_int 0))
10969                       (match_operand 0 "register_operand" ""))
10970                  (match_operand 2 "const1_operand" ""))
10971               (const_string "alu")
10972            ]
10973            (const_string "ishift")))
10974    (set_attr "mode" "HI")])
10975
10976 ;; This pattern can't accept a variable shift count, since shifts by
10977 ;; zero don't affect the flags.  We assume that shifts by constant
10978 ;; zero are optimized away.
10979 (define_insn "*ashlhi3_cmp"
10980   [(set (reg FLAGS_REG)
10981         (compare
10982           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10983                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10984           (const_int 0)))
10985    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10986         (ashift:HI (match_dup 1) (match_dup 2)))]
10987   "ix86_match_ccmode (insn, CCGOCmode)
10988    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10989    && (optimize_size
10990        || !TARGET_PARTIAL_FLAG_REG_STALL
10991        || (operands[2] == const1_rtx
10992            && (TARGET_SHIFT1
10993                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10994 {
10995   switch (get_attr_type (insn))
10996     {
10997     case TYPE_ALU:
10998       gcc_assert (operands[2] == const1_rtx);
10999       return "add{w}\t{%0, %0|%0, %0}";
11000
11001     default:
11002       if (REG_P (operands[2]))
11003         return "sal{w}\t{%b2, %0|%0, %b2}";
11004       else if (operands[2] == const1_rtx
11005                && (TARGET_SHIFT1 || optimize_size))
11006         return "sal{w}\t%0";
11007       else
11008         return "sal{w}\t{%2, %0|%0, %2}";
11009     }
11010 }
11011   [(set (attr "type")
11012      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11013                           (const_int 0))
11014                       (match_operand 0 "register_operand" ""))
11015                  (match_operand 2 "const1_operand" ""))
11016               (const_string "alu")
11017            ]
11018            (const_string "ishift")))
11019    (set_attr "mode" "HI")])
11020
11021 (define_insn "*ashlhi3_cconly"
11022   [(set (reg FLAGS_REG)
11023         (compare
11024           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11025                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11026           (const_int 0)))
11027    (clobber (match_scratch:HI 0 "=r"))]
11028   "ix86_match_ccmode (insn, CCGOCmode)
11029    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11030    && (optimize_size
11031        || !TARGET_PARTIAL_FLAG_REG_STALL
11032        || (operands[2] == const1_rtx
11033            && (TARGET_SHIFT1
11034                || TARGET_DOUBLE_WITH_ADD)))"
11035 {
11036   switch (get_attr_type (insn))
11037     {
11038     case TYPE_ALU:
11039       gcc_assert (operands[2] == const1_rtx);
11040       return "add{w}\t{%0, %0|%0, %0}";
11041
11042     default:
11043       if (REG_P (operands[2]))
11044         return "sal{w}\t{%b2, %0|%0, %b2}";
11045       else if (operands[2] == const1_rtx
11046                && (TARGET_SHIFT1 || optimize_size))
11047         return "sal{w}\t%0";
11048       else
11049         return "sal{w}\t{%2, %0|%0, %2}";
11050     }
11051 }
11052   [(set (attr "type")
11053      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11054                           (const_int 0))
11055                       (match_operand 0 "register_operand" ""))
11056                  (match_operand 2 "const1_operand" ""))
11057               (const_string "alu")
11058            ]
11059            (const_string "ishift")))
11060    (set_attr "mode" "HI")])
11061
11062 (define_expand "ashlqi3"
11063   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11064         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11065                    (match_operand:QI 2 "nonmemory_operand" "")))
11066    (clobber (reg:CC FLAGS_REG))]
11067   "TARGET_QIMODE_MATH"
11068   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11069
11070 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11071
11072 (define_insn "*ashlqi3_1_lea"
11073   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11074         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11075                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11076    (clobber (reg:CC FLAGS_REG))]
11077   "!TARGET_PARTIAL_REG_STALL
11078    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11079 {
11080   switch (get_attr_type (insn))
11081     {
11082     case TYPE_LEA:
11083       return "#";
11084     case TYPE_ALU:
11085       gcc_assert (operands[2] == const1_rtx);
11086       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11087         return "add{l}\t{%k0, %k0|%k0, %k0}";
11088       else
11089         return "add{b}\t{%0, %0|%0, %0}";
11090
11091     default:
11092       if (REG_P (operands[2]))
11093         {
11094           if (get_attr_mode (insn) == MODE_SI)
11095             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11096           else
11097             return "sal{b}\t{%b2, %0|%0, %b2}";
11098         }
11099       else if (operands[2] == const1_rtx
11100                && (TARGET_SHIFT1 || optimize_size))
11101         {
11102           if (get_attr_mode (insn) == MODE_SI)
11103             return "sal{l}\t%0";
11104           else
11105             return "sal{b}\t%0";
11106         }
11107       else
11108         {
11109           if (get_attr_mode (insn) == MODE_SI)
11110             return "sal{l}\t{%2, %k0|%k0, %2}";
11111           else
11112             return "sal{b}\t{%2, %0|%0, %2}";
11113         }
11114     }
11115 }
11116   [(set (attr "type")
11117      (cond [(eq_attr "alternative" "2")
11118               (const_string "lea")
11119             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11120                           (const_int 0))
11121                       (match_operand 0 "register_operand" ""))
11122                  (match_operand 2 "const1_operand" ""))
11123               (const_string "alu")
11124            ]
11125            (const_string "ishift")))
11126    (set_attr "mode" "QI,SI,SI")])
11127
11128 (define_insn "*ashlqi3_1"
11129   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11130         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11131                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11132    (clobber (reg:CC FLAGS_REG))]
11133   "TARGET_PARTIAL_REG_STALL
11134    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11135 {
11136   switch (get_attr_type (insn))
11137     {
11138     case TYPE_ALU:
11139       gcc_assert (operands[2] == const1_rtx);
11140       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11141         return "add{l}\t{%k0, %k0|%k0, %k0}";
11142       else
11143         return "add{b}\t{%0, %0|%0, %0}";
11144
11145     default:
11146       if (REG_P (operands[2]))
11147         {
11148           if (get_attr_mode (insn) == MODE_SI)
11149             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11150           else
11151             return "sal{b}\t{%b2, %0|%0, %b2}";
11152         }
11153       else if (operands[2] == const1_rtx
11154                && (TARGET_SHIFT1 || optimize_size))
11155         {
11156           if (get_attr_mode (insn) == MODE_SI)
11157             return "sal{l}\t%0";
11158           else
11159             return "sal{b}\t%0";
11160         }
11161       else
11162         {
11163           if (get_attr_mode (insn) == MODE_SI)
11164             return "sal{l}\t{%2, %k0|%k0, %2}";
11165           else
11166             return "sal{b}\t{%2, %0|%0, %2}";
11167         }
11168     }
11169 }
11170   [(set (attr "type")
11171      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11172                           (const_int 0))
11173                       (match_operand 0 "register_operand" ""))
11174                  (match_operand 2 "const1_operand" ""))
11175               (const_string "alu")
11176            ]
11177            (const_string "ishift")))
11178    (set_attr "mode" "QI,SI")])
11179
11180 ;; This pattern can't accept a variable shift count, since shifts by
11181 ;; zero don't affect the flags.  We assume that shifts by constant
11182 ;; zero are optimized away.
11183 (define_insn "*ashlqi3_cmp"
11184   [(set (reg FLAGS_REG)
11185         (compare
11186           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11187                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11188           (const_int 0)))
11189    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11190         (ashift:QI (match_dup 1) (match_dup 2)))]
11191   "ix86_match_ccmode (insn, CCGOCmode)
11192    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11193    && (optimize_size
11194        || !TARGET_PARTIAL_FLAG_REG_STALL
11195        || (operands[2] == const1_rtx
11196            && (TARGET_SHIFT1
11197                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11198 {
11199   switch (get_attr_type (insn))
11200     {
11201     case TYPE_ALU:
11202       gcc_assert (operands[2] == const1_rtx);
11203       return "add{b}\t{%0, %0|%0, %0}";
11204
11205     default:
11206       if (REG_P (operands[2]))
11207         return "sal{b}\t{%b2, %0|%0, %b2}";
11208       else if (operands[2] == const1_rtx
11209                && (TARGET_SHIFT1 || optimize_size))
11210         return "sal{b}\t%0";
11211       else
11212         return "sal{b}\t{%2, %0|%0, %2}";
11213     }
11214 }
11215   [(set (attr "type")
11216      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11217                           (const_int 0))
11218                       (match_operand 0 "register_operand" ""))
11219                  (match_operand 2 "const1_operand" ""))
11220               (const_string "alu")
11221            ]
11222            (const_string "ishift")))
11223    (set_attr "mode" "QI")])
11224
11225 (define_insn "*ashlqi3_cconly"
11226   [(set (reg FLAGS_REG)
11227         (compare
11228           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11229                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11230           (const_int 0)))
11231    (clobber (match_scratch:QI 0 "=q"))]
11232   "ix86_match_ccmode (insn, CCGOCmode)
11233    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11234    && (optimize_size
11235        || !TARGET_PARTIAL_FLAG_REG_STALL
11236        || (operands[2] == const1_rtx
11237            && (TARGET_SHIFT1
11238                || TARGET_DOUBLE_WITH_ADD)))"
11239 {
11240   switch (get_attr_type (insn))
11241     {
11242     case TYPE_ALU:
11243       gcc_assert (operands[2] == const1_rtx);
11244       return "add{b}\t{%0, %0|%0, %0}";
11245
11246     default:
11247       if (REG_P (operands[2]))
11248         return "sal{b}\t{%b2, %0|%0, %b2}";
11249       else if (operands[2] == const1_rtx
11250                && (TARGET_SHIFT1 || optimize_size))
11251         return "sal{b}\t%0";
11252       else
11253         return "sal{b}\t{%2, %0|%0, %2}";
11254     }
11255 }
11256   [(set (attr "type")
11257      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11258                           (const_int 0))
11259                       (match_operand 0 "register_operand" ""))
11260                  (match_operand 2 "const1_operand" ""))
11261               (const_string "alu")
11262            ]
11263            (const_string "ishift")))
11264    (set_attr "mode" "QI")])
11265
11266 ;; See comment above `ashldi3' about how this works.
11267
11268 (define_expand "ashrti3"
11269   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11270                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11271                                 (match_operand:QI 2 "nonmemory_operand" "")))
11272               (clobber (reg:CC FLAGS_REG))])]
11273   "TARGET_64BIT"
11274 {
11275   if (! immediate_operand (operands[2], QImode))
11276     {
11277       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11278       DONE;
11279     }
11280   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11281   DONE;
11282 })
11283
11284 (define_insn "ashrti3_1"
11285   [(set (match_operand:TI 0 "register_operand" "=r")
11286         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11287                      (match_operand:QI 2 "register_operand" "c")))
11288    (clobber (match_scratch:DI 3 "=&r"))
11289    (clobber (reg:CC FLAGS_REG))]
11290   "TARGET_64BIT"
11291   "#"
11292   [(set_attr "type" "multi")])
11293
11294 (define_insn "*ashrti3_2"
11295   [(set (match_operand:TI 0 "register_operand" "=r")
11296         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11297                      (match_operand:QI 2 "immediate_operand" "O")))
11298    (clobber (reg:CC FLAGS_REG))]
11299   "TARGET_64BIT"
11300   "#"
11301   [(set_attr "type" "multi")])
11302
11303 (define_split
11304   [(set (match_operand:TI 0 "register_operand" "")
11305         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11306                      (match_operand:QI 2 "register_operand" "")))
11307    (clobber (match_scratch:DI 3 ""))
11308    (clobber (reg:CC FLAGS_REG))]
11309   "TARGET_64BIT && reload_completed"
11310   [(const_int 0)]
11311   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11312
11313 (define_split
11314   [(set (match_operand:TI 0 "register_operand" "")
11315         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11316                      (match_operand:QI 2 "immediate_operand" "")))
11317    (clobber (reg:CC FLAGS_REG))]
11318   "TARGET_64BIT && reload_completed"
11319   [(const_int 0)]
11320   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11321
11322 (define_insn "x86_64_shrd"
11323   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11324         (ior:DI (ashiftrt:DI (match_dup 0)
11325                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11326                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11327                   (minus:QI (const_int 64) (match_dup 2)))))
11328    (clobber (reg:CC FLAGS_REG))]
11329   "TARGET_64BIT"
11330   "@
11331    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11332    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11333   [(set_attr "type" "ishift")
11334    (set_attr "prefix_0f" "1")
11335    (set_attr "mode" "DI")
11336    (set_attr "athlon_decode" "vector")])
11337
11338 (define_expand "ashrdi3"
11339   [(set (match_operand:DI 0 "shiftdi_operand" "")
11340         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11341                      (match_operand:QI 2 "nonmemory_operand" "")))]
11342   ""
11343   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11344
11345 (define_insn "*ashrdi3_63_rex64"
11346   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11347         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11348                      (match_operand:DI 2 "const_int_operand" "i,i")))
11349    (clobber (reg:CC FLAGS_REG))]
11350   "TARGET_64BIT && INTVAL (operands[2]) == 63
11351    && (TARGET_USE_CLTD || optimize_size)
11352    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11353   "@
11354    {cqto|cqo}
11355    sar{q}\t{%2, %0|%0, %2}"
11356   [(set_attr "type" "imovx,ishift")
11357    (set_attr "prefix_0f" "0,*")
11358    (set_attr "length_immediate" "0,*")
11359    (set_attr "modrm" "0,1")
11360    (set_attr "mode" "DI")])
11361
11362 (define_insn "*ashrdi3_1_one_bit_rex64"
11363   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11364         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11365                      (match_operand:QI 2 "const1_operand" "")))
11366    (clobber (reg:CC FLAGS_REG))]
11367   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11368    && (TARGET_SHIFT1 || optimize_size)"
11369   "sar{q}\t%0"
11370   [(set_attr "type" "ishift")
11371    (set (attr "length")
11372      (if_then_else (match_operand:DI 0 "register_operand" "")
11373         (const_string "2")
11374         (const_string "*")))])
11375
11376 (define_insn "*ashrdi3_1_rex64"
11377   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11378         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11379                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11380    (clobber (reg:CC FLAGS_REG))]
11381   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11382   "@
11383    sar{q}\t{%2, %0|%0, %2}
11384    sar{q}\t{%b2, %0|%0, %b2}"
11385   [(set_attr "type" "ishift")
11386    (set_attr "mode" "DI")])
11387
11388 ;; This pattern can't accept a variable shift count, since shifts by
11389 ;; zero don't affect the flags.  We assume that shifts by constant
11390 ;; zero are optimized away.
11391 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11392   [(set (reg FLAGS_REG)
11393         (compare
11394           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11395                        (match_operand:QI 2 "const1_operand" ""))
11396           (const_int 0)))
11397    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11398         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11399   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11400    && (TARGET_SHIFT1 || optimize_size)
11401    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11402   "sar{q}\t%0"
11403   [(set_attr "type" "ishift")
11404    (set (attr "length")
11405      (if_then_else (match_operand:DI 0 "register_operand" "")
11406         (const_string "2")
11407         (const_string "*")))])
11408
11409 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11410   [(set (reg FLAGS_REG)
11411         (compare
11412           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11413                        (match_operand:QI 2 "const1_operand" ""))
11414           (const_int 0)))
11415    (clobber (match_scratch:DI 0 "=r"))]
11416   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11417    && (TARGET_SHIFT1 || optimize_size)
11418    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11419   "sar{q}\t%0"
11420   [(set_attr "type" "ishift")
11421    (set_attr "length" "2")])
11422
11423 ;; This pattern can't accept a variable shift count, since shifts by
11424 ;; zero don't affect the flags.  We assume that shifts by constant
11425 ;; zero are optimized away.
11426 (define_insn "*ashrdi3_cmp_rex64"
11427   [(set (reg FLAGS_REG)
11428         (compare
11429           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11430                        (match_operand:QI 2 "const_int_operand" "n"))
11431           (const_int 0)))
11432    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11433         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11434   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11435    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11436    && (optimize_size
11437        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11438   "sar{q}\t{%2, %0|%0, %2}"
11439   [(set_attr "type" "ishift")
11440    (set_attr "mode" "DI")])
11441
11442 (define_insn "*ashrdi3_cconly_rex64"
11443   [(set (reg FLAGS_REG)
11444         (compare
11445           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11446                        (match_operand:QI 2 "const_int_operand" "n"))
11447           (const_int 0)))
11448    (clobber (match_scratch:DI 0 "=r"))]
11449   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11450    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11451    && (optimize_size
11452        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11453   "sar{q}\t{%2, %0|%0, %2}"
11454   [(set_attr "type" "ishift")
11455    (set_attr "mode" "DI")])
11456
11457 (define_insn "*ashrdi3_1"
11458   [(set (match_operand:DI 0 "register_operand" "=r")
11459         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11460                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11461    (clobber (reg:CC FLAGS_REG))]
11462   "!TARGET_64BIT"
11463   "#"
11464   [(set_attr "type" "multi")])
11465
11466 ;; By default we don't ask for a scratch register, because when DImode
11467 ;; values are manipulated, registers are already at a premium.  But if
11468 ;; we have one handy, we won't turn it away.
11469 (define_peephole2
11470   [(match_scratch:SI 3 "r")
11471    (parallel [(set (match_operand:DI 0 "register_operand" "")
11472                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11473                                 (match_operand:QI 2 "nonmemory_operand" "")))
11474               (clobber (reg:CC FLAGS_REG))])
11475    (match_dup 3)]
11476   "!TARGET_64BIT && TARGET_CMOVE"
11477   [(const_int 0)]
11478   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11479
11480 (define_split
11481   [(set (match_operand:DI 0 "register_operand" "")
11482         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11483                      (match_operand:QI 2 "nonmemory_operand" "")))
11484    (clobber (reg:CC FLAGS_REG))]
11485   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11486                      ? flow2_completed : reload_completed)"
11487   [(const_int 0)]
11488   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11489
11490 (define_insn "x86_shrd_1"
11491   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11492         (ior:SI (ashiftrt:SI (match_dup 0)
11493                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11494                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11495                   (minus:QI (const_int 32) (match_dup 2)))))
11496    (clobber (reg:CC FLAGS_REG))]
11497   ""
11498   "@
11499    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11500    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11501   [(set_attr "type" "ishift")
11502    (set_attr "prefix_0f" "1")
11503    (set_attr "pent_pair" "np")
11504    (set_attr "mode" "SI")])
11505
11506 (define_expand "x86_shift_adj_3"
11507   [(use (match_operand:SI 0 "register_operand" ""))
11508    (use (match_operand:SI 1 "register_operand" ""))
11509    (use (match_operand:QI 2 "register_operand" ""))]
11510   ""
11511 {
11512   rtx label = gen_label_rtx ();
11513   rtx tmp;
11514
11515   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11516
11517   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11518   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11519   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11520                               gen_rtx_LABEL_REF (VOIDmode, label),
11521                               pc_rtx);
11522   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11523   JUMP_LABEL (tmp) = label;
11524
11525   emit_move_insn (operands[0], operands[1]);
11526   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11527
11528   emit_label (label);
11529   LABEL_NUSES (label) = 1;
11530
11531   DONE;
11532 })
11533
11534 (define_insn "ashrsi3_31"
11535   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11536         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11537                      (match_operand:SI 2 "const_int_operand" "i,i")))
11538    (clobber (reg:CC FLAGS_REG))]
11539   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11540    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11541   "@
11542    {cltd|cdq}
11543    sar{l}\t{%2, %0|%0, %2}"
11544   [(set_attr "type" "imovx,ishift")
11545    (set_attr "prefix_0f" "0,*")
11546    (set_attr "length_immediate" "0,*")
11547    (set_attr "modrm" "0,1")
11548    (set_attr "mode" "SI")])
11549
11550 (define_insn "*ashrsi3_31_zext"
11551   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11552         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11553                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11554    (clobber (reg:CC FLAGS_REG))]
11555   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11556    && INTVAL (operands[2]) == 31
11557    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11558   "@
11559    {cltd|cdq}
11560    sar{l}\t{%2, %k0|%k0, %2}"
11561   [(set_attr "type" "imovx,ishift")
11562    (set_attr "prefix_0f" "0,*")
11563    (set_attr "length_immediate" "0,*")
11564    (set_attr "modrm" "0,1")
11565    (set_attr "mode" "SI")])
11566
11567 (define_expand "ashrsi3"
11568   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11569         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11570                      (match_operand:QI 2 "nonmemory_operand" "")))
11571    (clobber (reg:CC FLAGS_REG))]
11572   ""
11573   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11574
11575 (define_insn "*ashrsi3_1_one_bit"
11576   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11577         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11578                      (match_operand:QI 2 "const1_operand" "")))
11579    (clobber (reg:CC FLAGS_REG))]
11580   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11581    && (TARGET_SHIFT1 || optimize_size)"
11582   "sar{l}\t%0"
11583   [(set_attr "type" "ishift")
11584    (set (attr "length")
11585      (if_then_else (match_operand:SI 0 "register_operand" "")
11586         (const_string "2")
11587         (const_string "*")))])
11588
11589 (define_insn "*ashrsi3_1_one_bit_zext"
11590   [(set (match_operand:DI 0 "register_operand" "=r")
11591         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11592                                      (match_operand:QI 2 "const1_operand" ""))))
11593    (clobber (reg:CC FLAGS_REG))]
11594   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11595    && (TARGET_SHIFT1 || optimize_size)"
11596   "sar{l}\t%k0"
11597   [(set_attr "type" "ishift")
11598    (set_attr "length" "2")])
11599
11600 (define_insn "*ashrsi3_1"
11601   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11602         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11603                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11604    (clobber (reg:CC FLAGS_REG))]
11605   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11606   "@
11607    sar{l}\t{%2, %0|%0, %2}
11608    sar{l}\t{%b2, %0|%0, %b2}"
11609   [(set_attr "type" "ishift")
11610    (set_attr "mode" "SI")])
11611
11612 (define_insn "*ashrsi3_1_zext"
11613   [(set (match_operand:DI 0 "register_operand" "=r,r")
11614         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11615                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11616    (clobber (reg:CC FLAGS_REG))]
11617   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11618   "@
11619    sar{l}\t{%2, %k0|%k0, %2}
11620    sar{l}\t{%b2, %k0|%k0, %b2}"
11621   [(set_attr "type" "ishift")
11622    (set_attr "mode" "SI")])
11623
11624 ;; This pattern can't accept a variable shift count, since shifts by
11625 ;; zero don't affect the flags.  We assume that shifts by constant
11626 ;; zero are optimized away.
11627 (define_insn "*ashrsi3_one_bit_cmp"
11628   [(set (reg FLAGS_REG)
11629         (compare
11630           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11631                        (match_operand:QI 2 "const1_operand" ""))
11632           (const_int 0)))
11633    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11634         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11635   "ix86_match_ccmode (insn, CCGOCmode)
11636    && (TARGET_SHIFT1 || optimize_size)
11637    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11638   "sar{l}\t%0"
11639   [(set_attr "type" "ishift")
11640    (set (attr "length")
11641      (if_then_else (match_operand:SI 0 "register_operand" "")
11642         (const_string "2")
11643         (const_string "*")))])
11644
11645 (define_insn "*ashrsi3_one_bit_cconly"
11646   [(set (reg FLAGS_REG)
11647         (compare
11648           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11649                        (match_operand:QI 2 "const1_operand" ""))
11650           (const_int 0)))
11651    (clobber (match_scratch:SI 0 "=r"))]
11652   "ix86_match_ccmode (insn, CCGOCmode)
11653    && (TARGET_SHIFT1 || optimize_size)
11654    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11655   "sar{l}\t%0"
11656   [(set_attr "type" "ishift")
11657    (set_attr "length" "2")])
11658
11659 (define_insn "*ashrsi3_one_bit_cmp_zext"
11660   [(set (reg FLAGS_REG)
11661         (compare
11662           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11663                        (match_operand:QI 2 "const1_operand" ""))
11664           (const_int 0)))
11665    (set (match_operand:DI 0 "register_operand" "=r")
11666         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11667   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11668    && (TARGET_SHIFT1 || optimize_size)
11669    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11670   "sar{l}\t%k0"
11671   [(set_attr "type" "ishift")
11672    (set_attr "length" "2")])
11673
11674 ;; This pattern can't accept a variable shift count, since shifts by
11675 ;; zero don't affect the flags.  We assume that shifts by constant
11676 ;; zero are optimized away.
11677 (define_insn "*ashrsi3_cmp"
11678   [(set (reg FLAGS_REG)
11679         (compare
11680           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11681                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11682           (const_int 0)))
11683    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11684         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11685   "ix86_match_ccmode (insn, CCGOCmode)
11686    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11687    && (optimize_size
11688        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11689   "sar{l}\t{%2, %0|%0, %2}"
11690   [(set_attr "type" "ishift")
11691    (set_attr "mode" "SI")])
11692
11693 (define_insn "*ashrsi3_cconly"
11694   [(set (reg FLAGS_REG)
11695         (compare
11696           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11697                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11698           (const_int 0)))
11699    (clobber (match_scratch:SI 0 "=r"))]
11700   "ix86_match_ccmode (insn, CCGOCmode)
11701    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11702    && (optimize_size
11703        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11704   "sar{l}\t{%2, %0|%0, %2}"
11705   [(set_attr "type" "ishift")
11706    (set_attr "mode" "SI")])
11707
11708 (define_insn "*ashrsi3_cmp_zext"
11709   [(set (reg FLAGS_REG)
11710         (compare
11711           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11712                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11713           (const_int 0)))
11714    (set (match_operand:DI 0 "register_operand" "=r")
11715         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11716   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11717    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11718    && (optimize_size
11719        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11720   "sar{l}\t{%2, %k0|%k0, %2}"
11721   [(set_attr "type" "ishift")
11722    (set_attr "mode" "SI")])
11723
11724 (define_expand "ashrhi3"
11725   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11726         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11727                      (match_operand:QI 2 "nonmemory_operand" "")))
11728    (clobber (reg:CC FLAGS_REG))]
11729   "TARGET_HIMODE_MATH"
11730   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11731
11732 (define_insn "*ashrhi3_1_one_bit"
11733   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11734         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11735                      (match_operand:QI 2 "const1_operand" "")))
11736    (clobber (reg:CC FLAGS_REG))]
11737   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11738    && (TARGET_SHIFT1 || optimize_size)"
11739   "sar{w}\t%0"
11740   [(set_attr "type" "ishift")
11741    (set (attr "length")
11742      (if_then_else (match_operand 0 "register_operand" "")
11743         (const_string "2")
11744         (const_string "*")))])
11745
11746 (define_insn "*ashrhi3_1"
11747   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11748         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11749                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11750    (clobber (reg:CC FLAGS_REG))]
11751   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11752   "@
11753    sar{w}\t{%2, %0|%0, %2}
11754    sar{w}\t{%b2, %0|%0, %b2}"
11755   [(set_attr "type" "ishift")
11756    (set_attr "mode" "HI")])
11757
11758 ;; This pattern can't accept a variable shift count, since shifts by
11759 ;; zero don't affect the flags.  We assume that shifts by constant
11760 ;; zero are optimized away.
11761 (define_insn "*ashrhi3_one_bit_cmp"
11762   [(set (reg FLAGS_REG)
11763         (compare
11764           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11765                        (match_operand:QI 2 "const1_operand" ""))
11766           (const_int 0)))
11767    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11768         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11769   "ix86_match_ccmode (insn, CCGOCmode)
11770    && (TARGET_SHIFT1 || optimize_size)
11771    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11772   "sar{w}\t%0"
11773   [(set_attr "type" "ishift")
11774    (set (attr "length")
11775      (if_then_else (match_operand 0 "register_operand" "")
11776         (const_string "2")
11777         (const_string "*")))])
11778
11779 (define_insn "*ashrhi3_one_bit_cconly"
11780   [(set (reg FLAGS_REG)
11781         (compare
11782           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11783                        (match_operand:QI 2 "const1_operand" ""))
11784           (const_int 0)))
11785    (clobber (match_scratch:HI 0 "=r"))]
11786   "ix86_match_ccmode (insn, CCGOCmode)
11787    && (TARGET_SHIFT1 || optimize_size)
11788    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11789   "sar{w}\t%0"
11790   [(set_attr "type" "ishift")
11791    (set_attr "length" "2")])
11792
11793 ;; This pattern can't accept a variable shift count, since shifts by
11794 ;; zero don't affect the flags.  We assume that shifts by constant
11795 ;; zero are optimized away.
11796 (define_insn "*ashrhi3_cmp"
11797   [(set (reg FLAGS_REG)
11798         (compare
11799           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11800                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11801           (const_int 0)))
11802    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11803         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11804   "ix86_match_ccmode (insn, CCGOCmode)
11805    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11806    && (optimize_size
11807        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11808   "sar{w}\t{%2, %0|%0, %2}"
11809   [(set_attr "type" "ishift")
11810    (set_attr "mode" "HI")])
11811
11812 (define_insn "*ashrhi3_cconly"
11813   [(set (reg FLAGS_REG)
11814         (compare
11815           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11816                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11817           (const_int 0)))
11818    (clobber (match_scratch:HI 0 "=r"))]
11819   "ix86_match_ccmode (insn, CCGOCmode)
11820    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11821    && (optimize_size
11822        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11823   "sar{w}\t{%2, %0|%0, %2}"
11824   [(set_attr "type" "ishift")
11825    (set_attr "mode" "HI")])
11826
11827 (define_expand "ashrqi3"
11828   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11829         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11830                      (match_operand:QI 2 "nonmemory_operand" "")))
11831    (clobber (reg:CC FLAGS_REG))]
11832   "TARGET_QIMODE_MATH"
11833   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11834
11835 (define_insn "*ashrqi3_1_one_bit"
11836   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11837         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11838                      (match_operand:QI 2 "const1_operand" "")))
11839    (clobber (reg:CC FLAGS_REG))]
11840   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11841    && (TARGET_SHIFT1 || optimize_size)"
11842   "sar{b}\t%0"
11843   [(set_attr "type" "ishift")
11844    (set (attr "length")
11845      (if_then_else (match_operand 0 "register_operand" "")
11846         (const_string "2")
11847         (const_string "*")))])
11848
11849 (define_insn "*ashrqi3_1_one_bit_slp"
11850   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11851         (ashiftrt:QI (match_dup 0)
11852                      (match_operand:QI 1 "const1_operand" "")))
11853    (clobber (reg:CC FLAGS_REG))]
11854   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11855    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11856    && (TARGET_SHIFT1 || optimize_size)"
11857   "sar{b}\t%0"
11858   [(set_attr "type" "ishift1")
11859    (set (attr "length")
11860      (if_then_else (match_operand 0 "register_operand" "")
11861         (const_string "2")
11862         (const_string "*")))])
11863
11864 (define_insn "*ashrqi3_1"
11865   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11866         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11867                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11868    (clobber (reg:CC FLAGS_REG))]
11869   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11870   "@
11871    sar{b}\t{%2, %0|%0, %2}
11872    sar{b}\t{%b2, %0|%0, %b2}"
11873   [(set_attr "type" "ishift")
11874    (set_attr "mode" "QI")])
11875
11876 (define_insn "*ashrqi3_1_slp"
11877   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11878         (ashiftrt:QI (match_dup 0)
11879                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11880    (clobber (reg:CC FLAGS_REG))]
11881   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11882    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11883   "@
11884    sar{b}\t{%1, %0|%0, %1}
11885    sar{b}\t{%b1, %0|%0, %b1}"
11886   [(set_attr "type" "ishift1")
11887    (set_attr "mode" "QI")])
11888
11889 ;; This pattern can't accept a variable shift count, since shifts by
11890 ;; zero don't affect the flags.  We assume that shifts by constant
11891 ;; zero are optimized away.
11892 (define_insn "*ashrqi3_one_bit_cmp"
11893   [(set (reg FLAGS_REG)
11894         (compare
11895           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11896                        (match_operand:QI 2 "const1_operand" "I"))
11897           (const_int 0)))
11898    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11899         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11900   "ix86_match_ccmode (insn, CCGOCmode)
11901    && (TARGET_SHIFT1 || optimize_size)
11902    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11903   "sar{b}\t%0"
11904   [(set_attr "type" "ishift")
11905    (set (attr "length")
11906      (if_then_else (match_operand 0 "register_operand" "")
11907         (const_string "2")
11908         (const_string "*")))])
11909
11910 (define_insn "*ashrqi3_one_bit_cconly"
11911   [(set (reg FLAGS_REG)
11912         (compare
11913           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11914                        (match_operand:QI 2 "const1_operand" "I"))
11915           (const_int 0)))
11916    (clobber (match_scratch:QI 0 "=q"))]
11917   "ix86_match_ccmode (insn, CCGOCmode)
11918    && (TARGET_SHIFT1 || optimize_size)
11919    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11920   "sar{b}\t%0"
11921   [(set_attr "type" "ishift")
11922    (set_attr "length" "2")])
11923
11924 ;; This pattern can't accept a variable shift count, since shifts by
11925 ;; zero don't affect the flags.  We assume that shifts by constant
11926 ;; zero are optimized away.
11927 (define_insn "*ashrqi3_cmp"
11928   [(set (reg FLAGS_REG)
11929         (compare
11930           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11931                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11932           (const_int 0)))
11933    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11934         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11935   "ix86_match_ccmode (insn, CCGOCmode)
11936    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11937    && (optimize_size
11938        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11939   "sar{b}\t{%2, %0|%0, %2}"
11940   [(set_attr "type" "ishift")
11941    (set_attr "mode" "QI")])
11942
11943 (define_insn "*ashrqi3_cconly"
11944   [(set (reg FLAGS_REG)
11945         (compare
11946           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11947                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11948           (const_int 0)))
11949    (clobber (match_scratch:QI 0 "=q"))]
11950   "ix86_match_ccmode (insn, CCGOCmode)
11951    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11952    && (optimize_size
11953        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11954   "sar{b}\t{%2, %0|%0, %2}"
11955   [(set_attr "type" "ishift")
11956    (set_attr "mode" "QI")])
11957
11958 \f
11959 ;; Logical shift instructions
11960
11961 ;; See comment above `ashldi3' about how this works.
11962
11963 (define_expand "lshrti3"
11964   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11965                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11966                                 (match_operand:QI 2 "nonmemory_operand" "")))
11967               (clobber (reg:CC FLAGS_REG))])]
11968   "TARGET_64BIT"
11969 {
11970   if (! immediate_operand (operands[2], QImode))
11971     {
11972       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11973       DONE;
11974     }
11975   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11976   DONE;
11977 })
11978
11979 (define_insn "lshrti3_1"
11980   [(set (match_operand:TI 0 "register_operand" "=r")
11981         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11982                      (match_operand:QI 2 "register_operand" "c")))
11983    (clobber (match_scratch:DI 3 "=&r"))
11984    (clobber (reg:CC FLAGS_REG))]
11985   "TARGET_64BIT"
11986   "#"
11987   [(set_attr "type" "multi")])
11988
11989 (define_insn "*lshrti3_2"
11990   [(set (match_operand:TI 0 "register_operand" "=r")
11991         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11992                      (match_operand:QI 2 "immediate_operand" "O")))
11993    (clobber (reg:CC FLAGS_REG))]
11994   "TARGET_64BIT"
11995   "#"
11996   [(set_attr "type" "multi")])
11997
11998 (define_split
11999   [(set (match_operand:TI 0 "register_operand" "")
12000         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12001                      (match_operand:QI 2 "register_operand" "")))
12002    (clobber (match_scratch:DI 3 ""))
12003    (clobber (reg:CC FLAGS_REG))]
12004   "TARGET_64BIT && reload_completed"
12005   [(const_int 0)]
12006   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12007
12008 (define_split
12009   [(set (match_operand:TI 0 "register_operand" "")
12010         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12011                      (match_operand:QI 2 "immediate_operand" "")))
12012    (clobber (reg:CC FLAGS_REG))]
12013   "TARGET_64BIT && reload_completed"
12014   [(const_int 0)]
12015   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12016
12017 (define_expand "lshrdi3"
12018   [(set (match_operand:DI 0 "shiftdi_operand" "")
12019         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12020                      (match_operand:QI 2 "nonmemory_operand" "")))]
12021   ""
12022   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12023
12024 (define_insn "*lshrdi3_1_one_bit_rex64"
12025   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12026         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12027                      (match_operand:QI 2 "const1_operand" "")))
12028    (clobber (reg:CC FLAGS_REG))]
12029   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12030    && (TARGET_SHIFT1 || optimize_size)"
12031   "shr{q}\t%0"
12032   [(set_attr "type" "ishift")
12033    (set (attr "length")
12034      (if_then_else (match_operand:DI 0 "register_operand" "")
12035         (const_string "2")
12036         (const_string "*")))])
12037
12038 (define_insn "*lshrdi3_1_rex64"
12039   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12040         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12041                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12042    (clobber (reg:CC FLAGS_REG))]
12043   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12044   "@
12045    shr{q}\t{%2, %0|%0, %2}
12046    shr{q}\t{%b2, %0|%0, %b2}"
12047   [(set_attr "type" "ishift")
12048    (set_attr "mode" "DI")])
12049
12050 ;; This pattern can't accept a variable shift count, since shifts by
12051 ;; zero don't affect the flags.  We assume that shifts by constant
12052 ;; zero are optimized away.
12053 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12054   [(set (reg FLAGS_REG)
12055         (compare
12056           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12057                        (match_operand:QI 2 "const1_operand" ""))
12058           (const_int 0)))
12059    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12060         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12061   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12062    && (TARGET_SHIFT1 || optimize_size)
12063    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12064   "shr{q}\t%0"
12065   [(set_attr "type" "ishift")
12066    (set (attr "length")
12067      (if_then_else (match_operand:DI 0 "register_operand" "")
12068         (const_string "2")
12069         (const_string "*")))])
12070
12071 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12072   [(set (reg FLAGS_REG)
12073         (compare
12074           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12075                        (match_operand:QI 2 "const1_operand" ""))
12076           (const_int 0)))
12077    (clobber (match_scratch:DI 0 "=r"))]
12078   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12079    && (TARGET_SHIFT1 || optimize_size)
12080    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12081   "shr{q}\t%0"
12082   [(set_attr "type" "ishift")
12083    (set_attr "length" "2")])
12084
12085 ;; This pattern can't accept a variable shift count, since shifts by
12086 ;; zero don't affect the flags.  We assume that shifts by constant
12087 ;; zero are optimized away.
12088 (define_insn "*lshrdi3_cmp_rex64"
12089   [(set (reg FLAGS_REG)
12090         (compare
12091           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12092                        (match_operand:QI 2 "const_int_operand" "e"))
12093           (const_int 0)))
12094    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12095         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12096   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12097    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12098    && (optimize_size
12099        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12100   "shr{q}\t{%2, %0|%0, %2}"
12101   [(set_attr "type" "ishift")
12102    (set_attr "mode" "DI")])
12103
12104 (define_insn "*lshrdi3_cconly_rex64"
12105   [(set (reg FLAGS_REG)
12106         (compare
12107           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12108                        (match_operand:QI 2 "const_int_operand" "e"))
12109           (const_int 0)))
12110    (clobber (match_scratch:DI 0 "=r"))]
12111   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12112    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12113    && (optimize_size
12114        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12115   "shr{q}\t{%2, %0|%0, %2}"
12116   [(set_attr "type" "ishift")
12117    (set_attr "mode" "DI")])
12118
12119 (define_insn "*lshrdi3_1"
12120   [(set (match_operand:DI 0 "register_operand" "=r")
12121         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12122                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12123    (clobber (reg:CC FLAGS_REG))]
12124   "!TARGET_64BIT"
12125   "#"
12126   [(set_attr "type" "multi")])
12127
12128 ;; By default we don't ask for a scratch register, because when DImode
12129 ;; values are manipulated, registers are already at a premium.  But if
12130 ;; we have one handy, we won't turn it away.
12131 (define_peephole2
12132   [(match_scratch:SI 3 "r")
12133    (parallel [(set (match_operand:DI 0 "register_operand" "")
12134                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12135                                 (match_operand:QI 2 "nonmemory_operand" "")))
12136               (clobber (reg:CC FLAGS_REG))])
12137    (match_dup 3)]
12138   "!TARGET_64BIT && TARGET_CMOVE"
12139   [(const_int 0)]
12140   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12141
12142 (define_split
12143   [(set (match_operand:DI 0 "register_operand" "")
12144         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12145                      (match_operand:QI 2 "nonmemory_operand" "")))
12146    (clobber (reg:CC FLAGS_REG))]
12147   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12148                      ? flow2_completed : reload_completed)"
12149   [(const_int 0)]
12150   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12151
12152 (define_expand "lshrsi3"
12153   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12154         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12155                      (match_operand:QI 2 "nonmemory_operand" "")))
12156    (clobber (reg:CC FLAGS_REG))]
12157   ""
12158   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12159
12160 (define_insn "*lshrsi3_1_one_bit"
12161   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12162         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12163                      (match_operand:QI 2 "const1_operand" "")))
12164    (clobber (reg:CC FLAGS_REG))]
12165   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12166    && (TARGET_SHIFT1 || optimize_size)"
12167   "shr{l}\t%0"
12168   [(set_attr "type" "ishift")
12169    (set (attr "length")
12170      (if_then_else (match_operand:SI 0 "register_operand" "")
12171         (const_string "2")
12172         (const_string "*")))])
12173
12174 (define_insn "*lshrsi3_1_one_bit_zext"
12175   [(set (match_operand:DI 0 "register_operand" "=r")
12176         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12177                      (match_operand:QI 2 "const1_operand" "")))
12178    (clobber (reg:CC FLAGS_REG))]
12179   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12180    && (TARGET_SHIFT1 || optimize_size)"
12181   "shr{l}\t%k0"
12182   [(set_attr "type" "ishift")
12183    (set_attr "length" "2")])
12184
12185 (define_insn "*lshrsi3_1"
12186   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12187         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12188                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12189    (clobber (reg:CC FLAGS_REG))]
12190   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12191   "@
12192    shr{l}\t{%2, %0|%0, %2}
12193    shr{l}\t{%b2, %0|%0, %b2}"
12194   [(set_attr "type" "ishift")
12195    (set_attr "mode" "SI")])
12196
12197 (define_insn "*lshrsi3_1_zext"
12198   [(set (match_operand:DI 0 "register_operand" "=r,r")
12199         (zero_extend:DI
12200           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12201                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12202    (clobber (reg:CC FLAGS_REG))]
12203   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12204   "@
12205    shr{l}\t{%2, %k0|%k0, %2}
12206    shr{l}\t{%b2, %k0|%k0, %b2}"
12207   [(set_attr "type" "ishift")
12208    (set_attr "mode" "SI")])
12209
12210 ;; This pattern can't accept a variable shift count, since shifts by
12211 ;; zero don't affect the flags.  We assume that shifts by constant
12212 ;; zero are optimized away.
12213 (define_insn "*lshrsi3_one_bit_cmp"
12214   [(set (reg FLAGS_REG)
12215         (compare
12216           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12217                        (match_operand:QI 2 "const1_operand" ""))
12218           (const_int 0)))
12219    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12220         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12221   "ix86_match_ccmode (insn, CCGOCmode)
12222    && (TARGET_SHIFT1 || optimize_size)
12223    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12224   "shr{l}\t%0"
12225   [(set_attr "type" "ishift")
12226    (set (attr "length")
12227      (if_then_else (match_operand:SI 0 "register_operand" "")
12228         (const_string "2")
12229         (const_string "*")))])
12230
12231 (define_insn "*lshrsi3_one_bit_cconly"
12232   [(set (reg FLAGS_REG)
12233         (compare
12234           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12235                        (match_operand:QI 2 "const1_operand" ""))
12236           (const_int 0)))
12237    (clobber (match_scratch:SI 0 "=r"))]
12238   "ix86_match_ccmode (insn, CCGOCmode)
12239    && (TARGET_SHIFT1 || optimize_size)
12240    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12241   "shr{l}\t%0"
12242   [(set_attr "type" "ishift")
12243    (set_attr "length" "2")])
12244
12245 (define_insn "*lshrsi3_cmp_one_bit_zext"
12246   [(set (reg FLAGS_REG)
12247         (compare
12248           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12249                        (match_operand:QI 2 "const1_operand" ""))
12250           (const_int 0)))
12251    (set (match_operand:DI 0 "register_operand" "=r")
12252         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12253   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12254    && (TARGET_SHIFT1 || optimize_size)
12255    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12256   "shr{l}\t%k0"
12257   [(set_attr "type" "ishift")
12258    (set_attr "length" "2")])
12259
12260 ;; This pattern can't accept a variable shift count, since shifts by
12261 ;; zero don't affect the flags.  We assume that shifts by constant
12262 ;; zero are optimized away.
12263 (define_insn "*lshrsi3_cmp"
12264   [(set (reg FLAGS_REG)
12265         (compare
12266           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12267                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12268           (const_int 0)))
12269    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12270         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12271   "ix86_match_ccmode (insn, CCGOCmode)
12272    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12273    && (optimize_size
12274        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12275   "shr{l}\t{%2, %0|%0, %2}"
12276   [(set_attr "type" "ishift")
12277    (set_attr "mode" "SI")])
12278
12279 (define_insn "*lshrsi3_cconly"
12280   [(set (reg FLAGS_REG)
12281       (compare
12282         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12283                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12284         (const_int 0)))
12285    (clobber (match_scratch:SI 0 "=r"))]
12286   "ix86_match_ccmode (insn, CCGOCmode)
12287    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12288    && (optimize_size
12289        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12290   "shr{l}\t{%2, %0|%0, %2}"
12291   [(set_attr "type" "ishift")
12292    (set_attr "mode" "SI")])
12293
12294 (define_insn "*lshrsi3_cmp_zext"
12295   [(set (reg FLAGS_REG)
12296         (compare
12297           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12298                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12299           (const_int 0)))
12300    (set (match_operand:DI 0 "register_operand" "=r")
12301         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12302   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12303    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12304    && (optimize_size
12305        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12306   "shr{l}\t{%2, %k0|%k0, %2}"
12307   [(set_attr "type" "ishift")
12308    (set_attr "mode" "SI")])
12309
12310 (define_expand "lshrhi3"
12311   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12312         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12313                      (match_operand:QI 2 "nonmemory_operand" "")))
12314    (clobber (reg:CC FLAGS_REG))]
12315   "TARGET_HIMODE_MATH"
12316   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12317
12318 (define_insn "*lshrhi3_1_one_bit"
12319   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12320         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12321                      (match_operand:QI 2 "const1_operand" "")))
12322    (clobber (reg:CC FLAGS_REG))]
12323   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12324    && (TARGET_SHIFT1 || optimize_size)"
12325   "shr{w}\t%0"
12326   [(set_attr "type" "ishift")
12327    (set (attr "length")
12328      (if_then_else (match_operand 0 "register_operand" "")
12329         (const_string "2")
12330         (const_string "*")))])
12331
12332 (define_insn "*lshrhi3_1"
12333   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12334         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12335                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12336    (clobber (reg:CC FLAGS_REG))]
12337   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12338   "@
12339    shr{w}\t{%2, %0|%0, %2}
12340    shr{w}\t{%b2, %0|%0, %b2}"
12341   [(set_attr "type" "ishift")
12342    (set_attr "mode" "HI")])
12343
12344 ;; This pattern can't accept a variable shift count, since shifts by
12345 ;; zero don't affect the flags.  We assume that shifts by constant
12346 ;; zero are optimized away.
12347 (define_insn "*lshrhi3_one_bit_cmp"
12348   [(set (reg FLAGS_REG)
12349         (compare
12350           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12351                        (match_operand:QI 2 "const1_operand" ""))
12352           (const_int 0)))
12353    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12354         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12355   "ix86_match_ccmode (insn, CCGOCmode)
12356    && (TARGET_SHIFT1 || optimize_size)
12357    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12358   "shr{w}\t%0"
12359   [(set_attr "type" "ishift")
12360    (set (attr "length")
12361      (if_then_else (match_operand:SI 0 "register_operand" "")
12362         (const_string "2")
12363         (const_string "*")))])
12364
12365 (define_insn "*lshrhi3_one_bit_cconly"
12366   [(set (reg FLAGS_REG)
12367         (compare
12368           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12369                        (match_operand:QI 2 "const1_operand" ""))
12370           (const_int 0)))
12371    (clobber (match_scratch:HI 0 "=r"))]
12372   "ix86_match_ccmode (insn, CCGOCmode)
12373    && (TARGET_SHIFT1 || optimize_size)
12374    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12375   "shr{w}\t%0"
12376   [(set_attr "type" "ishift")
12377    (set_attr "length" "2")])
12378
12379 ;; This pattern can't accept a variable shift count, since shifts by
12380 ;; zero don't affect the flags.  We assume that shifts by constant
12381 ;; zero are optimized away.
12382 (define_insn "*lshrhi3_cmp"
12383   [(set (reg FLAGS_REG)
12384         (compare
12385           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12386                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12387           (const_int 0)))
12388    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12389         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12390   "ix86_match_ccmode (insn, CCGOCmode)
12391    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12392    && (optimize_size
12393        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12394   "shr{w}\t{%2, %0|%0, %2}"
12395   [(set_attr "type" "ishift")
12396    (set_attr "mode" "HI")])
12397
12398 (define_insn "*lshrhi3_cconly"
12399   [(set (reg FLAGS_REG)
12400         (compare
12401           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12402                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12403           (const_int 0)))
12404    (clobber (match_scratch:HI 0 "=r"))]
12405   "ix86_match_ccmode (insn, CCGOCmode)
12406    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12407    && (optimize_size
12408        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12409   "shr{w}\t{%2, %0|%0, %2}"
12410   [(set_attr "type" "ishift")
12411    (set_attr "mode" "HI")])
12412
12413 (define_expand "lshrqi3"
12414   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12415         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12416                      (match_operand:QI 2 "nonmemory_operand" "")))
12417    (clobber (reg:CC FLAGS_REG))]
12418   "TARGET_QIMODE_MATH"
12419   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12420
12421 (define_insn "*lshrqi3_1_one_bit"
12422   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12423         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12424                      (match_operand:QI 2 "const1_operand" "")))
12425    (clobber (reg:CC FLAGS_REG))]
12426   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12427    && (TARGET_SHIFT1 || optimize_size)"
12428   "shr{b}\t%0"
12429   [(set_attr "type" "ishift")
12430    (set (attr "length")
12431      (if_then_else (match_operand 0 "register_operand" "")
12432         (const_string "2")
12433         (const_string "*")))])
12434
12435 (define_insn "*lshrqi3_1_one_bit_slp"
12436   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12437         (lshiftrt:QI (match_dup 0)
12438                      (match_operand:QI 1 "const1_operand" "")))
12439    (clobber (reg:CC FLAGS_REG))]
12440   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12441    && (TARGET_SHIFT1 || optimize_size)"
12442   "shr{b}\t%0"
12443   [(set_attr "type" "ishift1")
12444    (set (attr "length")
12445      (if_then_else (match_operand 0 "register_operand" "")
12446         (const_string "2")
12447         (const_string "*")))])
12448
12449 (define_insn "*lshrqi3_1"
12450   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12451         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12452                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12453    (clobber (reg:CC FLAGS_REG))]
12454   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12455   "@
12456    shr{b}\t{%2, %0|%0, %2}
12457    shr{b}\t{%b2, %0|%0, %b2}"
12458   [(set_attr "type" "ishift")
12459    (set_attr "mode" "QI")])
12460
12461 (define_insn "*lshrqi3_1_slp"
12462   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12463         (lshiftrt:QI (match_dup 0)
12464                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12465    (clobber (reg:CC FLAGS_REG))]
12466   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12467    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12468   "@
12469    shr{b}\t{%1, %0|%0, %1}
12470    shr{b}\t{%b1, %0|%0, %b1}"
12471   [(set_attr "type" "ishift1")
12472    (set_attr "mode" "QI")])
12473
12474 ;; This pattern can't accept a variable shift count, since shifts by
12475 ;; zero don't affect the flags.  We assume that shifts by constant
12476 ;; zero are optimized away.
12477 (define_insn "*lshrqi2_one_bit_cmp"
12478   [(set (reg FLAGS_REG)
12479         (compare
12480           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12481                        (match_operand:QI 2 "const1_operand" ""))
12482           (const_int 0)))
12483    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12484         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12485   "ix86_match_ccmode (insn, CCGOCmode)
12486    && (TARGET_SHIFT1 || optimize_size)
12487    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12488   "shr{b}\t%0"
12489   [(set_attr "type" "ishift")
12490    (set (attr "length")
12491      (if_then_else (match_operand:SI 0 "register_operand" "")
12492         (const_string "2")
12493         (const_string "*")))])
12494
12495 (define_insn "*lshrqi2_one_bit_cconly"
12496   [(set (reg FLAGS_REG)
12497         (compare
12498           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12499                        (match_operand:QI 2 "const1_operand" ""))
12500           (const_int 0)))
12501    (clobber (match_scratch:QI 0 "=q"))]
12502   "ix86_match_ccmode (insn, CCGOCmode)
12503    && (TARGET_SHIFT1 || optimize_size)
12504    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12505   "shr{b}\t%0"
12506   [(set_attr "type" "ishift")
12507    (set_attr "length" "2")])
12508
12509 ;; This pattern can't accept a variable shift count, since shifts by
12510 ;; zero don't affect the flags.  We assume that shifts by constant
12511 ;; zero are optimized away.
12512 (define_insn "*lshrqi2_cmp"
12513   [(set (reg FLAGS_REG)
12514         (compare
12515           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12516                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12517           (const_int 0)))
12518    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12519         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12520   "ix86_match_ccmode (insn, CCGOCmode)
12521    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12522    && (optimize_size
12523        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12524   "shr{b}\t{%2, %0|%0, %2}"
12525   [(set_attr "type" "ishift")
12526    (set_attr "mode" "QI")])
12527
12528 (define_insn "*lshrqi2_cconly"
12529   [(set (reg FLAGS_REG)
12530         (compare
12531           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12532                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12533           (const_int 0)))
12534    (clobber (match_scratch:QI 0 "=q"))]
12535   "ix86_match_ccmode (insn, CCGOCmode)
12536    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12537    && (optimize_size
12538        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12539   "shr{b}\t{%2, %0|%0, %2}"
12540   [(set_attr "type" "ishift")
12541    (set_attr "mode" "QI")])
12542 \f
12543 ;; Rotate instructions
12544
12545 (define_expand "rotldi3"
12546   [(set (match_operand:DI 0 "shiftdi_operand" "")
12547         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12548                    (match_operand:QI 2 "nonmemory_operand" "")))
12549    (clobber (reg:CC FLAGS_REG))]
12550  ""
12551 {
12552   if (TARGET_64BIT)
12553     {
12554       ix86_expand_binary_operator (ROTATE, DImode, operands);
12555       DONE;
12556     }
12557   if (!const_1_to_31_operand (operands[2], VOIDmode))
12558     FAIL;
12559   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12560   DONE;
12561 })
12562
12563 ;; Implement rotation using two double-precision shift instructions
12564 ;; and a scratch register.
12565 (define_insn_and_split "ix86_rotldi3"
12566  [(set (match_operand:DI 0 "register_operand" "=r")
12567        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12568                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12569   (clobber (reg:CC FLAGS_REG))
12570   (clobber (match_scratch:SI 3 "=&r"))]
12571  "!TARGET_64BIT"
12572  ""
12573  "&& reload_completed"
12574  [(set (match_dup 3) (match_dup 4))
12575   (parallel
12576    [(set (match_dup 4)
12577          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12578                  (lshiftrt:SI (match_dup 5)
12579                               (minus:QI (const_int 32) (match_dup 2)))))
12580     (clobber (reg:CC FLAGS_REG))])
12581   (parallel
12582    [(set (match_dup 5)
12583          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12584                  (lshiftrt:SI (match_dup 3)
12585                               (minus:QI (const_int 32) (match_dup 2)))))
12586     (clobber (reg:CC FLAGS_REG))])]
12587  "split_di (operands, 1, operands + 4, operands + 5);")
12588
12589 (define_insn "*rotlsi3_1_one_bit_rex64"
12590   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12591         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12592                    (match_operand:QI 2 "const1_operand" "")))
12593    (clobber (reg:CC FLAGS_REG))]
12594   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12595    && (TARGET_SHIFT1 || optimize_size)"
12596   "rol{q}\t%0"
12597   [(set_attr "type" "rotate")
12598    (set (attr "length")
12599      (if_then_else (match_operand:DI 0 "register_operand" "")
12600         (const_string "2")
12601         (const_string "*")))])
12602
12603 (define_insn "*rotldi3_1_rex64"
12604   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12605         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12606                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12607    (clobber (reg:CC FLAGS_REG))]
12608   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12609   "@
12610    rol{q}\t{%2, %0|%0, %2}
12611    rol{q}\t{%b2, %0|%0, %b2}"
12612   [(set_attr "type" "rotate")
12613    (set_attr "mode" "DI")])
12614
12615 (define_expand "rotlsi3"
12616   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12617         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12618                    (match_operand:QI 2 "nonmemory_operand" "")))
12619    (clobber (reg:CC FLAGS_REG))]
12620   ""
12621   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12622
12623 (define_insn "*rotlsi3_1_one_bit"
12624   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12625         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12626                    (match_operand:QI 2 "const1_operand" "")))
12627    (clobber (reg:CC FLAGS_REG))]
12628   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12629    && (TARGET_SHIFT1 || optimize_size)"
12630   "rol{l}\t%0"
12631   [(set_attr "type" "rotate")
12632    (set (attr "length")
12633      (if_then_else (match_operand:SI 0 "register_operand" "")
12634         (const_string "2")
12635         (const_string "*")))])
12636
12637 (define_insn "*rotlsi3_1_one_bit_zext"
12638   [(set (match_operand:DI 0 "register_operand" "=r")
12639         (zero_extend:DI
12640           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12641                      (match_operand:QI 2 "const1_operand" ""))))
12642    (clobber (reg:CC FLAGS_REG))]
12643   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12644    && (TARGET_SHIFT1 || optimize_size)"
12645   "rol{l}\t%k0"
12646   [(set_attr "type" "rotate")
12647    (set_attr "length" "2")])
12648
12649 (define_insn "*rotlsi3_1"
12650   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12651         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12652                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12653    (clobber (reg:CC FLAGS_REG))]
12654   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12655   "@
12656    rol{l}\t{%2, %0|%0, %2}
12657    rol{l}\t{%b2, %0|%0, %b2}"
12658   [(set_attr "type" "rotate")
12659    (set_attr "mode" "SI")])
12660
12661 (define_insn "*rotlsi3_1_zext"
12662   [(set (match_operand:DI 0 "register_operand" "=r,r")
12663         (zero_extend:DI
12664           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12665                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12666    (clobber (reg:CC FLAGS_REG))]
12667   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12668   "@
12669    rol{l}\t{%2, %k0|%k0, %2}
12670    rol{l}\t{%b2, %k0|%k0, %b2}"
12671   [(set_attr "type" "rotate")
12672    (set_attr "mode" "SI")])
12673
12674 (define_expand "rotlhi3"
12675   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12676         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12677                    (match_operand:QI 2 "nonmemory_operand" "")))
12678    (clobber (reg:CC FLAGS_REG))]
12679   "TARGET_HIMODE_MATH"
12680   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12681
12682 (define_insn "*rotlhi3_1_one_bit"
12683   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12684         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12685                    (match_operand:QI 2 "const1_operand" "")))
12686    (clobber (reg:CC FLAGS_REG))]
12687   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12688    && (TARGET_SHIFT1 || optimize_size)"
12689   "rol{w}\t%0"
12690   [(set_attr "type" "rotate")
12691    (set (attr "length")
12692      (if_then_else (match_operand 0 "register_operand" "")
12693         (const_string "2")
12694         (const_string "*")))])
12695
12696 (define_insn "*rotlhi3_1"
12697   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12698         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12699                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12700    (clobber (reg:CC FLAGS_REG))]
12701   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12702   "@
12703    rol{w}\t{%2, %0|%0, %2}
12704    rol{w}\t{%b2, %0|%0, %b2}"
12705   [(set_attr "type" "rotate")
12706    (set_attr "mode" "HI")])
12707
12708 (define_expand "rotlqi3"
12709   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12710         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12711                    (match_operand:QI 2 "nonmemory_operand" "")))
12712    (clobber (reg:CC FLAGS_REG))]
12713   "TARGET_QIMODE_MATH"
12714   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12715
12716 (define_insn "*rotlqi3_1_one_bit_slp"
12717   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12718         (rotate:QI (match_dup 0)
12719                    (match_operand:QI 1 "const1_operand" "")))
12720    (clobber (reg:CC FLAGS_REG))]
12721   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12722    && (TARGET_SHIFT1 || optimize_size)"
12723   "rol{b}\t%0"
12724   [(set_attr "type" "rotate1")
12725    (set (attr "length")
12726      (if_then_else (match_operand 0 "register_operand" "")
12727         (const_string "2")
12728         (const_string "*")))])
12729
12730 (define_insn "*rotlqi3_1_one_bit"
12731   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12732         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12733                    (match_operand:QI 2 "const1_operand" "")))
12734    (clobber (reg:CC FLAGS_REG))]
12735   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12736    && (TARGET_SHIFT1 || optimize_size)"
12737   "rol{b}\t%0"
12738   [(set_attr "type" "rotate")
12739    (set (attr "length")
12740      (if_then_else (match_operand 0 "register_operand" "")
12741         (const_string "2")
12742         (const_string "*")))])
12743
12744 (define_insn "*rotlqi3_1_slp"
12745   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12746         (rotate:QI (match_dup 0)
12747                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12748    (clobber (reg:CC FLAGS_REG))]
12749   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12750    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12751   "@
12752    rol{b}\t{%1, %0|%0, %1}
12753    rol{b}\t{%b1, %0|%0, %b1}"
12754   [(set_attr "type" "rotate1")
12755    (set_attr "mode" "QI")])
12756
12757 (define_insn "*rotlqi3_1"
12758   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12759         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12760                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12761    (clobber (reg:CC FLAGS_REG))]
12762   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12763   "@
12764    rol{b}\t{%2, %0|%0, %2}
12765    rol{b}\t{%b2, %0|%0, %b2}"
12766   [(set_attr "type" "rotate")
12767    (set_attr "mode" "QI")])
12768
12769 (define_expand "rotrdi3"
12770   [(set (match_operand:DI 0 "shiftdi_operand" "")
12771         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12772                    (match_operand:QI 2 "nonmemory_operand" "")))
12773    (clobber (reg:CC FLAGS_REG))]
12774  ""
12775 {
12776   if (TARGET_64BIT)
12777     {
12778       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12779       DONE;
12780     }
12781   if (!const_1_to_31_operand (operands[2], VOIDmode))
12782     FAIL;
12783   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12784   DONE;
12785 })
12786
12787 ;; Implement rotation using two double-precision shift instructions
12788 ;; and a scratch register.
12789 (define_insn_and_split "ix86_rotrdi3"
12790  [(set (match_operand:DI 0 "register_operand" "=r")
12791        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12792                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12793   (clobber (reg:CC FLAGS_REG))
12794   (clobber (match_scratch:SI 3 "=&r"))]
12795  "!TARGET_64BIT"
12796  ""
12797  "&& reload_completed"
12798  [(set (match_dup 3) (match_dup 4))
12799   (parallel
12800    [(set (match_dup 4)
12801          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12802                  (ashift:SI (match_dup 5)
12803                             (minus:QI (const_int 32) (match_dup 2)))))
12804     (clobber (reg:CC FLAGS_REG))])
12805   (parallel
12806    [(set (match_dup 5)
12807          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12808                  (ashift:SI (match_dup 3)
12809                             (minus:QI (const_int 32) (match_dup 2)))))
12810     (clobber (reg:CC FLAGS_REG))])]
12811  "split_di (operands, 1, operands + 4, operands + 5);")
12812
12813 (define_insn "*rotrdi3_1_one_bit_rex64"
12814   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12815         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12816                      (match_operand:QI 2 "const1_operand" "")))
12817    (clobber (reg:CC FLAGS_REG))]
12818   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12819    && (TARGET_SHIFT1 || optimize_size)"
12820   "ror{q}\t%0"
12821   [(set_attr "type" "rotate")
12822    (set (attr "length")
12823      (if_then_else (match_operand:DI 0 "register_operand" "")
12824         (const_string "2")
12825         (const_string "*")))])
12826
12827 (define_insn "*rotrdi3_1_rex64"
12828   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12829         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12830                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12831    (clobber (reg:CC FLAGS_REG))]
12832   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12833   "@
12834    ror{q}\t{%2, %0|%0, %2}
12835    ror{q}\t{%b2, %0|%0, %b2}"
12836   [(set_attr "type" "rotate")
12837    (set_attr "mode" "DI")])
12838
12839 (define_expand "rotrsi3"
12840   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12841         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12842                      (match_operand:QI 2 "nonmemory_operand" "")))
12843    (clobber (reg:CC FLAGS_REG))]
12844   ""
12845   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12846
12847 (define_insn "*rotrsi3_1_one_bit"
12848   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12849         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12850                      (match_operand:QI 2 "const1_operand" "")))
12851    (clobber (reg:CC FLAGS_REG))]
12852   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12853    && (TARGET_SHIFT1 || optimize_size)"
12854   "ror{l}\t%0"
12855   [(set_attr "type" "rotate")
12856    (set (attr "length")
12857      (if_then_else (match_operand:SI 0 "register_operand" "")
12858         (const_string "2")
12859         (const_string "*")))])
12860
12861 (define_insn "*rotrsi3_1_one_bit_zext"
12862   [(set (match_operand:DI 0 "register_operand" "=r")
12863         (zero_extend:DI
12864           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12865                        (match_operand:QI 2 "const1_operand" ""))))
12866    (clobber (reg:CC FLAGS_REG))]
12867   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12868    && (TARGET_SHIFT1 || optimize_size)"
12869   "ror{l}\t%k0"
12870   [(set_attr "type" "rotate")
12871    (set (attr "length")
12872      (if_then_else (match_operand:SI 0 "register_operand" "")
12873         (const_string "2")
12874         (const_string "*")))])
12875
12876 (define_insn "*rotrsi3_1"
12877   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12878         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12879                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12880    (clobber (reg:CC FLAGS_REG))]
12881   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12882   "@
12883    ror{l}\t{%2, %0|%0, %2}
12884    ror{l}\t{%b2, %0|%0, %b2}"
12885   [(set_attr "type" "rotate")
12886    (set_attr "mode" "SI")])
12887
12888 (define_insn "*rotrsi3_1_zext"
12889   [(set (match_operand:DI 0 "register_operand" "=r,r")
12890         (zero_extend:DI
12891           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12892                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12893    (clobber (reg:CC FLAGS_REG))]
12894   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12895   "@
12896    ror{l}\t{%2, %k0|%k0, %2}
12897    ror{l}\t{%b2, %k0|%k0, %b2}"
12898   [(set_attr "type" "rotate")
12899    (set_attr "mode" "SI")])
12900
12901 (define_expand "rotrhi3"
12902   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12903         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12904                      (match_operand:QI 2 "nonmemory_operand" "")))
12905    (clobber (reg:CC FLAGS_REG))]
12906   "TARGET_HIMODE_MATH"
12907   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12908
12909 (define_insn "*rotrhi3_one_bit"
12910   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12911         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12912                      (match_operand:QI 2 "const1_operand" "")))
12913    (clobber (reg:CC FLAGS_REG))]
12914   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12915    && (TARGET_SHIFT1 || optimize_size)"
12916   "ror{w}\t%0"
12917   [(set_attr "type" "rotate")
12918    (set (attr "length")
12919      (if_then_else (match_operand 0 "register_operand" "")
12920         (const_string "2")
12921         (const_string "*")))])
12922
12923 (define_insn "*rotrhi3"
12924   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12925         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12926                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12927    (clobber (reg:CC FLAGS_REG))]
12928   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12929   "@
12930    ror{w}\t{%2, %0|%0, %2}
12931    ror{w}\t{%b2, %0|%0, %b2}"
12932   [(set_attr "type" "rotate")
12933    (set_attr "mode" "HI")])
12934
12935 (define_expand "rotrqi3"
12936   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12937         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12938                      (match_operand:QI 2 "nonmemory_operand" "")))
12939    (clobber (reg:CC FLAGS_REG))]
12940   "TARGET_QIMODE_MATH"
12941   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12942
12943 (define_insn "*rotrqi3_1_one_bit"
12944   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12945         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12946                      (match_operand:QI 2 "const1_operand" "")))
12947    (clobber (reg:CC FLAGS_REG))]
12948   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12949    && (TARGET_SHIFT1 || optimize_size)"
12950   "ror{b}\t%0"
12951   [(set_attr "type" "rotate")
12952    (set (attr "length")
12953      (if_then_else (match_operand 0 "register_operand" "")
12954         (const_string "2")
12955         (const_string "*")))])
12956
12957 (define_insn "*rotrqi3_1_one_bit_slp"
12958   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12959         (rotatert:QI (match_dup 0)
12960                      (match_operand:QI 1 "const1_operand" "")))
12961    (clobber (reg:CC FLAGS_REG))]
12962   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12963    && (TARGET_SHIFT1 || optimize_size)"
12964   "ror{b}\t%0"
12965   [(set_attr "type" "rotate1")
12966    (set (attr "length")
12967      (if_then_else (match_operand 0 "register_operand" "")
12968         (const_string "2")
12969         (const_string "*")))])
12970
12971 (define_insn "*rotrqi3_1"
12972   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12973         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12974                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12975    (clobber (reg:CC FLAGS_REG))]
12976   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12977   "@
12978    ror{b}\t{%2, %0|%0, %2}
12979    ror{b}\t{%b2, %0|%0, %b2}"
12980   [(set_attr "type" "rotate")
12981    (set_attr "mode" "QI")])
12982
12983 (define_insn "*rotrqi3_1_slp"
12984   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12985         (rotatert:QI (match_dup 0)
12986                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12987    (clobber (reg:CC FLAGS_REG))]
12988   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12989    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12990   "@
12991    ror{b}\t{%1, %0|%0, %1}
12992    ror{b}\t{%b1, %0|%0, %b1}"
12993   [(set_attr "type" "rotate1")
12994    (set_attr "mode" "QI")])
12995 \f
12996 ;; Bit set / bit test instructions
12997
12998 (define_expand "extv"
12999   [(set (match_operand:SI 0 "register_operand" "")
13000         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13001                          (match_operand:SI 2 "const8_operand" "")
13002                          (match_operand:SI 3 "const8_operand" "")))]
13003   ""
13004 {
13005   /* Handle extractions from %ah et al.  */
13006   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13007     FAIL;
13008
13009   /* From mips.md: extract_bit_field doesn't verify that our source
13010      matches the predicate, so check it again here.  */
13011   if (! ext_register_operand (operands[1], VOIDmode))
13012     FAIL;
13013 })
13014
13015 (define_expand "extzv"
13016   [(set (match_operand:SI 0 "register_operand" "")
13017         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13018                          (match_operand:SI 2 "const8_operand" "")
13019                          (match_operand:SI 3 "const8_operand" "")))]
13020   ""
13021 {
13022   /* Handle extractions from %ah et al.  */
13023   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13024     FAIL;
13025
13026   /* From mips.md: extract_bit_field doesn't verify that our source
13027      matches the predicate, so check it again here.  */
13028   if (! ext_register_operand (operands[1], VOIDmode))
13029     FAIL;
13030 })
13031
13032 (define_expand "insv"
13033   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13034                       (match_operand 1 "const8_operand" "")
13035                       (match_operand 2 "const8_operand" ""))
13036         (match_operand 3 "register_operand" ""))]
13037   ""
13038 {
13039   /* Handle insertions to %ah et al.  */
13040   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13041     FAIL;
13042
13043   /* From mips.md: insert_bit_field doesn't verify that our source
13044      matches the predicate, so check it again here.  */
13045   if (! ext_register_operand (operands[0], VOIDmode))
13046     FAIL;
13047
13048   if (TARGET_64BIT)
13049     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13050   else
13051     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13052
13053   DONE;
13054 })
13055
13056 ;; %%% bts, btr, btc, bt.
13057 ;; In general these instructions are *slow* when applied to memory,
13058 ;; since they enforce atomic operation.  When applied to registers,
13059 ;; it depends on the cpu implementation.  They're never faster than
13060 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13061 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13062 ;; within the instruction itself, so operating on bits in the high
13063 ;; 32-bits of a register becomes easier.
13064 ;;
13065 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13066 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13067 ;; negdf respectively, so they can never be disabled entirely.
13068
13069 (define_insn "*btsq"
13070   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13071                          (const_int 1)
13072                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13073         (const_int 1))
13074    (clobber (reg:CC FLAGS_REG))]
13075   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13076   "bts{q} %1,%0"
13077   [(set_attr "type" "alu1")])
13078
13079 (define_insn "*btrq"
13080   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13081                          (const_int 1)
13082                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13083         (const_int 0))
13084    (clobber (reg:CC FLAGS_REG))]
13085   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13086   "btr{q} %1,%0"
13087   [(set_attr "type" "alu1")])
13088
13089 (define_insn "*btcq"
13090   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13091                          (const_int 1)
13092                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13093         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13094    (clobber (reg:CC FLAGS_REG))]
13095   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13096   "btc{q} %1,%0"
13097   [(set_attr "type" "alu1")])
13098
13099 ;; Allow Nocona to avoid these instructions if a register is available.
13100
13101 (define_peephole2
13102   [(match_scratch:DI 2 "r")
13103    (parallel [(set (zero_extract:DI
13104                      (match_operand:DI 0 "register_operand" "")
13105                      (const_int 1)
13106                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13107                    (const_int 1))
13108               (clobber (reg:CC FLAGS_REG))])]
13109   "TARGET_64BIT && !TARGET_USE_BT"
13110   [(const_int 0)]
13111 {
13112   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13113   rtx op1;
13114
13115   if (HOST_BITS_PER_WIDE_INT >= 64)
13116     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13117   else if (i < HOST_BITS_PER_WIDE_INT)
13118     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13119   else
13120     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13121
13122   op1 = immed_double_const (lo, hi, DImode);
13123   if (i >= 31)
13124     {
13125       emit_move_insn (operands[2], op1);
13126       op1 = operands[2];
13127     }
13128
13129   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13130   DONE;
13131 })
13132
13133 (define_peephole2
13134   [(match_scratch:DI 2 "r")
13135    (parallel [(set (zero_extract:DI
13136                      (match_operand:DI 0 "register_operand" "")
13137                      (const_int 1)
13138                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13139                    (const_int 0))
13140               (clobber (reg:CC FLAGS_REG))])]
13141   "TARGET_64BIT && !TARGET_USE_BT"
13142   [(const_int 0)]
13143 {
13144   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13145   rtx op1;
13146
13147   if (HOST_BITS_PER_WIDE_INT >= 64)
13148     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13149   else if (i < HOST_BITS_PER_WIDE_INT)
13150     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13151   else
13152     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13153
13154   op1 = immed_double_const (~lo, ~hi, DImode);
13155   if (i >= 32)
13156     {
13157       emit_move_insn (operands[2], op1);
13158       op1 = operands[2];
13159     }
13160
13161   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13162   DONE;
13163 })
13164
13165 (define_peephole2
13166   [(match_scratch:DI 2 "r")
13167    (parallel [(set (zero_extract:DI
13168                      (match_operand:DI 0 "register_operand" "")
13169                      (const_int 1)
13170                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13171               (not:DI (zero_extract:DI
13172                         (match_dup 0) (const_int 1) (match_dup 1))))
13173               (clobber (reg:CC FLAGS_REG))])]
13174   "TARGET_64BIT && !TARGET_USE_BT"
13175   [(const_int 0)]
13176 {
13177   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13178   rtx op1;
13179
13180   if (HOST_BITS_PER_WIDE_INT >= 64)
13181     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13182   else if (i < HOST_BITS_PER_WIDE_INT)
13183     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13184   else
13185     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13186
13187   op1 = immed_double_const (lo, hi, DImode);
13188   if (i >= 31)
13189     {
13190       emit_move_insn (operands[2], op1);
13191       op1 = operands[2];
13192     }
13193
13194   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13195   DONE;
13196 })
13197 \f
13198 ;; Store-flag instructions.
13199
13200 ;; For all sCOND expanders, also expand the compare or test insn that
13201 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13202
13203 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13204 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13205 ;; way, which can later delete the movzx if only QImode is needed.
13206
13207 (define_expand "seq"
13208   [(set (match_operand:QI 0 "register_operand" "")
13209         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13210   ""
13211   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13212
13213 (define_expand "sne"
13214   [(set (match_operand:QI 0 "register_operand" "")
13215         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13216   ""
13217   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13218
13219 (define_expand "sgt"
13220   [(set (match_operand:QI 0 "register_operand" "")
13221         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13222   ""
13223   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13224
13225 (define_expand "sgtu"
13226   [(set (match_operand:QI 0 "register_operand" "")
13227         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13228   ""
13229   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13230
13231 (define_expand "slt"
13232   [(set (match_operand:QI 0 "register_operand" "")
13233         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13234   ""
13235   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13236
13237 (define_expand "sltu"
13238   [(set (match_operand:QI 0 "register_operand" "")
13239         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13240   ""
13241   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13242
13243 (define_expand "sge"
13244   [(set (match_operand:QI 0 "register_operand" "")
13245         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13246   ""
13247   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13248
13249 (define_expand "sgeu"
13250   [(set (match_operand:QI 0 "register_operand" "")
13251         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13252   ""
13253   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13254
13255 (define_expand "sle"
13256   [(set (match_operand:QI 0 "register_operand" "")
13257         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13258   ""
13259   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13260
13261 (define_expand "sleu"
13262   [(set (match_operand:QI 0 "register_operand" "")
13263         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13264   ""
13265   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13266
13267 (define_expand "sunordered"
13268   [(set (match_operand:QI 0 "register_operand" "")
13269         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13270   "TARGET_80387 || TARGET_SSE"
13271   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13272
13273 (define_expand "sordered"
13274   [(set (match_operand:QI 0 "register_operand" "")
13275         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13276   "TARGET_80387"
13277   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13278
13279 (define_expand "suneq"
13280   [(set (match_operand:QI 0 "register_operand" "")
13281         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13282   "TARGET_80387 || TARGET_SSE"
13283   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13284
13285 (define_expand "sunge"
13286   [(set (match_operand:QI 0 "register_operand" "")
13287         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13288   "TARGET_80387 || TARGET_SSE"
13289   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13290
13291 (define_expand "sungt"
13292   [(set (match_operand:QI 0 "register_operand" "")
13293         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13294   "TARGET_80387 || TARGET_SSE"
13295   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13296
13297 (define_expand "sunle"
13298   [(set (match_operand:QI 0 "register_operand" "")
13299         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13300   "TARGET_80387 || TARGET_SSE"
13301   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13302
13303 (define_expand "sunlt"
13304   [(set (match_operand:QI 0 "register_operand" "")
13305         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13306   "TARGET_80387 || TARGET_SSE"
13307   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13308
13309 (define_expand "sltgt"
13310   [(set (match_operand:QI 0 "register_operand" "")
13311         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13312   "TARGET_80387 || TARGET_SSE"
13313   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13314
13315 (define_insn "*setcc_1"
13316   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13317         (match_operator:QI 1 "ix86_comparison_operator"
13318           [(reg FLAGS_REG) (const_int 0)]))]
13319   ""
13320   "set%C1\t%0"
13321   [(set_attr "type" "setcc")
13322    (set_attr "mode" "QI")])
13323
13324 (define_insn "*setcc_2"
13325   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13326         (match_operator:QI 1 "ix86_comparison_operator"
13327           [(reg FLAGS_REG) (const_int 0)]))]
13328   ""
13329   "set%C1\t%0"
13330   [(set_attr "type" "setcc")
13331    (set_attr "mode" "QI")])
13332
13333 ;; In general it is not safe to assume too much about CCmode registers,
13334 ;; so simplify-rtx stops when it sees a second one.  Under certain
13335 ;; conditions this is safe on x86, so help combine not create
13336 ;;
13337 ;;      seta    %al
13338 ;;      testb   %al, %al
13339 ;;      sete    %al
13340
13341 (define_split
13342   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13343         (ne:QI (match_operator 1 "ix86_comparison_operator"
13344                  [(reg FLAGS_REG) (const_int 0)])
13345             (const_int 0)))]
13346   ""
13347   [(set (match_dup 0) (match_dup 1))]
13348 {
13349   PUT_MODE (operands[1], QImode);
13350 })
13351
13352 (define_split
13353   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13354         (ne:QI (match_operator 1 "ix86_comparison_operator"
13355                  [(reg FLAGS_REG) (const_int 0)])
13356             (const_int 0)))]
13357   ""
13358   [(set (match_dup 0) (match_dup 1))]
13359 {
13360   PUT_MODE (operands[1], QImode);
13361 })
13362
13363 (define_split
13364   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13365         (eq:QI (match_operator 1 "ix86_comparison_operator"
13366                  [(reg FLAGS_REG) (const_int 0)])
13367             (const_int 0)))]
13368   ""
13369   [(set (match_dup 0) (match_dup 1))]
13370 {
13371   rtx new_op1 = copy_rtx (operands[1]);
13372   operands[1] = new_op1;
13373   PUT_MODE (new_op1, QImode);
13374   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13375                                              GET_MODE (XEXP (new_op1, 0))));
13376
13377   /* Make sure that (a) the CCmode we have for the flags is strong
13378      enough for the reversed compare or (b) we have a valid FP compare.  */
13379   if (! ix86_comparison_operator (new_op1, VOIDmode))
13380     FAIL;
13381 })
13382
13383 (define_split
13384   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13385         (eq:QI (match_operator 1 "ix86_comparison_operator"
13386                  [(reg FLAGS_REG) (const_int 0)])
13387             (const_int 0)))]
13388   ""
13389   [(set (match_dup 0) (match_dup 1))]
13390 {
13391   rtx new_op1 = copy_rtx (operands[1]);
13392   operands[1] = new_op1;
13393   PUT_MODE (new_op1, QImode);
13394   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13395                                              GET_MODE (XEXP (new_op1, 0))));
13396
13397   /* Make sure that (a) the CCmode we have for the flags is strong
13398      enough for the reversed compare or (b) we have a valid FP compare.  */
13399   if (! ix86_comparison_operator (new_op1, VOIDmode))
13400     FAIL;
13401 })
13402
13403 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13404 ;; subsequent logical operations are used to imitate conditional moves.
13405 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13406 ;; it directly.
13407
13408 (define_insn "*sse_setccsf"
13409   [(set (match_operand:SF 0 "register_operand" "=x")
13410         (match_operator:SF 1 "sse_comparison_operator"
13411           [(match_operand:SF 2 "register_operand" "0")
13412            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13413   "TARGET_SSE"
13414   "cmp%D1ss\t{%3, %0|%0, %3}"
13415   [(set_attr "type" "ssecmp")
13416    (set_attr "mode" "SF")])
13417
13418 (define_insn "*sse_setccdf"
13419   [(set (match_operand:DF 0 "register_operand" "=Y")
13420         (match_operator:DF 1 "sse_comparison_operator"
13421           [(match_operand:DF 2 "register_operand" "0")
13422            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13423   "TARGET_SSE2"
13424   "cmp%D1sd\t{%3, %0|%0, %3}"
13425   [(set_attr "type" "ssecmp")
13426    (set_attr "mode" "DF")])
13427 \f
13428 ;; Basic conditional jump instructions.
13429 ;; We ignore the overflow flag for signed branch instructions.
13430
13431 ;; For all bCOND expanders, also expand the compare or test insn that
13432 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13433
13434 (define_expand "beq"
13435   [(set (pc)
13436         (if_then_else (match_dup 1)
13437                       (label_ref (match_operand 0 "" ""))
13438                       (pc)))]
13439   ""
13440   "ix86_expand_branch (EQ, operands[0]); DONE;")
13441
13442 (define_expand "bne"
13443   [(set (pc)
13444         (if_then_else (match_dup 1)
13445                       (label_ref (match_operand 0 "" ""))
13446                       (pc)))]
13447   ""
13448   "ix86_expand_branch (NE, operands[0]); DONE;")
13449
13450 (define_expand "bgt"
13451   [(set (pc)
13452         (if_then_else (match_dup 1)
13453                       (label_ref (match_operand 0 "" ""))
13454                       (pc)))]
13455   ""
13456   "ix86_expand_branch (GT, operands[0]); DONE;")
13457
13458 (define_expand "bgtu"
13459   [(set (pc)
13460         (if_then_else (match_dup 1)
13461                       (label_ref (match_operand 0 "" ""))
13462                       (pc)))]
13463   ""
13464   "ix86_expand_branch (GTU, operands[0]); DONE;")
13465
13466 (define_expand "blt"
13467   [(set (pc)
13468         (if_then_else (match_dup 1)
13469                       (label_ref (match_operand 0 "" ""))
13470                       (pc)))]
13471   ""
13472   "ix86_expand_branch (LT, operands[0]); DONE;")
13473
13474 (define_expand "bltu"
13475   [(set (pc)
13476         (if_then_else (match_dup 1)
13477                       (label_ref (match_operand 0 "" ""))
13478                       (pc)))]
13479   ""
13480   "ix86_expand_branch (LTU, operands[0]); DONE;")
13481
13482 (define_expand "bge"
13483   [(set (pc)
13484         (if_then_else (match_dup 1)
13485                       (label_ref (match_operand 0 "" ""))
13486                       (pc)))]
13487   ""
13488   "ix86_expand_branch (GE, operands[0]); DONE;")
13489
13490 (define_expand "bgeu"
13491   [(set (pc)
13492         (if_then_else (match_dup 1)
13493                       (label_ref (match_operand 0 "" ""))
13494                       (pc)))]
13495   ""
13496   "ix86_expand_branch (GEU, operands[0]); DONE;")
13497
13498 (define_expand "ble"
13499   [(set (pc)
13500         (if_then_else (match_dup 1)
13501                       (label_ref (match_operand 0 "" ""))
13502                       (pc)))]
13503   ""
13504   "ix86_expand_branch (LE, operands[0]); DONE;")
13505
13506 (define_expand "bleu"
13507   [(set (pc)
13508         (if_then_else (match_dup 1)
13509                       (label_ref (match_operand 0 "" ""))
13510                       (pc)))]
13511   ""
13512   "ix86_expand_branch (LEU, operands[0]); DONE;")
13513
13514 (define_expand "bunordered"
13515   [(set (pc)
13516         (if_then_else (match_dup 1)
13517                       (label_ref (match_operand 0 "" ""))
13518                       (pc)))]
13519   "TARGET_80387 || TARGET_SSE_MATH"
13520   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13521
13522 (define_expand "bordered"
13523   [(set (pc)
13524         (if_then_else (match_dup 1)
13525                       (label_ref (match_operand 0 "" ""))
13526                       (pc)))]
13527   "TARGET_80387 || TARGET_SSE_MATH"
13528   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13529
13530 (define_expand "buneq"
13531   [(set (pc)
13532         (if_then_else (match_dup 1)
13533                       (label_ref (match_operand 0 "" ""))
13534                       (pc)))]
13535   "TARGET_80387 || TARGET_SSE_MATH"
13536   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13537
13538 (define_expand "bunge"
13539   [(set (pc)
13540         (if_then_else (match_dup 1)
13541                       (label_ref (match_operand 0 "" ""))
13542                       (pc)))]
13543   "TARGET_80387 || TARGET_SSE_MATH"
13544   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13545
13546 (define_expand "bungt"
13547   [(set (pc)
13548         (if_then_else (match_dup 1)
13549                       (label_ref (match_operand 0 "" ""))
13550                       (pc)))]
13551   "TARGET_80387 || TARGET_SSE_MATH"
13552   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13553
13554 (define_expand "bunle"
13555   [(set (pc)
13556         (if_then_else (match_dup 1)
13557                       (label_ref (match_operand 0 "" ""))
13558                       (pc)))]
13559   "TARGET_80387 || TARGET_SSE_MATH"
13560   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13561
13562 (define_expand "bunlt"
13563   [(set (pc)
13564         (if_then_else (match_dup 1)
13565                       (label_ref (match_operand 0 "" ""))
13566                       (pc)))]
13567   "TARGET_80387 || TARGET_SSE_MATH"
13568   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13569
13570 (define_expand "bltgt"
13571   [(set (pc)
13572         (if_then_else (match_dup 1)
13573                       (label_ref (match_operand 0 "" ""))
13574                       (pc)))]
13575   "TARGET_80387 || TARGET_SSE_MATH"
13576   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13577
13578 (define_insn "*jcc_1"
13579   [(set (pc)
13580         (if_then_else (match_operator 1 "ix86_comparison_operator"
13581                                       [(reg FLAGS_REG) (const_int 0)])
13582                       (label_ref (match_operand 0 "" ""))
13583                       (pc)))]
13584   ""
13585   "%+j%C1\t%l0"
13586   [(set_attr "type" "ibr")
13587    (set_attr "modrm" "0")
13588    (set (attr "length")
13589            (if_then_else (and (ge (minus (match_dup 0) (pc))
13590                                   (const_int -126))
13591                               (lt (minus (match_dup 0) (pc))
13592                                   (const_int 128)))
13593              (const_int 2)
13594              (const_int 6)))])
13595
13596 (define_insn "*jcc_2"
13597   [(set (pc)
13598         (if_then_else (match_operator 1 "ix86_comparison_operator"
13599                                       [(reg FLAGS_REG) (const_int 0)])
13600                       (pc)
13601                       (label_ref (match_operand 0 "" ""))))]
13602   ""
13603   "%+j%c1\t%l0"
13604   [(set_attr "type" "ibr")
13605    (set_attr "modrm" "0")
13606    (set (attr "length")
13607            (if_then_else (and (ge (minus (match_dup 0) (pc))
13608                                   (const_int -126))
13609                               (lt (minus (match_dup 0) (pc))
13610                                   (const_int 128)))
13611              (const_int 2)
13612              (const_int 6)))])
13613
13614 ;; In general it is not safe to assume too much about CCmode registers,
13615 ;; so simplify-rtx stops when it sees a second one.  Under certain
13616 ;; conditions this is safe on x86, so help combine not create
13617 ;;
13618 ;;      seta    %al
13619 ;;      testb   %al, %al
13620 ;;      je      Lfoo
13621
13622 (define_split
13623   [(set (pc)
13624         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13625                                       [(reg FLAGS_REG) (const_int 0)])
13626                           (const_int 0))
13627                       (label_ref (match_operand 1 "" ""))
13628                       (pc)))]
13629   ""
13630   [(set (pc)
13631         (if_then_else (match_dup 0)
13632                       (label_ref (match_dup 1))
13633                       (pc)))]
13634 {
13635   PUT_MODE (operands[0], VOIDmode);
13636 })
13637
13638 (define_split
13639   [(set (pc)
13640         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13641                                       [(reg FLAGS_REG) (const_int 0)])
13642                           (const_int 0))
13643                       (label_ref (match_operand 1 "" ""))
13644                       (pc)))]
13645   ""
13646   [(set (pc)
13647         (if_then_else (match_dup 0)
13648                       (label_ref (match_dup 1))
13649                       (pc)))]
13650 {
13651   rtx new_op0 = copy_rtx (operands[0]);
13652   operands[0] = new_op0;
13653   PUT_MODE (new_op0, VOIDmode);
13654   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13655                                              GET_MODE (XEXP (new_op0, 0))));
13656
13657   /* Make sure that (a) the CCmode we have for the flags is strong
13658      enough for the reversed compare or (b) we have a valid FP compare.  */
13659   if (! ix86_comparison_operator (new_op0, VOIDmode))
13660     FAIL;
13661 })
13662
13663 ;; Define combination compare-and-branch fp compare instructions to use
13664 ;; during early optimization.  Splitting the operation apart early makes
13665 ;; for bad code when we want to reverse the operation.
13666
13667 (define_insn "*fp_jcc_1_mixed"
13668   [(set (pc)
13669         (if_then_else (match_operator 0 "comparison_operator"
13670                         [(match_operand 1 "register_operand" "f,x")
13671                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13672           (label_ref (match_operand 3 "" ""))
13673           (pc)))
13674    (clobber (reg:CCFP FPSR_REG))
13675    (clobber (reg:CCFP FLAGS_REG))]
13676   "TARGET_MIX_SSE_I387
13677    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13678    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13679    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13680   "#")
13681
13682 (define_insn "*fp_jcc_1_sse"
13683   [(set (pc)
13684         (if_then_else (match_operator 0 "comparison_operator"
13685                         [(match_operand 1 "register_operand" "x")
13686                          (match_operand 2 "nonimmediate_operand" "xm")])
13687           (label_ref (match_operand 3 "" ""))
13688           (pc)))
13689    (clobber (reg:CCFP FPSR_REG))
13690    (clobber (reg:CCFP FLAGS_REG))]
13691   "TARGET_SSE_MATH
13692    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13693    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13694    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13695   "#")
13696
13697 (define_insn "*fp_jcc_1_387"
13698   [(set (pc)
13699         (if_then_else (match_operator 0 "comparison_operator"
13700                         [(match_operand 1 "register_operand" "f")
13701                          (match_operand 2 "register_operand" "f")])
13702           (label_ref (match_operand 3 "" ""))
13703           (pc)))
13704    (clobber (reg:CCFP FPSR_REG))
13705    (clobber (reg:CCFP FLAGS_REG))]
13706   "TARGET_CMOVE && TARGET_80387
13707    && FLOAT_MODE_P (GET_MODE (operands[1]))
13708    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13709    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13710   "#")
13711
13712 (define_insn "*fp_jcc_2_mixed"
13713   [(set (pc)
13714         (if_then_else (match_operator 0 "comparison_operator"
13715                         [(match_operand 1 "register_operand" "f,x")
13716                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13717           (pc)
13718           (label_ref (match_operand 3 "" ""))))
13719    (clobber (reg:CCFP FPSR_REG))
13720    (clobber (reg:CCFP FLAGS_REG))]
13721   "TARGET_MIX_SSE_I387
13722    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13723    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13724    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13725   "#")
13726
13727 (define_insn "*fp_jcc_2_sse"
13728   [(set (pc)
13729         (if_then_else (match_operator 0 "comparison_operator"
13730                         [(match_operand 1 "register_operand" "x")
13731                          (match_operand 2 "nonimmediate_operand" "xm")])
13732           (pc)
13733           (label_ref (match_operand 3 "" ""))))
13734    (clobber (reg:CCFP FPSR_REG))
13735    (clobber (reg:CCFP FLAGS_REG))]
13736   "TARGET_SSE_MATH
13737    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13738    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13739    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13740   "#")
13741
13742 (define_insn "*fp_jcc_2_387"
13743   [(set (pc)
13744         (if_then_else (match_operator 0 "comparison_operator"
13745                         [(match_operand 1 "register_operand" "f")
13746                          (match_operand 2 "register_operand" "f")])
13747           (pc)
13748           (label_ref (match_operand 3 "" ""))))
13749    (clobber (reg:CCFP FPSR_REG))
13750    (clobber (reg:CCFP FLAGS_REG))]
13751   "TARGET_CMOVE && TARGET_80387
13752    && FLOAT_MODE_P (GET_MODE (operands[1]))
13753    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13754    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13755   "#")
13756
13757 (define_insn "*fp_jcc_3_387"
13758   [(set (pc)
13759         (if_then_else (match_operator 0 "comparison_operator"
13760                         [(match_operand 1 "register_operand" "f")
13761                          (match_operand 2 "nonimmediate_operand" "fm")])
13762           (label_ref (match_operand 3 "" ""))
13763           (pc)))
13764    (clobber (reg:CCFP FPSR_REG))
13765    (clobber (reg:CCFP FLAGS_REG))
13766    (clobber (match_scratch:HI 4 "=a"))]
13767   "TARGET_80387
13768    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13769    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13770    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13771    && SELECT_CC_MODE (GET_CODE (operands[0]),
13772                       operands[1], operands[2]) == CCFPmode
13773    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13774   "#")
13775
13776 (define_insn "*fp_jcc_4_387"
13777   [(set (pc)
13778         (if_then_else (match_operator 0 "comparison_operator"
13779                         [(match_operand 1 "register_operand" "f")
13780                          (match_operand 2 "nonimmediate_operand" "fm")])
13781           (pc)
13782           (label_ref (match_operand 3 "" ""))))
13783    (clobber (reg:CCFP FPSR_REG))
13784    (clobber (reg:CCFP FLAGS_REG))
13785    (clobber (match_scratch:HI 4 "=a"))]
13786   "TARGET_80387
13787    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13788    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13789    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13790    && SELECT_CC_MODE (GET_CODE (operands[0]),
13791                       operands[1], operands[2]) == CCFPmode
13792    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13793   "#")
13794
13795 (define_insn "*fp_jcc_5_387"
13796   [(set (pc)
13797         (if_then_else (match_operator 0 "comparison_operator"
13798                         [(match_operand 1 "register_operand" "f")
13799                          (match_operand 2 "register_operand" "f")])
13800           (label_ref (match_operand 3 "" ""))
13801           (pc)))
13802    (clobber (reg:CCFP FPSR_REG))
13803    (clobber (reg:CCFP FLAGS_REG))
13804    (clobber (match_scratch:HI 4 "=a"))]
13805   "TARGET_80387
13806    && FLOAT_MODE_P (GET_MODE (operands[1]))
13807    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13808    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13809   "#")
13810
13811 (define_insn "*fp_jcc_6_387"
13812   [(set (pc)
13813         (if_then_else (match_operator 0 "comparison_operator"
13814                         [(match_operand 1 "register_operand" "f")
13815                          (match_operand 2 "register_operand" "f")])
13816           (pc)
13817           (label_ref (match_operand 3 "" ""))))
13818    (clobber (reg:CCFP FPSR_REG))
13819    (clobber (reg:CCFP FLAGS_REG))
13820    (clobber (match_scratch:HI 4 "=a"))]
13821   "TARGET_80387
13822    && FLOAT_MODE_P (GET_MODE (operands[1]))
13823    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13824    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13825   "#")
13826
13827 (define_insn "*fp_jcc_7_387"
13828   [(set (pc)
13829         (if_then_else (match_operator 0 "comparison_operator"
13830                         [(match_operand 1 "register_operand" "f")
13831                          (match_operand 2 "const0_operand" "X")])
13832           (label_ref (match_operand 3 "" ""))
13833           (pc)))
13834    (clobber (reg:CCFP FPSR_REG))
13835    (clobber (reg:CCFP FLAGS_REG))
13836    (clobber (match_scratch:HI 4 "=a"))]
13837   "TARGET_80387
13838    && FLOAT_MODE_P (GET_MODE (operands[1]))
13839    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13840    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13841    && SELECT_CC_MODE (GET_CODE (operands[0]),
13842                       operands[1], operands[2]) == CCFPmode
13843    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13844   "#")
13845
13846 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13847 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13848 ;; with a precedence over other operators and is always put in the first
13849 ;; place. Swap condition and operands to match ficom instruction.
13850
13851 (define_insn "*fp_jcc_8<mode>_387"
13852   [(set (pc)
13853         (if_then_else (match_operator 0 "comparison_operator"
13854                         [(match_operator 1 "float_operator"
13855                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13856                            (match_operand 3 "register_operand" "f,f")])
13857           (label_ref (match_operand 4 "" ""))
13858           (pc)))
13859    (clobber (reg:CCFP FPSR_REG))
13860    (clobber (reg:CCFP FLAGS_REG))
13861    (clobber (match_scratch:HI 5 "=a,a"))]
13862   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13863    && FLOAT_MODE_P (GET_MODE (operands[3]))
13864    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13865    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13866    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13867    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13868   "#")
13869
13870 (define_split
13871   [(set (pc)
13872         (if_then_else (match_operator 0 "comparison_operator"
13873                         [(match_operand 1 "register_operand" "")
13874                          (match_operand 2 "nonimmediate_operand" "")])
13875           (match_operand 3 "" "")
13876           (match_operand 4 "" "")))
13877    (clobber (reg:CCFP FPSR_REG))
13878    (clobber (reg:CCFP FLAGS_REG))]
13879   "reload_completed"
13880   [(const_int 0)]
13881 {
13882   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13883                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13884   DONE;
13885 })
13886
13887 (define_split
13888   [(set (pc)
13889         (if_then_else (match_operator 0 "comparison_operator"
13890                         [(match_operand 1 "register_operand" "")
13891                          (match_operand 2 "general_operand" "")])
13892           (match_operand 3 "" "")
13893           (match_operand 4 "" "")))
13894    (clobber (reg:CCFP FPSR_REG))
13895    (clobber (reg:CCFP FLAGS_REG))
13896    (clobber (match_scratch:HI 5 "=a"))]
13897   "reload_completed"
13898   [(const_int 0)]
13899 {
13900   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13901                         operands[3], operands[4], operands[5], NULL_RTX);
13902   DONE;
13903 })
13904
13905 (define_split
13906   [(set (pc)
13907         (if_then_else (match_operator 0 "comparison_operator"
13908                         [(match_operator 1 "float_operator"
13909                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13910                            (match_operand 3 "register_operand" "")])
13911           (match_operand 4 "" "")
13912           (match_operand 5 "" "")))
13913    (clobber (reg:CCFP FPSR_REG))
13914    (clobber (reg:CCFP FLAGS_REG))
13915    (clobber (match_scratch:HI 6 "=a"))]
13916   "reload_completed"
13917   [(const_int 0)]
13918 {
13919   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13920   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13921                         operands[3], operands[7],
13922                         operands[4], operands[5], operands[6], NULL_RTX);
13923   DONE;
13924 })
13925
13926 ;; %%% Kill this when reload knows how to do it.
13927 (define_split
13928   [(set (pc)
13929         (if_then_else (match_operator 0 "comparison_operator"
13930                         [(match_operator 1 "float_operator"
13931                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13932                            (match_operand 3 "register_operand" "")])
13933           (match_operand 4 "" "")
13934           (match_operand 5 "" "")))
13935    (clobber (reg:CCFP FPSR_REG))
13936    (clobber (reg:CCFP FLAGS_REG))
13937    (clobber (match_scratch:HI 6 "=a"))]
13938   "reload_completed"
13939   [(const_int 0)]
13940 {
13941   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13942   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13943   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13944                         operands[3], operands[7],
13945                         operands[4], operands[5], operands[6], operands[2]);
13946   DONE;
13947 })
13948 \f
13949 ;; Unconditional and other jump instructions
13950
13951 (define_insn "jump"
13952   [(set (pc)
13953         (label_ref (match_operand 0 "" "")))]
13954   ""
13955   "jmp\t%l0"
13956   [(set_attr "type" "ibr")
13957    (set (attr "length")
13958            (if_then_else (and (ge (minus (match_dup 0) (pc))
13959                                   (const_int -126))
13960                               (lt (minus (match_dup 0) (pc))
13961                                   (const_int 128)))
13962              (const_int 2)
13963              (const_int 5)))
13964    (set_attr "modrm" "0")])
13965
13966 (define_expand "indirect_jump"
13967   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13968   ""
13969   "")
13970
13971 (define_insn "*indirect_jump"
13972   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13973   "!TARGET_64BIT"
13974   "jmp\t%A0"
13975   [(set_attr "type" "ibr")
13976    (set_attr "length_immediate" "0")])
13977
13978 (define_insn "*indirect_jump_rtx64"
13979   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13980   "TARGET_64BIT"
13981   "jmp\t%A0"
13982   [(set_attr "type" "ibr")
13983    (set_attr "length_immediate" "0")])
13984
13985 (define_expand "tablejump"
13986   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13987               (use (label_ref (match_operand 1 "" "")))])]
13988   ""
13989 {
13990   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13991      relative.  Convert the relative address to an absolute address.  */
13992   if (flag_pic)
13993     {
13994       rtx op0, op1;
13995       enum rtx_code code;
13996
13997       if (TARGET_64BIT)
13998         {
13999           code = PLUS;
14000           op0 = operands[0];
14001           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14002         }
14003       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14004         {
14005           code = PLUS;
14006           op0 = operands[0];
14007           op1 = pic_offset_table_rtx;
14008         }
14009       else
14010         {
14011           code = MINUS;
14012           op0 = pic_offset_table_rtx;
14013           op1 = operands[0];
14014         }
14015
14016       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14017                                          OPTAB_DIRECT);
14018     }
14019 })
14020
14021 (define_insn "*tablejump_1"
14022   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14023    (use (label_ref (match_operand 1 "" "")))]
14024   "!TARGET_64BIT"
14025   "jmp\t%A0"
14026   [(set_attr "type" "ibr")
14027    (set_attr "length_immediate" "0")])
14028
14029 (define_insn "*tablejump_1_rtx64"
14030   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14031    (use (label_ref (match_operand 1 "" "")))]
14032   "TARGET_64BIT"
14033   "jmp\t%A0"
14034   [(set_attr "type" "ibr")
14035    (set_attr "length_immediate" "0")])
14036 \f
14037 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14038
14039 (define_peephole2
14040   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14041    (set (match_operand:QI 1 "register_operand" "")
14042         (match_operator:QI 2 "ix86_comparison_operator"
14043           [(reg FLAGS_REG) (const_int 0)]))
14044    (set (match_operand 3 "q_regs_operand" "")
14045         (zero_extend (match_dup 1)))]
14046   "(peep2_reg_dead_p (3, operands[1])
14047     || operands_match_p (operands[1], operands[3]))
14048    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14049   [(set (match_dup 4) (match_dup 0))
14050    (set (strict_low_part (match_dup 5))
14051         (match_dup 2))]
14052 {
14053   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14054   operands[5] = gen_lowpart (QImode, operands[3]);
14055   ix86_expand_clear (operands[3]);
14056 })
14057
14058 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14059
14060 (define_peephole2
14061   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14062    (set (match_operand:QI 1 "register_operand" "")
14063         (match_operator:QI 2 "ix86_comparison_operator"
14064           [(reg FLAGS_REG) (const_int 0)]))
14065    (parallel [(set (match_operand 3 "q_regs_operand" "")
14066                    (zero_extend (match_dup 1)))
14067               (clobber (reg:CC FLAGS_REG))])]
14068   "(peep2_reg_dead_p (3, operands[1])
14069     || operands_match_p (operands[1], operands[3]))
14070    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14071   [(set (match_dup 4) (match_dup 0))
14072    (set (strict_low_part (match_dup 5))
14073         (match_dup 2))]
14074 {
14075   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14076   operands[5] = gen_lowpart (QImode, operands[3]);
14077   ix86_expand_clear (operands[3]);
14078 })
14079 \f
14080 ;; Call instructions.
14081
14082 ;; The predicates normally associated with named expanders are not properly
14083 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14084 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14085
14086 ;; Call subroutine returning no value.
14087
14088 (define_expand "call_pop"
14089   [(parallel [(call (match_operand:QI 0 "" "")
14090                     (match_operand:SI 1 "" ""))
14091               (set (reg:SI SP_REG)
14092                    (plus:SI (reg:SI SP_REG)
14093                             (match_operand:SI 3 "" "")))])]
14094   "!TARGET_64BIT"
14095 {
14096   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14097   DONE;
14098 })
14099
14100 (define_insn "*call_pop_0"
14101   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14102          (match_operand:SI 1 "" ""))
14103    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14104                             (match_operand:SI 2 "immediate_operand" "")))]
14105   "!TARGET_64BIT"
14106 {
14107   if (SIBLING_CALL_P (insn))
14108     return "jmp\t%P0";
14109   else
14110     return "call\t%P0";
14111 }
14112   [(set_attr "type" "call")])
14113
14114 (define_insn "*call_pop_1"
14115   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14116          (match_operand:SI 1 "" ""))
14117    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14118                             (match_operand:SI 2 "immediate_operand" "i")))]
14119   "!TARGET_64BIT"
14120 {
14121   if (constant_call_address_operand (operands[0], Pmode))
14122     {
14123       if (SIBLING_CALL_P (insn))
14124         return "jmp\t%P0";
14125       else
14126         return "call\t%P0";
14127     }
14128   if (SIBLING_CALL_P (insn))
14129     return "jmp\t%A0";
14130   else
14131     return "call\t%A0";
14132 }
14133   [(set_attr "type" "call")])
14134
14135 (define_expand "call"
14136   [(call (match_operand:QI 0 "" "")
14137          (match_operand 1 "" ""))
14138    (use (match_operand 2 "" ""))]
14139   ""
14140 {
14141   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14142   DONE;
14143 })
14144
14145 (define_expand "sibcall"
14146   [(call (match_operand:QI 0 "" "")
14147          (match_operand 1 "" ""))
14148    (use (match_operand 2 "" ""))]
14149   ""
14150 {
14151   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14152   DONE;
14153 })
14154
14155 (define_insn "*call_0"
14156   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14157          (match_operand 1 "" ""))]
14158   ""
14159 {
14160   if (SIBLING_CALL_P (insn))
14161     return "jmp\t%P0";
14162   else
14163     return "call\t%P0";
14164 }
14165   [(set_attr "type" "call")])
14166
14167 (define_insn "*call_1"
14168   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14169          (match_operand 1 "" ""))]
14170   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14171 {
14172   if (constant_call_address_operand (operands[0], Pmode))
14173     return "call\t%P0";
14174   return "call\t%A0";
14175 }
14176   [(set_attr "type" "call")])
14177
14178 (define_insn "*sibcall_1"
14179   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14180          (match_operand 1 "" ""))]
14181   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14182 {
14183   if (constant_call_address_operand (operands[0], Pmode))
14184     return "jmp\t%P0";
14185   return "jmp\t%A0";
14186 }
14187   [(set_attr "type" "call")])
14188
14189 (define_insn "*call_1_rex64"
14190   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14191          (match_operand 1 "" ""))]
14192   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14193 {
14194   if (constant_call_address_operand (operands[0], Pmode))
14195     return "call\t%P0";
14196   return "call\t%A0";
14197 }
14198   [(set_attr "type" "call")])
14199
14200 (define_insn "*sibcall_1_rex64"
14201   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14202          (match_operand 1 "" ""))]
14203   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14204   "jmp\t%P0"
14205   [(set_attr "type" "call")])
14206
14207 (define_insn "*sibcall_1_rex64_v"
14208   [(call (mem:QI (reg:DI R11_REG))
14209          (match_operand 0 "" ""))]
14210   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14211   "jmp\t*%%r11"
14212   [(set_attr "type" "call")])
14213
14214
14215 ;; Call subroutine, returning value in operand 0
14216
14217 (define_expand "call_value_pop"
14218   [(parallel [(set (match_operand 0 "" "")
14219                    (call (match_operand:QI 1 "" "")
14220                          (match_operand:SI 2 "" "")))
14221               (set (reg:SI SP_REG)
14222                    (plus:SI (reg:SI SP_REG)
14223                             (match_operand:SI 4 "" "")))])]
14224   "!TARGET_64BIT"
14225 {
14226   ix86_expand_call (operands[0], operands[1], operands[2],
14227                     operands[3], operands[4], 0);
14228   DONE;
14229 })
14230
14231 (define_expand "call_value"
14232   [(set (match_operand 0 "" "")
14233         (call (match_operand:QI 1 "" "")
14234               (match_operand:SI 2 "" "")))
14235    (use (match_operand:SI 3 "" ""))]
14236   ;; Operand 2 not used on the i386.
14237   ""
14238 {
14239   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14240   DONE;
14241 })
14242
14243 (define_expand "sibcall_value"
14244   [(set (match_operand 0 "" "")
14245         (call (match_operand:QI 1 "" "")
14246               (match_operand:SI 2 "" "")))
14247    (use (match_operand:SI 3 "" ""))]
14248   ;; Operand 2 not used on the i386.
14249   ""
14250 {
14251   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14252   DONE;
14253 })
14254
14255 ;; Call subroutine returning any type.
14256
14257 (define_expand "untyped_call"
14258   [(parallel [(call (match_operand 0 "" "")
14259                     (const_int 0))
14260               (match_operand 1 "" "")
14261               (match_operand 2 "" "")])]
14262   ""
14263 {
14264   int i;
14265
14266   /* In order to give reg-stack an easier job in validating two
14267      coprocessor registers as containing a possible return value,
14268      simply pretend the untyped call returns a complex long double
14269      value.  */
14270
14271   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14272                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14273                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14274                     NULL, 0);
14275
14276   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14277     {
14278       rtx set = XVECEXP (operands[2], 0, i);
14279       emit_move_insn (SET_DEST (set), SET_SRC (set));
14280     }
14281
14282   /* The optimizer does not know that the call sets the function value
14283      registers we stored in the result block.  We avoid problems by
14284      claiming that all hard registers are used and clobbered at this
14285      point.  */
14286   emit_insn (gen_blockage (const0_rtx));
14287
14288   DONE;
14289 })
14290 \f
14291 ;; Prologue and epilogue instructions
14292
14293 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14294 ;; all of memory.  This blocks insns from being moved across this point.
14295
14296 (define_insn "blockage"
14297   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14298   ""
14299   ""
14300   [(set_attr "length" "0")])
14301
14302 ;; Insn emitted into the body of a function to return from a function.
14303 ;; This is only done if the function's epilogue is known to be simple.
14304 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14305
14306 (define_expand "return"
14307   [(return)]
14308   "ix86_can_use_return_insn_p ()"
14309 {
14310   if (current_function_pops_args)
14311     {
14312       rtx popc = GEN_INT (current_function_pops_args);
14313       emit_jump_insn (gen_return_pop_internal (popc));
14314       DONE;
14315     }
14316 })
14317
14318 (define_insn "return_internal"
14319   [(return)]
14320   "reload_completed"
14321   "ret"
14322   [(set_attr "length" "1")
14323    (set_attr "length_immediate" "0")
14324    (set_attr "modrm" "0")])
14325
14326 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14327 ;; instruction Athlon and K8 have.
14328
14329 (define_insn "return_internal_long"
14330   [(return)
14331    (unspec [(const_int 0)] UNSPEC_REP)]
14332   "reload_completed"
14333   "rep {;} ret"
14334   [(set_attr "length" "1")
14335    (set_attr "length_immediate" "0")
14336    (set_attr "prefix_rep" "1")
14337    (set_attr "modrm" "0")])
14338
14339 (define_insn "return_pop_internal"
14340   [(return)
14341    (use (match_operand:SI 0 "const_int_operand" ""))]
14342   "reload_completed"
14343   "ret\t%0"
14344   [(set_attr "length" "3")
14345    (set_attr "length_immediate" "2")
14346    (set_attr "modrm" "0")])
14347
14348 (define_insn "return_indirect_internal"
14349   [(return)
14350    (use (match_operand:SI 0 "register_operand" "r"))]
14351   "reload_completed"
14352   "jmp\t%A0"
14353   [(set_attr "type" "ibr")
14354    (set_attr "length_immediate" "0")])
14355
14356 (define_insn "nop"
14357   [(const_int 0)]
14358   ""
14359   "nop"
14360   [(set_attr "length" "1")
14361    (set_attr "length_immediate" "0")
14362    (set_attr "modrm" "0")])
14363
14364 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14365 ;; branch prediction penalty for the third jump in a 16-byte
14366 ;; block on K8.
14367
14368 (define_insn "align"
14369   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14370   ""
14371 {
14372 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14373   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14374 #else
14375   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14376      The align insn is used to avoid 3 jump instructions in the row to improve
14377      branch prediction and the benefits hardly outweigh the cost of extra 8
14378      nops on the average inserted by full alignment pseudo operation.  */
14379 #endif
14380   return "";
14381 }
14382   [(set_attr "length" "16")])
14383
14384 (define_expand "prologue"
14385   [(const_int 1)]
14386   ""
14387   "ix86_expand_prologue (); DONE;")
14388
14389 (define_insn "set_got"
14390   [(set (match_operand:SI 0 "register_operand" "=r")
14391         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14392    (clobber (reg:CC FLAGS_REG))]
14393   "!TARGET_64BIT"
14394   { return output_set_got (operands[0], NULL_RTX); }
14395   [(set_attr "type" "multi")
14396    (set_attr "length" "12")])
14397
14398 (define_insn "set_got_labelled"
14399   [(set (match_operand:SI 0 "register_operand" "=r")
14400         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14401          UNSPEC_SET_GOT))
14402    (clobber (reg:CC FLAGS_REG))]
14403   "!TARGET_64BIT"
14404   { return output_set_got (operands[0], operands[1]); }
14405   [(set_attr "type" "multi")
14406    (set_attr "length" "12")])
14407
14408 (define_insn "set_got_rex64"
14409   [(set (match_operand:DI 0 "register_operand" "=r")
14410         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14411   "TARGET_64BIT"
14412   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14413   [(set_attr "type" "lea")
14414    (set_attr "length" "6")])
14415
14416 (define_expand "epilogue"
14417   [(const_int 1)]
14418   ""
14419   "ix86_expand_epilogue (1); DONE;")
14420
14421 (define_expand "sibcall_epilogue"
14422   [(const_int 1)]
14423   ""
14424   "ix86_expand_epilogue (0); DONE;")
14425
14426 (define_expand "eh_return"
14427   [(use (match_operand 0 "register_operand" ""))]
14428   ""
14429 {
14430   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14431
14432   /* Tricky bit: we write the address of the handler to which we will
14433      be returning into someone else's stack frame, one word below the
14434      stack address we wish to restore.  */
14435   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14436   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14437   tmp = gen_rtx_MEM (Pmode, tmp);
14438   emit_move_insn (tmp, ra);
14439
14440   if (Pmode == SImode)
14441     emit_jump_insn (gen_eh_return_si (sa));
14442   else
14443     emit_jump_insn (gen_eh_return_di (sa));
14444   emit_barrier ();
14445   DONE;
14446 })
14447
14448 (define_insn_and_split "eh_return_si"
14449   [(set (pc)
14450         (unspec [(match_operand:SI 0 "register_operand" "c")]
14451                  UNSPEC_EH_RETURN))]
14452   "!TARGET_64BIT"
14453   "#"
14454   "reload_completed"
14455   [(const_int 1)]
14456   "ix86_expand_epilogue (2); DONE;")
14457
14458 (define_insn_and_split "eh_return_di"
14459   [(set (pc)
14460         (unspec [(match_operand:DI 0 "register_operand" "c")]
14461                  UNSPEC_EH_RETURN))]
14462   "TARGET_64BIT"
14463   "#"
14464   "reload_completed"
14465   [(const_int 1)]
14466   "ix86_expand_epilogue (2); DONE;")
14467
14468 (define_insn "leave"
14469   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14470    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14471    (clobber (mem:BLK (scratch)))]
14472   "!TARGET_64BIT"
14473   "leave"
14474   [(set_attr "type" "leave")])
14475
14476 (define_insn "leave_rex64"
14477   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14478    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14479    (clobber (mem:BLK (scratch)))]
14480   "TARGET_64BIT"
14481   "leave"
14482   [(set_attr "type" "leave")])
14483 \f
14484 (define_expand "ffssi2"
14485   [(parallel
14486      [(set (match_operand:SI 0 "register_operand" "")
14487            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14488       (clobber (match_scratch:SI 2 ""))
14489       (clobber (reg:CC FLAGS_REG))])]
14490   ""
14491   "")
14492
14493 (define_insn_and_split "*ffs_cmove"
14494   [(set (match_operand:SI 0 "register_operand" "=r")
14495         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14496    (clobber (match_scratch:SI 2 "=&r"))
14497    (clobber (reg:CC FLAGS_REG))]
14498   "TARGET_CMOVE"
14499   "#"
14500   "&& reload_completed"
14501   [(set (match_dup 2) (const_int -1))
14502    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14503               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14504    (set (match_dup 0) (if_then_else:SI
14505                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14506                         (match_dup 2)
14507                         (match_dup 0)))
14508    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14509               (clobber (reg:CC FLAGS_REG))])]
14510   "")
14511
14512 (define_insn_and_split "*ffs_no_cmove"
14513   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14514         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14515    (clobber (match_scratch:SI 2 "=&q"))
14516    (clobber (reg:CC FLAGS_REG))]
14517   ""
14518   "#"
14519   "reload_completed"
14520   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14521               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14522    (set (strict_low_part (match_dup 3))
14523         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14524    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14525               (clobber (reg:CC FLAGS_REG))])
14526    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14527               (clobber (reg:CC FLAGS_REG))])
14528    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14529               (clobber (reg:CC FLAGS_REG))])]
14530 {
14531   operands[3] = gen_lowpart (QImode, operands[2]);
14532   ix86_expand_clear (operands[2]);
14533 })
14534
14535 (define_insn "*ffssi_1"
14536   [(set (reg:CCZ FLAGS_REG)
14537         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14538                      (const_int 0)))
14539    (set (match_operand:SI 0 "register_operand" "=r")
14540         (ctz:SI (match_dup 1)))]
14541   ""
14542   "bsf{l}\t{%1, %0|%0, %1}"
14543   [(set_attr "prefix_0f" "1")])
14544
14545 (define_expand "ffsdi2"
14546   [(parallel
14547      [(set (match_operand:DI 0 "register_operand" "")
14548            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14549       (clobber (match_scratch:DI 2 ""))
14550       (clobber (reg:CC FLAGS_REG))])]
14551   "TARGET_64BIT && TARGET_CMOVE"
14552   "")
14553
14554 (define_insn_and_split "*ffs_rex64"
14555   [(set (match_operand:DI 0 "register_operand" "=r")
14556         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14557    (clobber (match_scratch:DI 2 "=&r"))
14558    (clobber (reg:CC FLAGS_REG))]
14559   "TARGET_64BIT && TARGET_CMOVE"
14560   "#"
14561   "&& reload_completed"
14562   [(set (match_dup 2) (const_int -1))
14563    (parallel [(set (reg:CCZ FLAGS_REG)
14564                    (compare:CCZ (match_dup 1) (const_int 0)))
14565               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14566    (set (match_dup 0) (if_then_else:DI
14567                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14568                         (match_dup 2)
14569                         (match_dup 0)))
14570    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14571               (clobber (reg:CC FLAGS_REG))])]
14572   "")
14573
14574 (define_insn "*ffsdi_1"
14575   [(set (reg:CCZ FLAGS_REG)
14576         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14577                      (const_int 0)))
14578    (set (match_operand:DI 0 "register_operand" "=r")
14579         (ctz:DI (match_dup 1)))]
14580   "TARGET_64BIT"
14581   "bsf{q}\t{%1, %0|%0, %1}"
14582   [(set_attr "prefix_0f" "1")])
14583
14584 (define_insn "ctzsi2"
14585   [(set (match_operand:SI 0 "register_operand" "=r")
14586         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14587    (clobber (reg:CC FLAGS_REG))]
14588   ""
14589   "bsf{l}\t{%1, %0|%0, %1}"
14590   [(set_attr "prefix_0f" "1")])
14591
14592 (define_insn "ctzdi2"
14593   [(set (match_operand:DI 0 "register_operand" "=r")
14594         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14595    (clobber (reg:CC FLAGS_REG))]
14596   "TARGET_64BIT"
14597   "bsf{q}\t{%1, %0|%0, %1}"
14598   [(set_attr "prefix_0f" "1")])
14599
14600 (define_expand "clzsi2"
14601   [(parallel
14602      [(set (match_operand:SI 0 "register_operand" "")
14603            (minus:SI (const_int 31)
14604                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14605       (clobber (reg:CC FLAGS_REG))])
14606    (parallel
14607      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14608       (clobber (reg:CC FLAGS_REG))])]
14609   ""
14610   "")
14611
14612 (define_insn "*bsr"
14613   [(set (match_operand:SI 0 "register_operand" "=r")
14614         (minus:SI (const_int 31)
14615                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14616    (clobber (reg:CC FLAGS_REG))]
14617   ""
14618   "bsr{l}\t{%1, %0|%0, %1}"
14619   [(set_attr "prefix_0f" "1")])
14620
14621 (define_insn "bswapsi2"
14622   [(set (match_operand:SI 0 "register_operand" "=r")
14623         (bswap:SI (match_operand:SI 1 "register_operand" "0")))
14624    (clobber (reg:CC FLAGS_REG))]
14625   "TARGET_BSWAP"
14626   "bswap\t%k0"
14627   [(set_attr "prefix_0f" "1")
14628    (set_attr "length" "2")])
14629
14630 (define_insn "bswapdi2"
14631   [(set (match_operand:DI 0 "register_operand" "=r")
14632         (bswap:DI (match_operand:DI 1 "register_operand" "0")))
14633    (clobber (reg:CC FLAGS_REG))]
14634   "TARGET_64BIT && TARGET_BSWAP"
14635   "bswap\t%0"
14636   [(set_attr "prefix_0f" "1")
14637    (set_attr "length" "3")])
14638
14639 (define_expand "clzdi2"
14640   [(parallel
14641      [(set (match_operand:DI 0 "register_operand" "")
14642            (minus:DI (const_int 63)
14643                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14644       (clobber (reg:CC FLAGS_REG))])
14645    (parallel
14646      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14647       (clobber (reg:CC FLAGS_REG))])]
14648   "TARGET_64BIT"
14649   "")
14650
14651 (define_insn "*bsr_rex64"
14652   [(set (match_operand:DI 0 "register_operand" "=r")
14653         (minus:DI (const_int 63)
14654                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14655    (clobber (reg:CC FLAGS_REG))]
14656   "TARGET_64BIT"
14657   "bsr{q}\t{%1, %0|%0, %1}"
14658   [(set_attr "prefix_0f" "1")])
14659 \f
14660 ;; Thread-local storage patterns for ELF.
14661 ;;
14662 ;; Note that these code sequences must appear exactly as shown
14663 ;; in order to allow linker relaxation.
14664
14665 (define_insn "*tls_global_dynamic_32_gnu"
14666   [(set (match_operand:SI 0 "register_operand" "=a")
14667         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14668                     (match_operand:SI 2 "tls_symbolic_operand" "")
14669                     (match_operand:SI 3 "call_insn_operand" "")]
14670                     UNSPEC_TLS_GD))
14671    (clobber (match_scratch:SI 4 "=d"))
14672    (clobber (match_scratch:SI 5 "=c"))
14673    (clobber (reg:CC FLAGS_REG))]
14674   "!TARGET_64BIT && TARGET_GNU_TLS"
14675   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14676   [(set_attr "type" "multi")
14677    (set_attr "length" "12")])
14678
14679 (define_insn "*tls_global_dynamic_32_sun"
14680   [(set (match_operand:SI 0 "register_operand" "=a")
14681         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14682                     (match_operand:SI 2 "tls_symbolic_operand" "")
14683                     (match_operand:SI 3 "call_insn_operand" "")]
14684                     UNSPEC_TLS_GD))
14685    (clobber (match_scratch:SI 4 "=d"))
14686    (clobber (match_scratch:SI 5 "=c"))
14687    (clobber (reg:CC FLAGS_REG))]
14688   "!TARGET_64BIT && TARGET_SUN_TLS"
14689   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14690         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14691   [(set_attr "type" "multi")
14692    (set_attr "length" "14")])
14693
14694 (define_expand "tls_global_dynamic_32"
14695   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14696                    (unspec:SI
14697                     [(match_dup 2)
14698                      (match_operand:SI 1 "tls_symbolic_operand" "")
14699                      (match_dup 3)]
14700                     UNSPEC_TLS_GD))
14701               (clobber (match_scratch:SI 4 ""))
14702               (clobber (match_scratch:SI 5 ""))
14703               (clobber (reg:CC FLAGS_REG))])]
14704   ""
14705 {
14706   if (flag_pic)
14707     operands[2] = pic_offset_table_rtx;
14708   else
14709     {
14710       operands[2] = gen_reg_rtx (Pmode);
14711       emit_insn (gen_set_got (operands[2]));
14712     }
14713   if (TARGET_GNU2_TLS)
14714     {
14715        emit_insn (gen_tls_dynamic_gnu2_32
14716                   (operands[0], operands[1], operands[2]));
14717        DONE;
14718     }
14719   operands[3] = ix86_tls_get_addr ();
14720 })
14721
14722 (define_insn "*tls_global_dynamic_64"
14723   [(set (match_operand:DI 0 "register_operand" "=a")
14724         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14725                  (match_operand:DI 3 "" "")))
14726    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14727               UNSPEC_TLS_GD)]
14728   "TARGET_64BIT"
14729   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14730   [(set_attr "type" "multi")
14731    (set_attr "length" "16")])
14732
14733 (define_expand "tls_global_dynamic_64"
14734   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14735                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14736               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14737                          UNSPEC_TLS_GD)])]
14738   ""
14739 {
14740   if (TARGET_GNU2_TLS)
14741     {
14742        emit_insn (gen_tls_dynamic_gnu2_64
14743                   (operands[0], operands[1]));
14744        DONE;
14745     }
14746   operands[2] = ix86_tls_get_addr ();
14747 })
14748
14749 (define_insn "*tls_local_dynamic_base_32_gnu"
14750   [(set (match_operand:SI 0 "register_operand" "=a")
14751         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14752                     (match_operand:SI 2 "call_insn_operand" "")]
14753                    UNSPEC_TLS_LD_BASE))
14754    (clobber (match_scratch:SI 3 "=d"))
14755    (clobber (match_scratch:SI 4 "=c"))
14756    (clobber (reg:CC FLAGS_REG))]
14757   "!TARGET_64BIT && TARGET_GNU_TLS"
14758   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14759   [(set_attr "type" "multi")
14760    (set_attr "length" "11")])
14761
14762 (define_insn "*tls_local_dynamic_base_32_sun"
14763   [(set (match_operand:SI 0 "register_operand" "=a")
14764         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14765                     (match_operand:SI 2 "call_insn_operand" "")]
14766                    UNSPEC_TLS_LD_BASE))
14767    (clobber (match_scratch:SI 3 "=d"))
14768    (clobber (match_scratch:SI 4 "=c"))
14769    (clobber (reg:CC FLAGS_REG))]
14770   "!TARGET_64BIT && TARGET_SUN_TLS"
14771   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14772         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14773   [(set_attr "type" "multi")
14774    (set_attr "length" "13")])
14775
14776 (define_expand "tls_local_dynamic_base_32"
14777   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14778                    (unspec:SI [(match_dup 1) (match_dup 2)]
14779                               UNSPEC_TLS_LD_BASE))
14780               (clobber (match_scratch:SI 3 ""))
14781               (clobber (match_scratch:SI 4 ""))
14782               (clobber (reg:CC FLAGS_REG))])]
14783   ""
14784 {
14785   if (flag_pic)
14786     operands[1] = pic_offset_table_rtx;
14787   else
14788     {
14789       operands[1] = gen_reg_rtx (Pmode);
14790       emit_insn (gen_set_got (operands[1]));
14791     }
14792   if (TARGET_GNU2_TLS)
14793     {
14794        emit_insn (gen_tls_dynamic_gnu2_32
14795                   (operands[0], ix86_tls_module_base (), operands[1]));
14796        DONE;
14797     }
14798   operands[2] = ix86_tls_get_addr ();
14799 })
14800
14801 (define_insn "*tls_local_dynamic_base_64"
14802   [(set (match_operand:DI 0 "register_operand" "=a")
14803         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14804                  (match_operand:DI 2 "" "")))
14805    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14806   "TARGET_64BIT"
14807   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14808   [(set_attr "type" "multi")
14809    (set_attr "length" "12")])
14810
14811 (define_expand "tls_local_dynamic_base_64"
14812   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14813                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14814               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14815   ""
14816 {
14817   if (TARGET_GNU2_TLS)
14818     {
14819        emit_insn (gen_tls_dynamic_gnu2_64
14820                   (operands[0], ix86_tls_module_base ()));
14821        DONE;
14822     }
14823   operands[1] = ix86_tls_get_addr ();
14824 })
14825
14826 ;; Local dynamic of a single variable is a lose.  Show combine how
14827 ;; to convert that back to global dynamic.
14828
14829 (define_insn_and_split "*tls_local_dynamic_32_once"
14830   [(set (match_operand:SI 0 "register_operand" "=a")
14831         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14832                              (match_operand:SI 2 "call_insn_operand" "")]
14833                             UNSPEC_TLS_LD_BASE)
14834                  (const:SI (unspec:SI
14835                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14836                             UNSPEC_DTPOFF))))
14837    (clobber (match_scratch:SI 4 "=d"))
14838    (clobber (match_scratch:SI 5 "=c"))
14839    (clobber (reg:CC FLAGS_REG))]
14840   ""
14841   "#"
14842   ""
14843   [(parallel [(set (match_dup 0)
14844                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14845                               UNSPEC_TLS_GD))
14846               (clobber (match_dup 4))
14847               (clobber (match_dup 5))
14848               (clobber (reg:CC FLAGS_REG))])]
14849   "")
14850
14851 ;; Load and add the thread base pointer from %gs:0.
14852
14853 (define_insn "*load_tp_si"
14854   [(set (match_operand:SI 0 "register_operand" "=r")
14855         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14856   "!TARGET_64BIT"
14857   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14858   [(set_attr "type" "imov")
14859    (set_attr "modrm" "0")
14860    (set_attr "length" "7")
14861    (set_attr "memory" "load")
14862    (set_attr "imm_disp" "false")])
14863
14864 (define_insn "*add_tp_si"
14865   [(set (match_operand:SI 0 "register_operand" "=r")
14866         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14867                  (match_operand:SI 1 "register_operand" "0")))
14868    (clobber (reg:CC FLAGS_REG))]
14869   "!TARGET_64BIT"
14870   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14871   [(set_attr "type" "alu")
14872    (set_attr "modrm" "0")
14873    (set_attr "length" "7")
14874    (set_attr "memory" "load")
14875    (set_attr "imm_disp" "false")])
14876
14877 (define_insn "*load_tp_di"
14878   [(set (match_operand:DI 0 "register_operand" "=r")
14879         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14880   "TARGET_64BIT"
14881   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14882   [(set_attr "type" "imov")
14883    (set_attr "modrm" "0")
14884    (set_attr "length" "7")
14885    (set_attr "memory" "load")
14886    (set_attr "imm_disp" "false")])
14887
14888 (define_insn "*add_tp_di"
14889   [(set (match_operand:DI 0 "register_operand" "=r")
14890         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14891                  (match_operand:DI 1 "register_operand" "0")))
14892    (clobber (reg:CC FLAGS_REG))]
14893   "TARGET_64BIT"
14894   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14895   [(set_attr "type" "alu")
14896    (set_attr "modrm" "0")
14897    (set_attr "length" "7")
14898    (set_attr "memory" "load")
14899    (set_attr "imm_disp" "false")])
14900
14901 ;; GNU2 TLS patterns can be split.
14902
14903 (define_expand "tls_dynamic_gnu2_32"
14904   [(set (match_dup 3)
14905         (plus:SI (match_operand:SI 2 "register_operand" "")
14906                  (const:SI
14907                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14908                              UNSPEC_TLSDESC))))
14909    (parallel
14910     [(set (match_operand:SI 0 "register_operand" "")
14911           (unspec:SI [(match_dup 1) (match_dup 3)
14912                       (match_dup 2) (reg:SI SP_REG)]
14913                       UNSPEC_TLSDESC))
14914      (clobber (reg:CC FLAGS_REG))])]
14915   "!TARGET_64BIT && TARGET_GNU2_TLS"
14916 {
14917   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14918   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14919 })
14920
14921 (define_insn "*tls_dynamic_lea_32"
14922   [(set (match_operand:SI 0 "register_operand" "=r")
14923         (plus:SI (match_operand:SI 1 "register_operand" "b")
14924                  (const:SI
14925                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14926                               UNSPEC_TLSDESC))))]
14927   "!TARGET_64BIT && TARGET_GNU2_TLS"
14928   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14929   [(set_attr "type" "lea")
14930    (set_attr "mode" "SI")
14931    (set_attr "length" "6")
14932    (set_attr "length_address" "4")])
14933
14934 (define_insn "*tls_dynamic_call_32"
14935   [(set (match_operand:SI 0 "register_operand" "=a")
14936         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14937                     (match_operand:SI 2 "register_operand" "0")
14938                     ;; we have to make sure %ebx still points to the GOT
14939                     (match_operand:SI 3 "register_operand" "b")
14940                     (reg:SI SP_REG)]
14941                    UNSPEC_TLSDESC))
14942    (clobber (reg:CC FLAGS_REG))]
14943   "!TARGET_64BIT && TARGET_GNU2_TLS"
14944   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14945   [(set_attr "type" "call")
14946    (set_attr "length" "2")
14947    (set_attr "length_address" "0")])
14948
14949 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14950   [(set (match_operand:SI 0 "register_operand" "=&a")
14951         (plus:SI
14952          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14953                      (match_operand:SI 4 "" "")
14954                      (match_operand:SI 2 "register_operand" "b")
14955                      (reg:SI SP_REG)]
14956                     UNSPEC_TLSDESC)
14957          (const:SI (unspec:SI
14958                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
14959                     UNSPEC_DTPOFF))))
14960    (clobber (reg:CC FLAGS_REG))]
14961   "!TARGET_64BIT && TARGET_GNU2_TLS"
14962   "#"
14963   ""
14964   [(set (match_dup 0) (match_dup 5))]
14965 {
14966   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14967   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14968 })
14969
14970 (define_expand "tls_dynamic_gnu2_64"
14971   [(set (match_dup 2)
14972         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14973                    UNSPEC_TLSDESC))
14974    (parallel
14975     [(set (match_operand:DI 0 "register_operand" "")
14976           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14977                      UNSPEC_TLSDESC))
14978      (clobber (reg:CC FLAGS_REG))])]
14979   "TARGET_64BIT && TARGET_GNU2_TLS"
14980 {
14981   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14982   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14983 })
14984
14985 (define_insn "*tls_dynamic_lea_64"
14986   [(set (match_operand:DI 0 "register_operand" "=r")
14987         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14988                    UNSPEC_TLSDESC))]
14989   "TARGET_64BIT && TARGET_GNU2_TLS"
14990   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14991   [(set_attr "type" "lea")
14992    (set_attr "mode" "DI")
14993    (set_attr "length" "7")
14994    (set_attr "length_address" "4")])
14995
14996 (define_insn "*tls_dynamic_call_64"
14997   [(set (match_operand:DI 0 "register_operand" "=a")
14998         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14999                     (match_operand:DI 2 "register_operand" "0")
15000                     (reg:DI SP_REG)]
15001                    UNSPEC_TLSDESC))
15002    (clobber (reg:CC FLAGS_REG))]
15003   "TARGET_64BIT && TARGET_GNU2_TLS"
15004   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15005   [(set_attr "type" "call")
15006    (set_attr "length" "2")
15007    (set_attr "length_address" "0")])
15008
15009 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15010   [(set (match_operand:DI 0 "register_operand" "=&a")
15011         (plus:DI
15012          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15013                      (match_operand:DI 3 "" "")
15014                      (reg:DI SP_REG)]
15015                     UNSPEC_TLSDESC)
15016          (const:DI (unspec:DI
15017                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15018                     UNSPEC_DTPOFF))))
15019    (clobber (reg:CC FLAGS_REG))]
15020   "TARGET_64BIT && TARGET_GNU2_TLS"
15021   "#"
15022   ""
15023   [(set (match_dup 0) (match_dup 4))]
15024 {
15025   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15026   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15027 })
15028
15029 ;;
15030 \f
15031 ;; These patterns match the binary 387 instructions for addM3, subM3,
15032 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15033 ;; SFmode.  The first is the normal insn, the second the same insn but
15034 ;; with one operand a conversion, and the third the same insn but with
15035 ;; the other operand a conversion.  The conversion may be SFmode or
15036 ;; SImode if the target mode DFmode, but only SImode if the target mode
15037 ;; is SFmode.
15038
15039 ;; Gcc is slightly more smart about handling normal two address instructions
15040 ;; so use special patterns for add and mull.
15041
15042 (define_insn "*fop_sf_comm_mixed"
15043   [(set (match_operand:SF 0 "register_operand" "=f,x")
15044         (match_operator:SF 3 "binary_fp_operator"
15045                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15046                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15047   "TARGET_MIX_SSE_I387
15048    && COMMUTATIVE_ARITH_P (operands[3])
15049    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15050   "* return output_387_binary_op (insn, operands);"
15051   [(set (attr "type")
15052         (if_then_else (eq_attr "alternative" "1")
15053            (if_then_else (match_operand:SF 3 "mult_operator" "")
15054               (const_string "ssemul")
15055               (const_string "sseadd"))
15056            (if_then_else (match_operand:SF 3 "mult_operator" "")
15057               (const_string "fmul")
15058               (const_string "fop"))))
15059    (set_attr "mode" "SF")])
15060
15061 (define_insn "*fop_sf_comm_sse"
15062   [(set (match_operand:SF 0 "register_operand" "=x")
15063         (match_operator:SF 3 "binary_fp_operator"
15064                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15065                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15066   "TARGET_SSE_MATH
15067    && COMMUTATIVE_ARITH_P (operands[3])
15068    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15069   "* return output_387_binary_op (insn, operands);"
15070   [(set (attr "type")
15071         (if_then_else (match_operand:SF 3 "mult_operator" "")
15072            (const_string "ssemul")
15073            (const_string "sseadd")))
15074    (set_attr "mode" "SF")])
15075
15076 (define_insn "*fop_sf_comm_i387"
15077   [(set (match_operand:SF 0 "register_operand" "=f")
15078         (match_operator:SF 3 "binary_fp_operator"
15079                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15080                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15081   "TARGET_80387
15082    && COMMUTATIVE_ARITH_P (operands[3])
15083    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15084   "* return output_387_binary_op (insn, operands);"
15085   [(set (attr "type")
15086         (if_then_else (match_operand:SF 3 "mult_operator" "")
15087            (const_string "fmul")
15088            (const_string "fop")))
15089    (set_attr "mode" "SF")])
15090
15091 (define_insn "*fop_sf_1_mixed"
15092   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15093         (match_operator:SF 3 "binary_fp_operator"
15094                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15095                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15096   "TARGET_MIX_SSE_I387
15097    && !COMMUTATIVE_ARITH_P (operands[3])
15098    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15099   "* return output_387_binary_op (insn, operands);"
15100   [(set (attr "type")
15101         (cond [(and (eq_attr "alternative" "2")
15102                     (match_operand:SF 3 "mult_operator" ""))
15103                  (const_string "ssemul")
15104                (and (eq_attr "alternative" "2")
15105                     (match_operand:SF 3 "div_operator" ""))
15106                  (const_string "ssediv")
15107                (eq_attr "alternative" "2")
15108                  (const_string "sseadd")
15109                (match_operand:SF 3 "mult_operator" "")
15110                  (const_string "fmul")
15111                (match_operand:SF 3 "div_operator" "")
15112                  (const_string "fdiv")
15113               ]
15114               (const_string "fop")))
15115    (set_attr "mode" "SF")])
15116
15117 (define_insn "*fop_sf_1_sse"
15118   [(set (match_operand:SF 0 "register_operand" "=x")
15119         (match_operator:SF 3 "binary_fp_operator"
15120                         [(match_operand:SF 1 "register_operand" "0")
15121                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15122   "TARGET_SSE_MATH
15123    && !COMMUTATIVE_ARITH_P (operands[3])"
15124   "* return output_387_binary_op (insn, operands);"
15125   [(set (attr "type")
15126         (cond [(match_operand:SF 3 "mult_operator" "")
15127                  (const_string "ssemul")
15128                (match_operand:SF 3 "div_operator" "")
15129                  (const_string "ssediv")
15130               ]
15131               (const_string "sseadd")))
15132    (set_attr "mode" "SF")])
15133
15134 ;; This pattern is not fully shadowed by the pattern above.
15135 (define_insn "*fop_sf_1_i387"
15136   [(set (match_operand:SF 0 "register_operand" "=f,f")
15137         (match_operator:SF 3 "binary_fp_operator"
15138                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15139                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15140   "TARGET_80387 && !TARGET_SSE_MATH
15141    && !COMMUTATIVE_ARITH_P (operands[3])
15142    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15143   "* return output_387_binary_op (insn, operands);"
15144   [(set (attr "type")
15145         (cond [(match_operand:SF 3 "mult_operator" "")
15146                  (const_string "fmul")
15147                (match_operand:SF 3 "div_operator" "")
15148                  (const_string "fdiv")
15149               ]
15150               (const_string "fop")))
15151    (set_attr "mode" "SF")])
15152
15153 ;; ??? Add SSE splitters for these!
15154 (define_insn "*fop_sf_2<mode>_i387"
15155   [(set (match_operand:SF 0 "register_operand" "=f,f")
15156         (match_operator:SF 3 "binary_fp_operator"
15157           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15158            (match_operand:SF 2 "register_operand" "0,0")]))]
15159   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15160   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15161   [(set (attr "type")
15162         (cond [(match_operand:SF 3 "mult_operator" "")
15163                  (const_string "fmul")
15164                (match_operand:SF 3 "div_operator" "")
15165                  (const_string "fdiv")
15166               ]
15167               (const_string "fop")))
15168    (set_attr "fp_int_src" "true")
15169    (set_attr "mode" "<MODE>")])
15170
15171 (define_insn "*fop_sf_3<mode>_i387"
15172   [(set (match_operand:SF 0 "register_operand" "=f,f")
15173         (match_operator:SF 3 "binary_fp_operator"
15174           [(match_operand:SF 1 "register_operand" "0,0")
15175            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15176   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15177   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15178   [(set (attr "type")
15179         (cond [(match_operand:SF 3 "mult_operator" "")
15180                  (const_string "fmul")
15181                (match_operand:SF 3 "div_operator" "")
15182                  (const_string "fdiv")
15183               ]
15184               (const_string "fop")))
15185    (set_attr "fp_int_src" "true")
15186    (set_attr "mode" "<MODE>")])
15187
15188 (define_insn "*fop_df_comm_mixed"
15189   [(set (match_operand:DF 0 "register_operand" "=f,Y")
15190         (match_operator:DF 3 "binary_fp_operator"
15191                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15192                          (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15193   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15194    && COMMUTATIVE_ARITH_P (operands[3])
15195    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15196   "* return output_387_binary_op (insn, operands);"
15197   [(set (attr "type")
15198         (if_then_else (eq_attr "alternative" "1")
15199            (if_then_else (match_operand:DF 3 "mult_operator" "")
15200               (const_string "ssemul")
15201               (const_string "sseadd"))
15202            (if_then_else (match_operand:DF 3 "mult_operator" "")
15203               (const_string "fmul")
15204               (const_string "fop"))))
15205    (set_attr "mode" "DF")])
15206
15207 (define_insn "*fop_df_comm_sse"
15208   [(set (match_operand:DF 0 "register_operand" "=Y")
15209         (match_operator:DF 3 "binary_fp_operator"
15210                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15211                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15212   "TARGET_SSE2 && TARGET_SSE_MATH
15213    && COMMUTATIVE_ARITH_P (operands[3])
15214    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15215   "* return output_387_binary_op (insn, operands);"
15216   [(set (attr "type")
15217         (if_then_else (match_operand:DF 3 "mult_operator" "")
15218            (const_string "ssemul")
15219            (const_string "sseadd")))
15220    (set_attr "mode" "DF")])
15221
15222 (define_insn "*fop_df_comm_i387"
15223   [(set (match_operand:DF 0 "register_operand" "=f")
15224         (match_operator:DF 3 "binary_fp_operator"
15225                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15226                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15227   "TARGET_80387
15228    && COMMUTATIVE_ARITH_P (operands[3])
15229    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15230   "* return output_387_binary_op (insn, operands);"
15231   [(set (attr "type")
15232         (if_then_else (match_operand:DF 3 "mult_operator" "")
15233            (const_string "fmul")
15234            (const_string "fop")))
15235    (set_attr "mode" "DF")])
15236
15237 (define_insn "*fop_df_1_mixed"
15238   [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15239         (match_operator:DF 3 "binary_fp_operator"
15240                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15241                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15242   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15243    && !COMMUTATIVE_ARITH_P (operands[3])
15244    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15245   "* return output_387_binary_op (insn, operands);"
15246   [(set (attr "type")
15247         (cond [(and (eq_attr "alternative" "2")
15248                     (match_operand:DF 3 "mult_operator" ""))
15249                  (const_string "ssemul")
15250                (and (eq_attr "alternative" "2")
15251                     (match_operand:DF 3 "div_operator" ""))
15252                  (const_string "ssediv")
15253                (eq_attr "alternative" "2")
15254                  (const_string "sseadd")
15255                (match_operand:DF 3 "mult_operator" "")
15256                  (const_string "fmul")
15257                (match_operand:DF 3 "div_operator" "")
15258                  (const_string "fdiv")
15259               ]
15260               (const_string "fop")))
15261    (set_attr "mode" "DF")])
15262
15263 (define_insn "*fop_df_1_sse"
15264   [(set (match_operand:DF 0 "register_operand" "=Y")
15265         (match_operator:DF 3 "binary_fp_operator"
15266                         [(match_operand:DF 1 "register_operand" "0")
15267                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15268   "TARGET_SSE2 && TARGET_SSE_MATH
15269    && !COMMUTATIVE_ARITH_P (operands[3])"
15270   "* return output_387_binary_op (insn, operands);"
15271   [(set_attr "mode" "DF")
15272    (set (attr "type")
15273         (cond [(match_operand:DF 3 "mult_operator" "")
15274                  (const_string "ssemul")
15275                (match_operand:DF 3 "div_operator" "")
15276                  (const_string "ssediv")
15277               ]
15278               (const_string "sseadd")))])
15279
15280 ;; This pattern is not fully shadowed by the pattern above.
15281 (define_insn "*fop_df_1_i387"
15282   [(set (match_operand:DF 0 "register_operand" "=f,f")
15283         (match_operator:DF 3 "binary_fp_operator"
15284                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15285                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15286   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15287    && !COMMUTATIVE_ARITH_P (operands[3])
15288    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15289   "* return output_387_binary_op (insn, operands);"
15290   [(set (attr "type")
15291         (cond [(match_operand:DF 3 "mult_operator" "")
15292                  (const_string "fmul")
15293                (match_operand:DF 3 "div_operator" "")
15294                  (const_string "fdiv")
15295               ]
15296               (const_string "fop")))
15297    (set_attr "mode" "DF")])
15298
15299 ;; ??? Add SSE splitters for these!
15300 (define_insn "*fop_df_2<mode>_i387"
15301   [(set (match_operand:DF 0 "register_operand" "=f,f")
15302         (match_operator:DF 3 "binary_fp_operator"
15303            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15304             (match_operand:DF 2 "register_operand" "0,0")]))]
15305   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15306    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15307   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15308   [(set (attr "type")
15309         (cond [(match_operand:DF 3 "mult_operator" "")
15310                  (const_string "fmul")
15311                (match_operand:DF 3 "div_operator" "")
15312                  (const_string "fdiv")
15313               ]
15314               (const_string "fop")))
15315    (set_attr "fp_int_src" "true")
15316    (set_attr "mode" "<MODE>")])
15317
15318 (define_insn "*fop_df_3<mode>_i387"
15319   [(set (match_operand:DF 0 "register_operand" "=f,f")
15320         (match_operator:DF 3 "binary_fp_operator"
15321            [(match_operand:DF 1 "register_operand" "0,0")
15322             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15323   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15324    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15325   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15326   [(set (attr "type")
15327         (cond [(match_operand:DF 3 "mult_operator" "")
15328                  (const_string "fmul")
15329                (match_operand:DF 3 "div_operator" "")
15330                  (const_string "fdiv")
15331               ]
15332               (const_string "fop")))
15333    (set_attr "fp_int_src" "true")
15334    (set_attr "mode" "<MODE>")])
15335
15336 (define_insn "*fop_df_4_i387"
15337   [(set (match_operand:DF 0 "register_operand" "=f,f")
15338         (match_operator:DF 3 "binary_fp_operator"
15339            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15340             (match_operand:DF 2 "register_operand" "0,f")]))]
15341   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15342    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15343   "* return output_387_binary_op (insn, operands);"
15344   [(set (attr "type")
15345         (cond [(match_operand:DF 3 "mult_operator" "")
15346                  (const_string "fmul")
15347                (match_operand:DF 3 "div_operator" "")
15348                  (const_string "fdiv")
15349               ]
15350               (const_string "fop")))
15351    (set_attr "mode" "SF")])
15352
15353 (define_insn "*fop_df_5_i387"
15354   [(set (match_operand:DF 0 "register_operand" "=f,f")
15355         (match_operator:DF 3 "binary_fp_operator"
15356           [(match_operand:DF 1 "register_operand" "0,f")
15357            (float_extend:DF
15358             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15359   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15360   "* return output_387_binary_op (insn, operands);"
15361   [(set (attr "type")
15362         (cond [(match_operand:DF 3 "mult_operator" "")
15363                  (const_string "fmul")
15364                (match_operand:DF 3 "div_operator" "")
15365                  (const_string "fdiv")
15366               ]
15367               (const_string "fop")))
15368    (set_attr "mode" "SF")])
15369
15370 (define_insn "*fop_df_6_i387"
15371   [(set (match_operand:DF 0 "register_operand" "=f,f")
15372         (match_operator:DF 3 "binary_fp_operator"
15373           [(float_extend:DF
15374             (match_operand:SF 1 "register_operand" "0,f"))
15375            (float_extend:DF
15376             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15377   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15378   "* return output_387_binary_op (insn, operands);"
15379   [(set (attr "type")
15380         (cond [(match_operand:DF 3 "mult_operator" "")
15381                  (const_string "fmul")
15382                (match_operand:DF 3 "div_operator" "")
15383                  (const_string "fdiv")
15384               ]
15385               (const_string "fop")))
15386    (set_attr "mode" "SF")])
15387
15388 (define_insn "*fop_xf_comm_i387"
15389   [(set (match_operand:XF 0 "register_operand" "=f")
15390         (match_operator:XF 3 "binary_fp_operator"
15391                         [(match_operand:XF 1 "register_operand" "%0")
15392                          (match_operand:XF 2 "register_operand" "f")]))]
15393   "TARGET_80387
15394    && COMMUTATIVE_ARITH_P (operands[3])"
15395   "* return output_387_binary_op (insn, operands);"
15396   [(set (attr "type")
15397         (if_then_else (match_operand:XF 3 "mult_operator" "")
15398            (const_string "fmul")
15399            (const_string "fop")))
15400    (set_attr "mode" "XF")])
15401
15402 (define_insn "*fop_xf_1_i387"
15403   [(set (match_operand:XF 0 "register_operand" "=f,f")
15404         (match_operator:XF 3 "binary_fp_operator"
15405                         [(match_operand:XF 1 "register_operand" "0,f")
15406                          (match_operand:XF 2 "register_operand" "f,0")]))]
15407   "TARGET_80387
15408    && !COMMUTATIVE_ARITH_P (operands[3])"
15409   "* return output_387_binary_op (insn, operands);"
15410   [(set (attr "type")
15411         (cond [(match_operand:XF 3 "mult_operator" "")
15412                  (const_string "fmul")
15413                (match_operand:XF 3 "div_operator" "")
15414                  (const_string "fdiv")
15415               ]
15416               (const_string "fop")))
15417    (set_attr "mode" "XF")])
15418
15419 (define_insn "*fop_xf_2<mode>_i387"
15420   [(set (match_operand:XF 0 "register_operand" "=f,f")
15421         (match_operator:XF 3 "binary_fp_operator"
15422            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15423             (match_operand:XF 2 "register_operand" "0,0")]))]
15424   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15425   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15426   [(set (attr "type")
15427         (cond [(match_operand:XF 3 "mult_operator" "")
15428                  (const_string "fmul")
15429                (match_operand:XF 3 "div_operator" "")
15430                  (const_string "fdiv")
15431               ]
15432               (const_string "fop")))
15433    (set_attr "fp_int_src" "true")
15434    (set_attr "mode" "<MODE>")])
15435
15436 (define_insn "*fop_xf_3<mode>_i387"
15437   [(set (match_operand:XF 0 "register_operand" "=f,f")
15438         (match_operator:XF 3 "binary_fp_operator"
15439           [(match_operand:XF 1 "register_operand" "0,0")
15440            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15441   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15442   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15443   [(set (attr "type")
15444         (cond [(match_operand:XF 3 "mult_operator" "")
15445                  (const_string "fmul")
15446                (match_operand:XF 3 "div_operator" "")
15447                  (const_string "fdiv")
15448               ]
15449               (const_string "fop")))
15450    (set_attr "fp_int_src" "true")
15451    (set_attr "mode" "<MODE>")])
15452
15453 (define_insn "*fop_xf_4_i387"
15454   [(set (match_operand:XF 0 "register_operand" "=f,f")
15455         (match_operator:XF 3 "binary_fp_operator"
15456            [(float_extend:XF
15457               (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
15458             (match_operand:XF 2 "register_operand" "0,f")]))]
15459   "TARGET_80387"
15460   "* return output_387_binary_op (insn, operands);"
15461   [(set (attr "type")
15462         (cond [(match_operand:XF 3 "mult_operator" "")
15463                  (const_string "fmul")
15464                (match_operand:XF 3 "div_operator" "")
15465                  (const_string "fdiv")
15466               ]
15467               (const_string "fop")))
15468    (set_attr "mode" "SF")])
15469
15470 (define_insn "*fop_xf_5_i387"
15471   [(set (match_operand:XF 0 "register_operand" "=f,f")
15472         (match_operator:XF 3 "binary_fp_operator"
15473           [(match_operand:XF 1 "register_operand" "0,f")
15474            (float_extend:XF
15475              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15476   "TARGET_80387"
15477   "* return output_387_binary_op (insn, operands);"
15478   [(set (attr "type")
15479         (cond [(match_operand:XF 3 "mult_operator" "")
15480                  (const_string "fmul")
15481                (match_operand:XF 3 "div_operator" "")
15482                  (const_string "fdiv")
15483               ]
15484               (const_string "fop")))
15485    (set_attr "mode" "SF")])
15486
15487 (define_insn "*fop_xf_6_i387"
15488   [(set (match_operand:XF 0 "register_operand" "=f,f")
15489         (match_operator:XF 3 "binary_fp_operator"
15490           [(float_extend:XF
15491              (match_operand:X87MODEF12 1 "register_operand" "0,f"))
15492            (float_extend:XF
15493              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15494   "TARGET_80387"
15495   "* return output_387_binary_op (insn, operands);"
15496   [(set (attr "type")
15497         (cond [(match_operand:XF 3 "mult_operator" "")
15498                  (const_string "fmul")
15499                (match_operand:XF 3 "div_operator" "")
15500                  (const_string "fdiv")
15501               ]
15502               (const_string "fop")))
15503    (set_attr "mode" "SF")])
15504
15505 (define_split
15506   [(set (match_operand 0 "register_operand" "")
15507         (match_operator 3 "binary_fp_operator"
15508            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15509             (match_operand 2 "register_operand" "")]))]
15510   "TARGET_80387 && reload_completed
15511    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15512   [(const_int 0)]
15513 {
15514   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15515   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15516   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15517                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15518                                           GET_MODE (operands[3]),
15519                                           operands[4],
15520                                           operands[2])));
15521   ix86_free_from_memory (GET_MODE (operands[1]));
15522   DONE;
15523 })
15524
15525 (define_split
15526   [(set (match_operand 0 "register_operand" "")
15527         (match_operator 3 "binary_fp_operator"
15528            [(match_operand 1 "register_operand" "")
15529             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15530   "TARGET_80387 && reload_completed
15531    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15532   [(const_int 0)]
15533 {
15534   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15535   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15536   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15537                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15538                                           GET_MODE (operands[3]),
15539                                           operands[1],
15540                                           operands[4])));
15541   ix86_free_from_memory (GET_MODE (operands[2]));
15542   DONE;
15543 })
15544 \f
15545 ;; FPU special functions.
15546
15547 ;; This pattern implements a no-op XFmode truncation for
15548 ;; all fancy i386 XFmode math functions.
15549
15550 (define_insn "truncxf<mode>2_i387_noop_unspec"
15551   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15552         (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
15553         UNSPEC_TRUNC_NOOP))]
15554   "TARGET_USE_FANCY_MATH_387"
15555   "* return output_387_reg_move (insn, operands);"
15556   [(set_attr "type" "fmov")
15557    (set_attr "mode" "<MODE>")])
15558
15559 (define_insn "sqrtxf2"
15560   [(set (match_operand:XF 0 "register_operand" "=f")
15561         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15562   "TARGET_USE_FANCY_MATH_387"
15563   "fsqrt"
15564   [(set_attr "type" "fpspc")
15565    (set_attr "mode" "XF")
15566    (set_attr "athlon_decode" "direct")])
15567
15568 (define_insn "sqrt_extend<mode>xf2_i387"
15569   [(set (match_operand:XF 0 "register_operand" "=f")
15570         (sqrt:XF
15571           (float_extend:XF
15572             (match_operand:X87MODEF12 1 "register_operand" "0"))))]
15573   "TARGET_USE_FANCY_MATH_387"
15574   "fsqrt"
15575   [(set_attr "type" "fpspc")
15576    (set_attr "mode" "XF")
15577    (set_attr "athlon_decode" "direct")])
15578
15579 (define_insn "*sqrt<mode>2_sse"
15580   [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
15581         (sqrt:SSEMODEF
15582           (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
15583   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15584   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
15585   [(set_attr "type" "sse")
15586    (set_attr "mode" "<MODE>")
15587    (set_attr "athlon_decode" "*")])
15588
15589 (define_expand "sqrt<mode>2"
15590   [(set (match_operand:X87MODEF12 0 "register_operand" "")
15591         (sqrt:X87MODEF12
15592           (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
15593   "TARGET_USE_FANCY_MATH_387
15594    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15595 {
15596   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15597     {
15598       rtx op0 = gen_reg_rtx (XFmode);
15599       rtx op1 = force_reg (<MODE>mode, operands[1]);
15600
15601       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15602       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15603       DONE;
15604    }
15605 })
15606
15607 (define_insn "fpremxf4_i387"
15608   [(set (match_operand:XF 0 "register_operand" "=f")
15609         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15610                     (match_operand:XF 3 "register_operand" "1")]
15611                    UNSPEC_FPREM_F))
15612    (set (match_operand:XF 1 "register_operand" "=u")
15613         (unspec:XF [(match_dup 2) (match_dup 3)]
15614                    UNSPEC_FPREM_U))
15615    (set (reg:CCFP FPSR_REG)
15616         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15617   "TARGET_USE_FANCY_MATH_387"
15618   "fprem"
15619   [(set_attr "type" "fpspc")
15620    (set_attr "mode" "XF")])
15621
15622 (define_expand "fmodxf3"
15623   [(use (match_operand:XF 0 "register_operand" ""))
15624    (use (match_operand:XF 1 "register_operand" ""))
15625    (use (match_operand:XF 2 "register_operand" ""))]
15626   "TARGET_USE_FANCY_MATH_387"
15627 {
15628   rtx label = gen_label_rtx ();
15629
15630   emit_label (label);
15631
15632   emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
15633                                 operands[1], operands[2]));
15634   ix86_emit_fp_unordered_jump (label);
15635
15636   emit_move_insn (operands[0], operands[1]);
15637   DONE;
15638 })
15639
15640 (define_expand "fmod<mode>3"
15641   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15642    (use (match_operand:X87MODEF12 1 "general_operand" ""))
15643    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
15644   "TARGET_USE_FANCY_MATH_387"
15645 {
15646   rtx label = gen_label_rtx ();
15647
15648   rtx op1 = gen_reg_rtx (XFmode);
15649   rtx op2 = gen_reg_rtx (XFmode);
15650
15651   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15652   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15653
15654   emit_label (label);
15655   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15656   ix86_emit_fp_unordered_jump (label);
15657
15658   /* Truncate the result properly for strict SSE math.  */
15659   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15660       && !TARGET_MIX_SSE_I387)
15661     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15662   else
15663     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15664
15665   DONE;
15666 })
15667
15668 (define_insn "fprem1xf4_i387"
15669   [(set (match_operand:XF 0 "register_operand" "=f")
15670         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15671                     (match_operand:XF 3 "register_operand" "1")]
15672                    UNSPEC_FPREM1_F))
15673    (set (match_operand:XF 1 "register_operand" "=u")
15674         (unspec:XF [(match_dup 2) (match_dup 3)]
15675                    UNSPEC_FPREM1_U))
15676    (set (reg:CCFP FPSR_REG)
15677         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15678   "TARGET_USE_FANCY_MATH_387"
15679   "fprem1"
15680   [(set_attr "type" "fpspc")
15681    (set_attr "mode" "XF")])
15682
15683 (define_expand "remainderxf3"
15684   [(use (match_operand:XF 0 "register_operand" ""))
15685    (use (match_operand:XF 1 "register_operand" ""))
15686    (use (match_operand:XF 2 "register_operand" ""))]
15687   "TARGET_USE_FANCY_MATH_387"
15688 {
15689   rtx label = gen_label_rtx ();
15690
15691   emit_label (label);
15692
15693   emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
15694                                  operands[1], operands[2]));
15695   ix86_emit_fp_unordered_jump (label);
15696
15697   emit_move_insn (operands[0], operands[1]);
15698   DONE;
15699 })
15700
15701 (define_expand "remainder<mode>3"
15702   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15703    (use (match_operand:X87MODEF12 1 "general_operand" ""))
15704    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
15705   "TARGET_USE_FANCY_MATH_387"
15706 {
15707   rtx label = gen_label_rtx ();
15708
15709   rtx op1 = gen_reg_rtx (XFmode);
15710   rtx op2 = gen_reg_rtx (XFmode);
15711
15712   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15713   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15714
15715   emit_label (label);
15716
15717   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15718   ix86_emit_fp_unordered_jump (label);
15719
15720   /* Truncate the result properly for strict SSE math.  */
15721   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15722       && !TARGET_MIX_SSE_I387)
15723     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15724   else
15725     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15726
15727   DONE;
15728 })
15729
15730 (define_insn "*sinxf2_i387"
15731   [(set (match_operand:XF 0 "register_operand" "=f")
15732         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15733   "TARGET_USE_FANCY_MATH_387
15734    && flag_unsafe_math_optimizations"
15735   "fsin"
15736   [(set_attr "type" "fpspc")
15737    (set_attr "mode" "XF")])
15738
15739 (define_insn "*sin_extend<mode>xf2_i387"
15740   [(set (match_operand:XF 0 "register_operand" "=f")
15741         (unspec:XF [(float_extend:XF
15742                       (match_operand:X87MODEF12 1 "register_operand" "0"))]
15743                    UNSPEC_SIN))]
15744   "TARGET_USE_FANCY_MATH_387
15745    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15746        || TARGET_MIX_SSE_I387)
15747    && flag_unsafe_math_optimizations"
15748   "fsin"
15749   [(set_attr "type" "fpspc")
15750    (set_attr "mode" "XF")])
15751
15752 (define_insn "*cosxf2_i387"
15753   [(set (match_operand:XF 0 "register_operand" "=f")
15754         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15755   "TARGET_USE_FANCY_MATH_387
15756    && flag_unsafe_math_optimizations"
15757   "fcos"
15758   [(set_attr "type" "fpspc")
15759    (set_attr "mode" "XF")])
15760
15761 (define_insn "*cos_extend<mode>xf2_i387"
15762   [(set (match_operand:XF 0 "register_operand" "=f")
15763         (unspec:XF [(float_extend:XF
15764                       (match_operand:X87MODEF12 1 "register_operand" "0"))]
15765                    UNSPEC_COS))]
15766   "TARGET_USE_FANCY_MATH_387
15767    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15768        || TARGET_MIX_SSE_I387)
15769    && flag_unsafe_math_optimizations"
15770   "fcos"
15771   [(set_attr "type" "fpspc")
15772    (set_attr "mode" "XF")])
15773
15774 ;; When sincos pattern is defined, sin and cos builtin functions will be
15775 ;; expanded to sincos pattern with one of its outputs left unused.
15776 ;; CSE pass will figure out if two sincos patterns can be combined,
15777 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15778 ;; depending on the unused output.
15779
15780 (define_insn "sincosxf3"
15781   [(set (match_operand:XF 0 "register_operand" "=f")
15782         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15783                    UNSPEC_SINCOS_COS))
15784    (set (match_operand:XF 1 "register_operand" "=u")
15785         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15786   "TARGET_USE_FANCY_MATH_387
15787    && flag_unsafe_math_optimizations"
15788   "fsincos"
15789   [(set_attr "type" "fpspc")
15790    (set_attr "mode" "XF")])
15791
15792 (define_split
15793   [(set (match_operand:XF 0 "register_operand" "")
15794         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15795                    UNSPEC_SINCOS_COS))
15796    (set (match_operand:XF 1 "register_operand" "")
15797         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15798   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15799    && !reload_completed && !reload_in_progress"
15800   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15801   "")
15802
15803 (define_split
15804   [(set (match_operand:XF 0 "register_operand" "")
15805         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15806                    UNSPEC_SINCOS_COS))
15807    (set (match_operand:XF 1 "register_operand" "")
15808         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15809   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15810    && !reload_completed && !reload_in_progress"
15811   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15812   "")
15813
15814 (define_insn "sincos_extend<mode>xf3_i387"
15815   [(set (match_operand:XF 0 "register_operand" "=f")
15816         (unspec:XF [(float_extend:XF
15817                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
15818                    UNSPEC_SINCOS_COS))
15819    (set (match_operand:XF 1 "register_operand" "=u")
15820         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15821   "TARGET_USE_FANCY_MATH_387
15822    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15823        || TARGET_MIX_SSE_I387)
15824    && flag_unsafe_math_optimizations"
15825   "fsincos"
15826   [(set_attr "type" "fpspc")
15827    (set_attr "mode" "XF")])
15828
15829 (define_split
15830   [(set (match_operand:XF 0 "register_operand" "")
15831         (unspec:XF [(float_extend:XF
15832                       (match_operand:X87MODEF12 2 "register_operand" ""))]
15833                    UNSPEC_SINCOS_COS))
15834    (set (match_operand:XF 1 "register_operand" "")
15835         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15836   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15837    && !reload_completed && !reload_in_progress"
15838   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
15839   "")
15840
15841 (define_split
15842   [(set (match_operand:XF 0 "register_operand" "")
15843         (unspec:XF [(float_extend:XF
15844                       (match_operand:X87MODEF12 2 "register_operand" ""))]
15845                    UNSPEC_SINCOS_COS))
15846    (set (match_operand:XF 1 "register_operand" "")
15847         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15848   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15849    && !reload_completed && !reload_in_progress"
15850   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
15851   "")
15852
15853 (define_expand "sincos<mode>3"
15854   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15855    (use (match_operand:X87MODEF12 1 "register_operand" ""))
15856    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
15857   "TARGET_USE_FANCY_MATH_387
15858    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15859        || TARGET_MIX_SSE_I387)
15860    && flag_unsafe_math_optimizations"
15861 {
15862   rtx op0 = gen_reg_rtx (XFmode);
15863   rtx op1 = gen_reg_rtx (XFmode);
15864
15865   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
15866   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15867   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
15868   DONE;
15869 })
15870
15871 (define_insn "fptanxf4_i387"
15872   [(set (match_operand:XF 0 "register_operand" "=f")
15873         (match_operand:XF 3 "const_double_operand" "F"))
15874    (set (match_operand:XF 1 "register_operand" "=u")
15875         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15876                    UNSPEC_TAN))]
15877   "TARGET_USE_FANCY_MATH_387
15878    && flag_unsafe_math_optimizations
15879    && standard_80387_constant_p (operands[3]) == 2"
15880   "fptan"
15881   [(set_attr "type" "fpspc")
15882    (set_attr "mode" "XF")])
15883
15884 (define_insn "fptan_extend<mode>xf4_i387"
15885   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15886         (match_operand:X87MODEF12 3 "const_double_operand" "F"))
15887    (set (match_operand:XF 1 "register_operand" "=u")
15888         (unspec:XF [(float_extend:XF
15889                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
15890                    UNSPEC_TAN))]
15891   "TARGET_USE_FANCY_MATH_387
15892    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15893        || TARGET_MIX_SSE_I387)
15894    && flag_unsafe_math_optimizations
15895    && standard_80387_constant_p (operands[3]) == 2"
15896   "fptan"
15897   [(set_attr "type" "fpspc")
15898    (set_attr "mode" "XF")])
15899
15900 (define_expand "tanxf2"
15901   [(use (match_operand:XF 0 "register_operand" ""))
15902    (use (match_operand:XF 1 "register_operand" ""))]
15903   "TARGET_USE_FANCY_MATH_387
15904    && flag_unsafe_math_optimizations"
15905 {
15906   rtx one = gen_reg_rtx (XFmode);
15907   operands[2] = CONST1_RTX (XFmode); /* fld1 */
15908
15909   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], operands[2]));
15910   DONE;
15911 })
15912
15913 (define_expand "tan<mode>2"
15914   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15915    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
15916   "TARGET_USE_FANCY_MATH_387
15917    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15918        || TARGET_MIX_SSE_I387)
15919    && flag_unsafe_math_optimizations"
15920 {
15921   rtx op0 = gen_reg_rtx (XFmode);
15922
15923   rtx one = gen_reg_rtx (<MODE>mode);
15924   operands[2] = CONST1_RTX (<MODE>mode); /* fld1 */
15925
15926   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
15927                                              operands[1], operands[2]));
15928   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15929   DONE;
15930 })
15931
15932 (define_insn "*fpatanxf3_i387"
15933   [(set (match_operand:XF 0 "register_operand" "=f")
15934         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15935                     (match_operand:XF 2 "register_operand" "u")]
15936                    UNSPEC_FPATAN))
15937    (clobber (match_scratch:XF 3 "=2"))]
15938   "TARGET_USE_FANCY_MATH_387
15939    && flag_unsafe_math_optimizations"
15940   "fpatan"
15941   [(set_attr "type" "fpspc")
15942    (set_attr "mode" "XF")])
15943
15944 (define_insn "fpatan_extend<mode>xf3_i387"
15945   [(set (match_operand:XF 0 "register_operand" "=f")
15946         (unspec:XF [(float_extend:XF
15947                       (match_operand:X87MODEF12 1 "register_operand" "0"))
15948                     (float_extend:XF
15949                       (match_operand:X87MODEF12 2 "register_operand" "u"))]
15950                    UNSPEC_FPATAN))
15951    (clobber (match_scratch:XF 3 "=2"))]
15952   "TARGET_USE_FANCY_MATH_387
15953    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15954        || TARGET_MIX_SSE_I387)
15955    && flag_unsafe_math_optimizations"
15956   "fpatan"
15957   [(set_attr "type" "fpspc")
15958    (set_attr "mode" "XF")])
15959
15960 (define_expand "atan2xf3"
15961   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15962                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
15963                                (match_operand:XF 1 "register_operand" "")]
15964                               UNSPEC_FPATAN))
15965               (clobber (match_scratch:XF 3 ""))])]
15966   "TARGET_USE_FANCY_MATH_387
15967    && flag_unsafe_math_optimizations"
15968   "")
15969
15970 (define_expand "atan2<mode>3"
15971   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15972    (use (match_operand:X87MODEF12 1 "register_operand" ""))
15973    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
15974   "TARGET_USE_FANCY_MATH_387
15975    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15976        || TARGET_MIX_SSE_I387)
15977    && flag_unsafe_math_optimizations"
15978 {
15979   rtx op0 = gen_reg_rtx (XFmode);
15980
15981   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
15982   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15983   DONE;
15984 })
15985
15986 (define_expand "atanxf2"
15987   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15988                    (unspec:XF [(match_dup 2)
15989                                (match_operand:XF 1 "register_operand" "")]
15990                               UNSPEC_FPATAN))
15991               (clobber (match_scratch:XF 3 ""))])]
15992   "TARGET_USE_FANCY_MATH_387
15993    && flag_unsafe_math_optimizations"
15994 {
15995   operands[2] = gen_reg_rtx (XFmode);
15996   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15997 })
15998
15999 (define_expand "atan<mode>2"
16000   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16001    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16002   "TARGET_USE_FANCY_MATH_387
16003    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16004        || TARGET_MIX_SSE_I387)
16005    && flag_unsafe_math_optimizations"
16006 {
16007   rtx op0 = gen_reg_rtx (XFmode);
16008
16009   operands[2] = gen_reg_rtx (<MODE>mode);
16010   emit_move_insn (operands[2], CONST1_RTX (<MODE>mode));  /* fld1 */
16011
16012   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16013   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16014   DONE;
16015 })
16016
16017 (define_expand "asinxf2"
16018   [(set (match_dup 2)
16019         (mult:XF (match_operand:XF 1 "register_operand" "")
16020                  (match_dup 1)))
16021    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16022    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16023    (parallel [(set (match_operand:XF 0 "register_operand" "")
16024                    (unspec:XF [(match_dup 5) (match_dup 1)]
16025                               UNSPEC_FPATAN))
16026               (clobber (match_scratch:XF 6 ""))])]
16027   "TARGET_USE_FANCY_MATH_387
16028    && flag_unsafe_math_optimizations && !optimize_size"
16029 {
16030   int i;
16031
16032   for (i = 2; i < 6; i++)
16033     operands[i] = gen_reg_rtx (XFmode);
16034
16035   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16036 })
16037
16038 (define_expand "asin<mode>2"
16039   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16040    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16041  "TARGET_USE_FANCY_MATH_387
16042    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16043        || TARGET_MIX_SSE_I387)
16044    && flag_unsafe_math_optimizations && !optimize_size"
16045 {
16046   rtx op0 = gen_reg_rtx (XFmode);
16047   rtx op1 = gen_reg_rtx (XFmode);
16048
16049   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16050   emit_insn (gen_asinxf2 (op0, op1));
16051   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16052   DONE;
16053 })
16054
16055 (define_expand "acosxf2"
16056   [(set (match_dup 2)
16057         (mult:XF (match_operand:XF 1 "register_operand" "")
16058                  (match_dup 1)))
16059    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16060    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16061    (parallel [(set (match_operand:XF 0 "register_operand" "")
16062                    (unspec:XF [(match_dup 1) (match_dup 5)]
16063                               UNSPEC_FPATAN))
16064               (clobber (match_scratch:XF 6 ""))])]
16065   "TARGET_USE_FANCY_MATH_387
16066    && flag_unsafe_math_optimizations && !optimize_size"
16067 {
16068   int i;
16069
16070   for (i = 2; i < 6; i++)
16071     operands[i] = gen_reg_rtx (XFmode);
16072
16073   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16074 })
16075
16076 (define_expand "acos<mode>2"
16077   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16078    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16079  "TARGET_USE_FANCY_MATH_387
16080    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16081        || TARGET_MIX_SSE_I387)
16082    && flag_unsafe_math_optimizations && !optimize_size"
16083 {
16084   rtx op0 = gen_reg_rtx (XFmode);
16085   rtx op1 = gen_reg_rtx (XFmode);
16086
16087   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16088   emit_insn (gen_acosxf2 (op0, op1));
16089   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16090   DONE;
16091 })
16092
16093 (define_insn "fyl2xxf3_i387"
16094   [(set (match_operand:XF 0 "register_operand" "=f")
16095         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16096                     (match_operand:XF 2 "register_operand" "u")]
16097                    UNSPEC_FYL2X))
16098    (clobber (match_scratch:XF 3 "=2"))]
16099   "TARGET_USE_FANCY_MATH_387
16100    && flag_unsafe_math_optimizations"
16101   "fyl2x"
16102   [(set_attr "type" "fpspc")
16103    (set_attr "mode" "XF")])
16104
16105 (define_insn "fyl2x_extend<mode>xf3_i387"
16106   [(set (match_operand:XF 0 "register_operand" "=f")
16107         (unspec:XF [(float_extend:XF
16108                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16109                     (match_operand:XF 2 "register_operand" "u")]
16110                    UNSPEC_FYL2X))
16111    (clobber (match_scratch:XF 3 "=2"))]
16112   "TARGET_USE_FANCY_MATH_387
16113    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16114        || TARGET_MIX_SSE_I387)
16115    && flag_unsafe_math_optimizations"
16116   "fyl2x"
16117   [(set_attr "type" "fpspc")
16118    (set_attr "mode" "XF")])
16119
16120 (define_expand "logxf2"
16121   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16122                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16123                                (match_dup 2)] UNSPEC_FYL2X))
16124               (clobber (match_scratch:XF 3 ""))])]
16125   "TARGET_USE_FANCY_MATH_387
16126    && flag_unsafe_math_optimizations"
16127 {
16128   operands[2] = gen_reg_rtx (XFmode);
16129   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16130 })
16131
16132 (define_expand "log<mode>2"
16133   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16134    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16135   "TARGET_USE_FANCY_MATH_387
16136    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16137        || TARGET_MIX_SSE_I387)
16138    && flag_unsafe_math_optimizations"
16139 {
16140   rtx op0 = gen_reg_rtx (XFmode);
16141
16142   operands[2] = gen_reg_rtx (XFmode);
16143   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16144
16145   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], operands[2]));
16146   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16147   DONE;
16148 })
16149
16150 (define_expand "log10xf2"
16151   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16152                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16153                                (match_dup 2)] UNSPEC_FYL2X))
16154               (clobber (match_scratch:XF 3 ""))])]
16155   "TARGET_USE_FANCY_MATH_387
16156    && flag_unsafe_math_optimizations"
16157 {
16158   operands[2] = gen_reg_rtx (XFmode);
16159   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16160 })
16161
16162 (define_expand "log10<mode>2"
16163   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16164    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16165   "TARGET_USE_FANCY_MATH_387
16166    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16167        || TARGET_MIX_SSE_I387)
16168    && flag_unsafe_math_optimizations"
16169 {
16170   rtx op0 = gen_reg_rtx (XFmode);
16171
16172   operands[2] = gen_reg_rtx (XFmode);
16173   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16174
16175   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], operands[2]));
16176   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16177   DONE;
16178 })
16179
16180 (define_expand "log2xf2"
16181   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16182                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16183                                (match_dup 2)] UNSPEC_FYL2X))
16184               (clobber (match_scratch:XF 3 ""))])]
16185   "TARGET_USE_FANCY_MATH_387
16186    && flag_unsafe_math_optimizations"
16187 {
16188   operands[2] = gen_reg_rtx (XFmode);
16189   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16190 })
16191
16192 (define_expand "log2<mode>2"
16193   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16194    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16195   "TARGET_USE_FANCY_MATH_387
16196    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16197        || TARGET_MIX_SSE_I387)
16198    && flag_unsafe_math_optimizations"
16199 {
16200   rtx op0 = gen_reg_rtx (XFmode);
16201
16202   operands[2] = gen_reg_rtx (XFmode);
16203   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16204
16205   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], operands[2]));
16206   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16207   DONE;
16208 })
16209
16210 (define_insn "fyl2xp1xf3_i387"
16211   [(set (match_operand:XF 0 "register_operand" "=f")
16212         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16213                     (match_operand:XF 2 "register_operand" "u")]
16214                    UNSPEC_FYL2XP1))
16215    (clobber (match_scratch:XF 3 "=2"))]
16216   "TARGET_USE_FANCY_MATH_387
16217    && flag_unsafe_math_optimizations"
16218   "fyl2xp1"
16219   [(set_attr "type" "fpspc")
16220    (set_attr "mode" "XF")])
16221
16222 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16223   [(set (match_operand:XF 0 "register_operand" "=f")
16224         (unspec:XF [(float_extend:XF
16225                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16226                     (match_operand:XF 2 "register_operand" "u")]
16227                    UNSPEC_FYL2XP1))
16228    (clobber (match_scratch:XF 3 "=2"))]
16229   "TARGET_USE_FANCY_MATH_387
16230    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16231        || TARGET_MIX_SSE_I387)
16232    && flag_unsafe_math_optimizations"
16233   "fyl2xp1"
16234   [(set_attr "type" "fpspc")
16235    (set_attr "mode" "XF")])
16236
16237 (define_expand "log1pxf2"
16238   [(use (match_operand:XF 0 "register_operand" ""))
16239    (use (match_operand:XF 1 "register_operand" ""))]
16240   "TARGET_USE_FANCY_MATH_387
16241    && flag_unsafe_math_optimizations && !optimize_size"
16242 {
16243   ix86_emit_i387_log1p (operands[0], operands[1]);
16244   DONE;
16245 })
16246
16247 (define_expand "log1p<mode>2"
16248   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16249    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16250   "TARGET_USE_FANCY_MATH_387
16251    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16252        || TARGET_MIX_SSE_I387)
16253    && flag_unsafe_math_optimizations && !optimize_size"
16254 {
16255   rtx op0 = gen_reg_rtx (XFmode);
16256
16257   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16258
16259   ix86_emit_i387_log1p (op0, operands[1]);
16260   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16261   DONE;
16262 })
16263
16264 (define_insn "*fxtractxf3_i387"
16265   [(set (match_operand:XF 0 "register_operand" "=f")
16266         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16267                    UNSPEC_XTRACT_FRACT))
16268    (set (match_operand:XF 1 "register_operand" "=u")
16269         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16270   "TARGET_USE_FANCY_MATH_387
16271    && flag_unsafe_math_optimizations"
16272   "fxtract"
16273   [(set_attr "type" "fpspc")
16274    (set_attr "mode" "XF")])
16275
16276 (define_insn "fxtract_extend<mode>xf3_i387"
16277   [(set (match_operand:XF 0 "register_operand" "=f")
16278         (unspec:XF [(float_extend:XF
16279                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16280                    UNSPEC_XTRACT_FRACT))
16281    (set (match_operand:XF 1 "register_operand" "=u")
16282         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16283   "TARGET_USE_FANCY_MATH_387
16284    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16285        || TARGET_MIX_SSE_I387)
16286    && flag_unsafe_math_optimizations"
16287   "fxtract"
16288   [(set_attr "type" "fpspc")
16289    (set_attr "mode" "XF")])
16290
16291 (define_expand "logbxf2"
16292   [(parallel [(set (match_dup 2)
16293                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16294                               UNSPEC_XTRACT_FRACT))
16295               (set (match_operand:XF 0 "register_operand" "")
16296                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16297   "TARGET_USE_FANCY_MATH_387
16298    && flag_unsafe_math_optimizations"
16299 {
16300   operands[2] = gen_reg_rtx (XFmode);
16301 })
16302
16303 (define_expand "logb<mode>2"
16304   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16305    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16306   "TARGET_USE_FANCY_MATH_387
16307    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16308        || TARGET_MIX_SSE_I387)
16309    && flag_unsafe_math_optimizations"
16310 {
16311   rtx op0 = gen_reg_rtx (XFmode);
16312   rtx op1 = gen_reg_rtx (XFmode);
16313
16314   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16315   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16316   DONE;
16317 })
16318
16319 (define_expand "ilogbsi2"
16320   [(parallel [(set (match_dup 2)
16321                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16322                               UNSPEC_XTRACT_FRACT))
16323               (set (match_dup 3)
16324                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16325    (parallel [(set (match_operand:SI 0 "register_operand" "")
16326                    (fix:SI (match_dup 3)))
16327               (clobber (reg:CC FLAGS_REG))])]
16328   "TARGET_USE_FANCY_MATH_387
16329    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16330    && flag_unsafe_math_optimizations && !optimize_size"
16331 {
16332   operands[2] = gen_reg_rtx (XFmode);
16333   operands[3] = gen_reg_rtx (XFmode);
16334 })
16335
16336 (define_insn "*f2xm1xf2_i387"
16337   [(set (match_operand:XF 0 "register_operand" "=f")
16338         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16339                    UNSPEC_F2XM1))]
16340   "TARGET_USE_FANCY_MATH_387
16341    && flag_unsafe_math_optimizations"
16342   "f2xm1"
16343   [(set_attr "type" "fpspc")
16344    (set_attr "mode" "XF")])
16345
16346 (define_insn "*fscalexf4_i387"
16347   [(set (match_operand:XF 0 "register_operand" "=f")
16348         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16349                     (match_operand:XF 3 "register_operand" "1")]
16350                    UNSPEC_FSCALE_FRACT))
16351    (set (match_operand:XF 1 "register_operand" "=u")
16352         (unspec:XF [(match_dup 2) (match_dup 3)]
16353                    UNSPEC_FSCALE_EXP))]
16354   "TARGET_USE_FANCY_MATH_387
16355    && flag_unsafe_math_optimizations"
16356   "fscale"
16357   [(set_attr "type" "fpspc")
16358    (set_attr "mode" "XF")])
16359
16360 (define_expand "expNcorexf3"
16361   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16362                                (match_operand:XF 2 "register_operand" "")))
16363    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16364    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16365    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16366    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16367    (parallel [(set (match_operand:XF 0 "register_operand" "")
16368                    (unspec:XF [(match_dup 8) (match_dup 4)]
16369                               UNSPEC_FSCALE_FRACT))
16370               (set (match_dup 9)
16371                    (unspec:XF [(match_dup 8) (match_dup 4)]
16372                               UNSPEC_FSCALE_EXP))])]
16373   "TARGET_USE_FANCY_MATH_387
16374    && flag_unsafe_math_optimizations && !optimize_size"
16375 {
16376   int i;
16377
16378   for (i = 3; i < 10; i++)
16379     operands[i] = gen_reg_rtx (XFmode);
16380
16381   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16382 })
16383
16384 (define_expand "expxf2"
16385   [(use (match_operand:XF 0 "register_operand" ""))
16386    (use (match_operand:XF 1 "register_operand" ""))]
16387   "TARGET_USE_FANCY_MATH_387
16388    && flag_unsafe_math_optimizations && !optimize_size"
16389 {
16390   operands[2] = gen_reg_rtx (XFmode);
16391   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16392
16393   emit_insn (gen_expNcorexf3 (operands[0], operands[1], operands[2]));
16394   DONE;
16395 })
16396
16397 (define_expand "exp<mode>2"
16398   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16399    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
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 && !optimize_size"
16404 {
16405   rtx op0 = gen_reg_rtx (XFmode);
16406   rtx op1 = gen_reg_rtx (XFmode);
16407
16408   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16409   emit_insn (gen_expxf2 (op0, op1));
16410   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16411   DONE;
16412 })
16413
16414 (define_expand "exp10xf2"
16415   [(use (match_operand:XF 0 "register_operand" ""))
16416    (use (match_operand:XF 1 "register_operand" ""))]
16417   "TARGET_USE_FANCY_MATH_387
16418    && flag_unsafe_math_optimizations && !optimize_size"
16419 {
16420   operands[2] = gen_reg_rtx (XFmode);
16421   emit_move_insn (operands[2], standard_80387_constant_rtx (6)); /* fldl2t */
16422
16423   emit_insn (gen_expNcorexf3 (operands[0], operands[1], operands[2]));
16424   DONE;
16425 })
16426
16427 (define_expand "exp10<mode>2"
16428   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16429    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16430  "TARGET_USE_FANCY_MATH_387
16431    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16432        || TARGET_MIX_SSE_I387)
16433    && flag_unsafe_math_optimizations && !optimize_size"
16434 {
16435   rtx op0 = gen_reg_rtx (XFmode);
16436   rtx op1 = gen_reg_rtx (XFmode);
16437
16438   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16439   emit_insn (gen_exp10xf2 (op0, op1));
16440   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16441   DONE;
16442 })
16443
16444 (define_expand "exp2xf2"
16445   [(use (match_operand:XF 0 "register_operand" ""))
16446    (use (match_operand:XF 1 "register_operand" ""))]
16447   "TARGET_USE_FANCY_MATH_387
16448    && flag_unsafe_math_optimizations && !optimize_size"
16449 {
16450   operands[2] = gen_reg_rtx (XFmode);
16451   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16452
16453   emit_insn (gen_expNcorexf3 (operands[0], operands[1], operands[2]));
16454   DONE;
16455 })
16456
16457 (define_expand "exp2<mode>2"
16458   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16459    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16460  "TARGET_USE_FANCY_MATH_387
16461    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16462        || TARGET_MIX_SSE_I387)
16463    && flag_unsafe_math_optimizations && !optimize_size"
16464 {
16465   rtx op0 = gen_reg_rtx (XFmode);
16466   rtx op1 = gen_reg_rtx (XFmode);
16467
16468   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16469   emit_insn (gen_exp2xf2 (op0, op1));
16470   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16471   DONE;
16472 })
16473
16474 (define_expand "expm1xf2"
16475   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16476                                (match_dup 2)))
16477    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16478    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16479    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16480    (parallel [(set (match_dup 7)
16481                    (unspec:XF [(match_dup 6) (match_dup 4)]
16482                               UNSPEC_FSCALE_FRACT))
16483                    (set (match_dup 8)
16484                    (unspec:XF [(match_dup 6) (match_dup 4)]
16485                               UNSPEC_FSCALE_EXP))])
16486    (parallel [(set (match_dup 10)
16487                    (unspec:XF [(match_dup 9) (match_dup 8)]
16488                               UNSPEC_FSCALE_FRACT))
16489               (set (match_dup 11)
16490                    (unspec:XF [(match_dup 9) (match_dup 8)]
16491                               UNSPEC_FSCALE_EXP))])
16492    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16493    (set (match_operand:XF 0 "register_operand" "")
16494         (plus:XF (match_dup 12) (match_dup 7)))]
16495   "TARGET_USE_FANCY_MATH_387
16496    && flag_unsafe_math_optimizations && !optimize_size"
16497 {
16498   int i;
16499
16500   for (i = 2; i < 13; i++)
16501     operands[i] = gen_reg_rtx (XFmode);
16502  
16503   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16504   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16505 })
16506
16507 (define_expand "expm1<mode>2"
16508   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16509    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16510  "TARGET_USE_FANCY_MATH_387
16511    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16512        || TARGET_MIX_SSE_I387)
16513    && flag_unsafe_math_optimizations && !optimize_size"
16514 {
16515   rtx op0 = gen_reg_rtx (XFmode);
16516   rtx op1 = gen_reg_rtx (XFmode);
16517
16518   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16519   emit_insn (gen_expm1xf2 (op0, op1));
16520   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16521   DONE;
16522 })
16523
16524 (define_expand "ldexpxf3"
16525   [(set (match_dup 3)
16526         (float:XF (match_operand:SI 2 "register_operand" "")))
16527    (parallel [(set (match_operand:XF 0 " register_operand" "")
16528                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16529                                (match_dup 3)]
16530                               UNSPEC_FSCALE_FRACT))
16531               (set (match_dup 4)
16532                    (unspec:XF [(match_dup 1) (match_dup 3)]
16533                               UNSPEC_FSCALE_EXP))])]
16534   "TARGET_USE_FANCY_MATH_387
16535    && flag_unsafe_math_optimizations && !optimize_size"
16536 {
16537   operands[3] = gen_reg_rtx (XFmode);
16538   operands[4] = gen_reg_rtx (XFmode);
16539 })
16540
16541 (define_expand "ldexp<mode>3"
16542   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16543    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16544    (use (match_operand:SI 2 "register_operand" ""))]
16545  "TARGET_USE_FANCY_MATH_387
16546    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16547        || TARGET_MIX_SSE_I387)
16548    && flag_unsafe_math_optimizations && !optimize_size"
16549 {
16550   rtx op0 = gen_reg_rtx (XFmode);
16551   rtx op1 = gen_reg_rtx (XFmode);
16552
16553   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16554   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16555   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16556   DONE;
16557 })
16558 \f
16559
16560 (define_insn "frndintxf2"
16561   [(set (match_operand:XF 0 "register_operand" "=f")
16562         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16563          UNSPEC_FRNDINT))]
16564   "TARGET_USE_FANCY_MATH_387
16565    && flag_unsafe_math_optimizations"
16566   "frndint"
16567   [(set_attr "type" "fpspc")
16568    (set_attr "mode" "XF")])
16569
16570 (define_expand "rintdf2"
16571   [(use (match_operand:DF 0 "register_operand" ""))
16572    (use (match_operand:DF 1 "register_operand" ""))]
16573   "(TARGET_USE_FANCY_MATH_387
16574     && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16575     && flag_unsafe_math_optimizations)
16576    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16577        && !flag_trapping_math
16578        && !optimize_size)"
16579 {
16580   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16581       && !flag_trapping_math
16582       && !optimize_size)
16583     ix86_expand_rint (operand0, operand1);
16584   else
16585     {
16586       rtx op0 = gen_reg_rtx (XFmode);
16587       rtx op1 = gen_reg_rtx (XFmode);
16588
16589       emit_insn (gen_extenddfxf2 (op1, operands[1]));
16590       emit_insn (gen_frndintxf2 (op0, op1));
16591
16592       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16593     }
16594   DONE;
16595 })
16596
16597 (define_expand "rintsf2"
16598   [(use (match_operand:SF 0 "register_operand" ""))
16599    (use (match_operand:SF 1 "register_operand" ""))]
16600   "(TARGET_USE_FANCY_MATH_387
16601     && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16602     && flag_unsafe_math_optimizations)
16603    || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16604        && !flag_trapping_math
16605        && !optimize_size)"
16606 {
16607   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16608       && !flag_trapping_math
16609       && !optimize_size)
16610     ix86_expand_rint (operand0, operand1);
16611   else
16612     {
16613       rtx op0 = gen_reg_rtx (XFmode);
16614       rtx op1 = gen_reg_rtx (XFmode);
16615
16616       emit_insn (gen_extendsfxf2 (op1, operands[1]));
16617       emit_insn (gen_frndintxf2 (op0, op1));
16618
16619       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16620     }
16621   DONE;
16622 })
16623
16624 (define_expand "rintxf2"
16625   [(use (match_operand:XF 0 "register_operand" ""))
16626    (use (match_operand:XF 1 "register_operand" ""))]
16627   "TARGET_USE_FANCY_MATH_387
16628    && flag_unsafe_math_optimizations && !optimize_size"
16629 {
16630   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16631   DONE;
16632 })
16633
16634 (define_expand "roundsf2"
16635   [(match_operand:SF 0 "register_operand" "")
16636    (match_operand:SF 1 "nonimmediate_operand" "")]
16637   "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16638    && !flag_trapping_math && !flag_rounding_math
16639    && !optimize_size"
16640 {
16641   ix86_expand_round (operand0, operand1);
16642   DONE;
16643 })
16644
16645 (define_expand "rounddf2"
16646   [(match_operand:DF 0 "register_operand" "")
16647    (match_operand:DF 1 "nonimmediate_operand" "")]
16648   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16649    && !flag_trapping_math && !flag_rounding_math
16650    && !optimize_size"
16651 {
16652   if (TARGET_64BIT)
16653     ix86_expand_round (operand0, operand1);
16654   else
16655     ix86_expand_rounddf_32 (operand0, operand1);
16656   DONE;
16657 })
16658
16659 (define_insn_and_split "*fistdi2_1"
16660   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16661         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16662          UNSPEC_FIST))]
16663   "TARGET_USE_FANCY_MATH_387
16664    && !(reload_completed || reload_in_progress)"
16665   "#"
16666   "&& 1"
16667   [(const_int 0)]
16668 {
16669   if (memory_operand (operands[0], VOIDmode))
16670     emit_insn (gen_fistdi2 (operands[0], operands[1]));
16671   else
16672     {
16673       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16674       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16675                                          operands[2]));
16676     }
16677   DONE;
16678 }
16679   [(set_attr "type" "fpspc")
16680    (set_attr "mode" "DI")])
16681
16682 (define_insn "fistdi2"
16683   [(set (match_operand:DI 0 "memory_operand" "=m")
16684         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16685          UNSPEC_FIST))
16686    (clobber (match_scratch:XF 2 "=&1f"))]
16687   "TARGET_USE_FANCY_MATH_387"
16688   "* return output_fix_trunc (insn, operands, 0);"
16689   [(set_attr "type" "fpspc")
16690    (set_attr "mode" "DI")])
16691
16692 (define_insn "fistdi2_with_temp"
16693   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16694         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16695          UNSPEC_FIST))
16696    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16697    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16698   "TARGET_USE_FANCY_MATH_387"
16699   "#"
16700   [(set_attr "type" "fpspc")
16701    (set_attr "mode" "DI")])
16702
16703 (define_split
16704   [(set (match_operand:DI 0 "register_operand" "")
16705         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16706          UNSPEC_FIST))
16707    (clobber (match_operand:DI 2 "memory_operand" ""))
16708    (clobber (match_scratch 3 ""))]
16709   "reload_completed"
16710   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16711               (clobber (match_dup 3))])
16712    (set (match_dup 0) (match_dup 2))]
16713   "")
16714
16715 (define_split
16716   [(set (match_operand:DI 0 "memory_operand" "")
16717         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16718          UNSPEC_FIST))
16719    (clobber (match_operand:DI 2 "memory_operand" ""))
16720    (clobber (match_scratch 3 ""))]
16721   "reload_completed"
16722   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16723               (clobber (match_dup 3))])]
16724   "")
16725
16726 (define_insn_and_split "*fist<mode>2_1"
16727   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16728         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16729          UNSPEC_FIST))]
16730   "TARGET_USE_FANCY_MATH_387
16731    && !(reload_completed || reload_in_progress)"
16732   "#"
16733   "&& 1"
16734   [(const_int 0)]
16735 {
16736   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16737   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16738                                         operands[2]));
16739   DONE;
16740 }
16741   [(set_attr "type" "fpspc")
16742    (set_attr "mode" "<MODE>")])
16743
16744 (define_insn "fist<mode>2"
16745   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16746         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16747          UNSPEC_FIST))]
16748   "TARGET_USE_FANCY_MATH_387"
16749   "* return output_fix_trunc (insn, operands, 0);"
16750   [(set_attr "type" "fpspc")
16751    (set_attr "mode" "<MODE>")])
16752
16753 (define_insn "fist<mode>2_with_temp"
16754   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16755         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16756          UNSPEC_FIST))
16757    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16758   "TARGET_USE_FANCY_MATH_387"
16759   "#"
16760   [(set_attr "type" "fpspc")
16761    (set_attr "mode" "<MODE>")])
16762
16763 (define_split
16764   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16765         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16766          UNSPEC_FIST))
16767    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16768   "reload_completed"
16769   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16770                        UNSPEC_FIST))
16771    (set (match_dup 0) (match_dup 2))]
16772   "")
16773
16774 (define_split
16775   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16776         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16777          UNSPEC_FIST))
16778    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16779   "reload_completed"
16780   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16781                        UNSPEC_FIST))]
16782   "")
16783
16784 (define_expand "lrintxf<mode>2"
16785   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16786      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16787       UNSPEC_FIST))]
16788   "TARGET_USE_FANCY_MATH_387"
16789   "")
16790
16791 (define_expand "lrint<mode>di2"
16792   [(set (match_operand:DI 0 "nonimmediate_operand" "")
16793      (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
16794       UNSPEC_FIX_NOTRUNC))]
16795   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
16796   "")
16797
16798 (define_expand "lrint<mode>si2"
16799   [(set (match_operand:SI 0 "nonimmediate_operand" "")
16800      (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
16801       UNSPEC_FIX_NOTRUNC))]
16802   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16803   "")
16804
16805 (define_expand "lround<mode>di2"
16806   [(match_operand:DI 0 "nonimmediate_operand" "")
16807    (match_operand:SSEMODEF 1 "register_operand" "")]
16808   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
16809    && !flag_trapping_math && !flag_rounding_math
16810    && !optimize_size"
16811 {
16812   ix86_expand_lround (operand0, operand1);
16813   DONE;
16814 })
16815
16816 (define_expand "lround<mode>si2"
16817   [(match_operand:SI 0 "nonimmediate_operand" "")
16818    (match_operand:SSEMODEF 1 "register_operand" "")]
16819   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16820    && !flag_trapping_math && !flag_rounding_math
16821    && !optimize_size"
16822 {
16823   ix86_expand_lround (operand0, operand1);
16824   DONE;
16825 })
16826
16827 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16828 (define_insn_and_split "frndintxf2_floor"
16829   [(set (match_operand:XF 0 "register_operand" "=f")
16830         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16831          UNSPEC_FRNDINT_FLOOR))
16832    (clobber (reg:CC FLAGS_REG))]
16833   "TARGET_USE_FANCY_MATH_387
16834    && flag_unsafe_math_optimizations
16835    && !(reload_completed || reload_in_progress)"
16836   "#"
16837   "&& 1"
16838   [(const_int 0)]
16839 {
16840   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16841
16842   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16843   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16844
16845   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16846                                         operands[2], operands[3]));
16847   DONE;
16848 }
16849   [(set_attr "type" "frndint")
16850    (set_attr "i387_cw" "floor")
16851    (set_attr "mode" "XF")])
16852
16853 (define_insn "frndintxf2_floor_i387"
16854   [(set (match_operand:XF 0 "register_operand" "=f")
16855         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16856          UNSPEC_FRNDINT_FLOOR))
16857    (use (match_operand:HI 2 "memory_operand" "m"))
16858    (use (match_operand:HI 3 "memory_operand" "m"))]
16859   "TARGET_USE_FANCY_MATH_387
16860    && flag_unsafe_math_optimizations"
16861   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16862   [(set_attr "type" "frndint")
16863    (set_attr "i387_cw" "floor")
16864    (set_attr "mode" "XF")])
16865
16866 (define_expand "floorxf2"
16867   [(use (match_operand:XF 0 "register_operand" ""))
16868    (use (match_operand:XF 1 "register_operand" ""))]
16869   "TARGET_USE_FANCY_MATH_387
16870    && flag_unsafe_math_optimizations && !optimize_size"
16871 {
16872   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16873   DONE;
16874 })
16875
16876 (define_expand "floordf2"
16877   [(use (match_operand:DF 0 "register_operand" ""))
16878    (use (match_operand:DF 1 "register_operand" ""))]
16879   "((TARGET_USE_FANCY_MATH_387
16880      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16881      && flag_unsafe_math_optimizations)
16882     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16883         && !flag_trapping_math))
16884    && !optimize_size"
16885 {
16886   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16887       && !flag_trapping_math)
16888     {
16889       if (TARGET_64BIT)
16890         ix86_expand_floorceil (operand0, operand1, true);
16891       else
16892         ix86_expand_floorceildf_32 (operand0, operand1, true);
16893     }
16894   else
16895     {
16896       rtx op0 = gen_reg_rtx (XFmode);
16897       rtx op1 = gen_reg_rtx (XFmode);
16898
16899       emit_insn (gen_extenddfxf2 (op1, operands[1]));
16900       emit_insn (gen_frndintxf2_floor (op0, op1));
16901
16902       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16903     }
16904   DONE;
16905 })
16906
16907 (define_expand "floorsf2"
16908   [(use (match_operand:SF 0 "register_operand" ""))
16909    (use (match_operand:SF 1 "register_operand" ""))]
16910   "((TARGET_USE_FANCY_MATH_387
16911      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16912      && flag_unsafe_math_optimizations)
16913     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16914         && !flag_trapping_math))
16915    && !optimize_size"
16916 {
16917   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16918       && !flag_trapping_math)
16919     ix86_expand_floorceil (operand0, operand1, true);
16920   else
16921     {
16922       rtx op0 = gen_reg_rtx (XFmode);
16923       rtx op1 = gen_reg_rtx (XFmode);
16924
16925       emit_insn (gen_extendsfxf2 (op1, operands[1]));
16926       emit_insn (gen_frndintxf2_floor (op0, op1));
16927
16928       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16929     }
16930   DONE;
16931 })
16932
16933 (define_insn_and_split "*fist<mode>2_floor_1"
16934   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16935         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16936          UNSPEC_FIST_FLOOR))
16937    (clobber (reg:CC FLAGS_REG))]
16938   "TARGET_USE_FANCY_MATH_387
16939    && flag_unsafe_math_optimizations
16940    && !(reload_completed || reload_in_progress)"
16941   "#"
16942   "&& 1"
16943   [(const_int 0)]
16944 {
16945   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16946
16947   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16948   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16949   if (memory_operand (operands[0], VOIDmode))
16950     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16951                                       operands[2], operands[3]));
16952   else
16953     {
16954       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16955       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16956                                                   operands[2], operands[3],
16957                                                   operands[4]));
16958     }
16959   DONE;
16960 }
16961   [(set_attr "type" "fistp")
16962    (set_attr "i387_cw" "floor")
16963    (set_attr "mode" "<MODE>")])
16964
16965 (define_insn "fistdi2_floor"
16966   [(set (match_operand:DI 0 "memory_operand" "=m")
16967         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16968          UNSPEC_FIST_FLOOR))
16969    (use (match_operand:HI 2 "memory_operand" "m"))
16970    (use (match_operand:HI 3 "memory_operand" "m"))
16971    (clobber (match_scratch:XF 4 "=&1f"))]
16972   "TARGET_USE_FANCY_MATH_387
16973    && flag_unsafe_math_optimizations"
16974   "* return output_fix_trunc (insn, operands, 0);"
16975   [(set_attr "type" "fistp")
16976    (set_attr "i387_cw" "floor")
16977    (set_attr "mode" "DI")])
16978
16979 (define_insn "fistdi2_floor_with_temp"
16980   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16981         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16982          UNSPEC_FIST_FLOOR))
16983    (use (match_operand:HI 2 "memory_operand" "m,m"))
16984    (use (match_operand:HI 3 "memory_operand" "m,m"))
16985    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16986    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16987   "TARGET_USE_FANCY_MATH_387
16988    && flag_unsafe_math_optimizations"
16989   "#"
16990   [(set_attr "type" "fistp")
16991    (set_attr "i387_cw" "floor")
16992    (set_attr "mode" "DI")])
16993
16994 (define_split
16995   [(set (match_operand:DI 0 "register_operand" "")
16996         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16997          UNSPEC_FIST_FLOOR))
16998    (use (match_operand:HI 2 "memory_operand" ""))
16999    (use (match_operand:HI 3 "memory_operand" ""))
17000    (clobber (match_operand:DI 4 "memory_operand" ""))
17001    (clobber (match_scratch 5 ""))]
17002   "reload_completed"
17003   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17004               (use (match_dup 2))
17005               (use (match_dup 3))
17006               (clobber (match_dup 5))])
17007    (set (match_dup 0) (match_dup 4))]
17008   "")
17009
17010 (define_split
17011   [(set (match_operand:DI 0 "memory_operand" "")
17012         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17013          UNSPEC_FIST_FLOOR))
17014    (use (match_operand:HI 2 "memory_operand" ""))
17015    (use (match_operand:HI 3 "memory_operand" ""))
17016    (clobber (match_operand:DI 4 "memory_operand" ""))
17017    (clobber (match_scratch 5 ""))]
17018   "reload_completed"
17019   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17020               (use (match_dup 2))
17021               (use (match_dup 3))
17022               (clobber (match_dup 5))])]
17023   "")
17024
17025 (define_insn "fist<mode>2_floor"
17026   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17027         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17028          UNSPEC_FIST_FLOOR))
17029    (use (match_operand:HI 2 "memory_operand" "m"))
17030    (use (match_operand:HI 3 "memory_operand" "m"))]
17031   "TARGET_USE_FANCY_MATH_387
17032    && flag_unsafe_math_optimizations"
17033   "* return output_fix_trunc (insn, operands, 0);"
17034   [(set_attr "type" "fistp")
17035    (set_attr "i387_cw" "floor")
17036    (set_attr "mode" "<MODE>")])
17037
17038 (define_insn "fist<mode>2_floor_with_temp"
17039   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17040         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17041          UNSPEC_FIST_FLOOR))
17042    (use (match_operand:HI 2 "memory_operand" "m,m"))
17043    (use (match_operand:HI 3 "memory_operand" "m,m"))
17044    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17045   "TARGET_USE_FANCY_MATH_387
17046    && flag_unsafe_math_optimizations"
17047   "#"
17048   [(set_attr "type" "fistp")
17049    (set_attr "i387_cw" "floor")
17050    (set_attr "mode" "<MODE>")])
17051
17052 (define_split
17053   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17054         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17055          UNSPEC_FIST_FLOOR))
17056    (use (match_operand:HI 2 "memory_operand" ""))
17057    (use (match_operand:HI 3 "memory_operand" ""))
17058    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17059   "reload_completed"
17060   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17061                                   UNSPEC_FIST_FLOOR))
17062               (use (match_dup 2))
17063               (use (match_dup 3))])
17064    (set (match_dup 0) (match_dup 4))]
17065   "")
17066
17067 (define_split
17068   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17069         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17070          UNSPEC_FIST_FLOOR))
17071    (use (match_operand:HI 2 "memory_operand" ""))
17072    (use (match_operand:HI 3 "memory_operand" ""))
17073    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17074   "reload_completed"
17075   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17076                                   UNSPEC_FIST_FLOOR))
17077               (use (match_dup 2))
17078               (use (match_dup 3))])]
17079   "")
17080
17081 (define_expand "lfloorxf<mode>2"
17082   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17083                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17084                     UNSPEC_FIST_FLOOR))
17085               (clobber (reg:CC FLAGS_REG))])]
17086   "TARGET_USE_FANCY_MATH_387
17087    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17088    && flag_unsafe_math_optimizations"
17089   "")
17090
17091 (define_expand "lfloor<mode>di2"
17092   [(match_operand:DI 0 "nonimmediate_operand" "")
17093    (match_operand:SSEMODEF 1 "register_operand" "")]
17094   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17095    && !flag_trapping_math
17096    && !optimize_size"
17097 {
17098   ix86_expand_lfloorceil (operand0, operand1, true);
17099   DONE;
17100 })
17101
17102 (define_expand "lfloor<mode>si2"
17103   [(match_operand:SI 0 "nonimmediate_operand" "")
17104    (match_operand:SSEMODEF 1 "register_operand" "")]
17105   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17106    && !flag_trapping_math
17107    && (!optimize_size || !TARGET_64BIT)"
17108 {
17109   ix86_expand_lfloorceil (operand0, operand1, true);
17110   DONE;
17111 })
17112
17113 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17114 (define_insn_and_split "frndintxf2_ceil"
17115   [(set (match_operand:XF 0 "register_operand" "=f")
17116         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17117          UNSPEC_FRNDINT_CEIL))
17118    (clobber (reg:CC FLAGS_REG))]
17119   "TARGET_USE_FANCY_MATH_387
17120    && flag_unsafe_math_optimizations
17121    && !(reload_completed || reload_in_progress)"
17122   "#"
17123   "&& 1"
17124   [(const_int 0)]
17125 {
17126   ix86_optimize_mode_switching[I387_CEIL] = 1;
17127
17128   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17129   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17130
17131   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17132                                        operands[2], operands[3]));
17133   DONE;
17134 }
17135   [(set_attr "type" "frndint")
17136    (set_attr "i387_cw" "ceil")
17137    (set_attr "mode" "XF")])
17138
17139 (define_insn "frndintxf2_ceil_i387"
17140   [(set (match_operand:XF 0 "register_operand" "=f")
17141         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17142          UNSPEC_FRNDINT_CEIL))
17143    (use (match_operand:HI 2 "memory_operand" "m"))
17144    (use (match_operand:HI 3 "memory_operand" "m"))]
17145   "TARGET_USE_FANCY_MATH_387
17146    && flag_unsafe_math_optimizations"
17147   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17148   [(set_attr "type" "frndint")
17149    (set_attr "i387_cw" "ceil")
17150    (set_attr "mode" "XF")])
17151
17152 (define_expand "ceilxf2"
17153   [(use (match_operand:XF 0 "register_operand" ""))
17154    (use (match_operand:XF 1 "register_operand" ""))]
17155   "TARGET_USE_FANCY_MATH_387
17156    && flag_unsafe_math_optimizations && !optimize_size"
17157 {
17158   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17159   DONE;
17160 })
17161
17162 (define_expand "ceildf2"
17163   [(use (match_operand:DF 0 "register_operand" ""))
17164    (use (match_operand:DF 1 "register_operand" ""))]
17165   "((TARGET_USE_FANCY_MATH_387
17166      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17167      && flag_unsafe_math_optimizations)
17168     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17169         && !flag_trapping_math))
17170    && !optimize_size"
17171 {
17172   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17173       && !flag_trapping_math)
17174     {
17175       if (TARGET_64BIT)
17176         ix86_expand_floorceil (operand0, operand1, false);
17177       else
17178         ix86_expand_floorceildf_32 (operand0, operand1, false);
17179     }
17180   else
17181     {
17182       rtx op0 = gen_reg_rtx (XFmode);
17183       rtx op1 = gen_reg_rtx (XFmode);
17184
17185       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17186       emit_insn (gen_frndintxf2_ceil (op0, op1));
17187
17188       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17189     }
17190   DONE;
17191 })
17192
17193 (define_expand "ceilsf2"
17194   [(use (match_operand:SF 0 "register_operand" ""))
17195    (use (match_operand:SF 1 "register_operand" ""))]
17196   "((TARGET_USE_FANCY_MATH_387
17197      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17198      && flag_unsafe_math_optimizations)
17199     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17200         && !flag_trapping_math))
17201    && !optimize_size"
17202 {
17203   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17204       && !flag_trapping_math)
17205     ix86_expand_floorceil (operand0, operand1, false);
17206   else
17207     {
17208       rtx op0 = gen_reg_rtx (XFmode);
17209       rtx op1 = gen_reg_rtx (XFmode);
17210
17211       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17212       emit_insn (gen_frndintxf2_ceil (op0, op1));
17213
17214       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17215     }
17216   DONE;
17217 })
17218
17219 (define_insn_and_split "*fist<mode>2_ceil_1"
17220   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17221         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17222          UNSPEC_FIST_CEIL))
17223    (clobber (reg:CC FLAGS_REG))]
17224   "TARGET_USE_FANCY_MATH_387
17225    && flag_unsafe_math_optimizations
17226    && !(reload_completed || reload_in_progress)"
17227   "#"
17228   "&& 1"
17229   [(const_int 0)]
17230 {
17231   ix86_optimize_mode_switching[I387_CEIL] = 1;
17232
17233   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17234   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17235   if (memory_operand (operands[0], VOIDmode))
17236     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17237                                      operands[2], operands[3]));
17238   else
17239     {
17240       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17241       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17242                                                  operands[2], operands[3],
17243                                                  operands[4]));
17244     }
17245   DONE;
17246 }
17247   [(set_attr "type" "fistp")
17248    (set_attr "i387_cw" "ceil")
17249    (set_attr "mode" "<MODE>")])
17250
17251 (define_insn "fistdi2_ceil"
17252   [(set (match_operand:DI 0 "memory_operand" "=m")
17253         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17254          UNSPEC_FIST_CEIL))
17255    (use (match_operand:HI 2 "memory_operand" "m"))
17256    (use (match_operand:HI 3 "memory_operand" "m"))
17257    (clobber (match_scratch:XF 4 "=&1f"))]
17258   "TARGET_USE_FANCY_MATH_387
17259    && flag_unsafe_math_optimizations"
17260   "* return output_fix_trunc (insn, operands, 0);"
17261   [(set_attr "type" "fistp")
17262    (set_attr "i387_cw" "ceil")
17263    (set_attr "mode" "DI")])
17264
17265 (define_insn "fistdi2_ceil_with_temp"
17266   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17267         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17268          UNSPEC_FIST_CEIL))
17269    (use (match_operand:HI 2 "memory_operand" "m,m"))
17270    (use (match_operand:HI 3 "memory_operand" "m,m"))
17271    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17272    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17273   "TARGET_USE_FANCY_MATH_387
17274    && flag_unsafe_math_optimizations"
17275   "#"
17276   [(set_attr "type" "fistp")
17277    (set_attr "i387_cw" "ceil")
17278    (set_attr "mode" "DI")])
17279
17280 (define_split
17281   [(set (match_operand:DI 0 "register_operand" "")
17282         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17283          UNSPEC_FIST_CEIL))
17284    (use (match_operand:HI 2 "memory_operand" ""))
17285    (use (match_operand:HI 3 "memory_operand" ""))
17286    (clobber (match_operand:DI 4 "memory_operand" ""))
17287    (clobber (match_scratch 5 ""))]
17288   "reload_completed"
17289   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17290               (use (match_dup 2))
17291               (use (match_dup 3))
17292               (clobber (match_dup 5))])
17293    (set (match_dup 0) (match_dup 4))]
17294   "")
17295
17296 (define_split
17297   [(set (match_operand:DI 0 "memory_operand" "")
17298         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17299          UNSPEC_FIST_CEIL))
17300    (use (match_operand:HI 2 "memory_operand" ""))
17301    (use (match_operand:HI 3 "memory_operand" ""))
17302    (clobber (match_operand:DI 4 "memory_operand" ""))
17303    (clobber (match_scratch 5 ""))]
17304   "reload_completed"
17305   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17306               (use (match_dup 2))
17307               (use (match_dup 3))
17308               (clobber (match_dup 5))])]
17309   "")
17310
17311 (define_insn "fist<mode>2_ceil"
17312   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17313         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17314          UNSPEC_FIST_CEIL))
17315    (use (match_operand:HI 2 "memory_operand" "m"))
17316    (use (match_operand:HI 3 "memory_operand" "m"))]
17317   "TARGET_USE_FANCY_MATH_387
17318    && flag_unsafe_math_optimizations"
17319   "* return output_fix_trunc (insn, operands, 0);"
17320   [(set_attr "type" "fistp")
17321    (set_attr "i387_cw" "ceil")
17322    (set_attr "mode" "<MODE>")])
17323
17324 (define_insn "fist<mode>2_ceil_with_temp"
17325   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17326         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17327          UNSPEC_FIST_CEIL))
17328    (use (match_operand:HI 2 "memory_operand" "m,m"))
17329    (use (match_operand:HI 3 "memory_operand" "m,m"))
17330    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17331   "TARGET_USE_FANCY_MATH_387
17332    && flag_unsafe_math_optimizations"
17333   "#"
17334   [(set_attr "type" "fistp")
17335    (set_attr "i387_cw" "ceil")
17336    (set_attr "mode" "<MODE>")])
17337
17338 (define_split
17339   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17340         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17341          UNSPEC_FIST_CEIL))
17342    (use (match_operand:HI 2 "memory_operand" ""))
17343    (use (match_operand:HI 3 "memory_operand" ""))
17344    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17345   "reload_completed"
17346   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17347                                   UNSPEC_FIST_CEIL))
17348               (use (match_dup 2))
17349               (use (match_dup 3))])
17350    (set (match_dup 0) (match_dup 4))]
17351   "")
17352
17353 (define_split
17354   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17355         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17356          UNSPEC_FIST_CEIL))
17357    (use (match_operand:HI 2 "memory_operand" ""))
17358    (use (match_operand:HI 3 "memory_operand" ""))
17359    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17360   "reload_completed"
17361   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17362                                   UNSPEC_FIST_CEIL))
17363               (use (match_dup 2))
17364               (use (match_dup 3))])]
17365   "")
17366
17367 (define_expand "lceilxf<mode>2"
17368   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17369                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17370                     UNSPEC_FIST_CEIL))
17371               (clobber (reg:CC FLAGS_REG))])]
17372   "TARGET_USE_FANCY_MATH_387
17373    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17374    && flag_unsafe_math_optimizations"
17375   "")
17376
17377 (define_expand "lceil<mode>di2"
17378   [(match_operand:DI 0 "nonimmediate_operand" "")
17379    (match_operand:SSEMODEF 1 "register_operand" "")]
17380   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17381    && !flag_trapping_math"
17382 {
17383   ix86_expand_lfloorceil (operand0, operand1, false);
17384   DONE;
17385 })
17386
17387 (define_expand "lceil<mode>si2"
17388   [(match_operand:SI 0 "nonimmediate_operand" "")
17389    (match_operand:SSEMODEF 1 "register_operand" "")]
17390   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17391    && !flag_trapping_math"
17392 {
17393   ix86_expand_lfloorceil (operand0, operand1, false);
17394   DONE;
17395 })
17396
17397 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17398 (define_insn_and_split "frndintxf2_trunc"
17399   [(set (match_operand:XF 0 "register_operand" "=f")
17400         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17401          UNSPEC_FRNDINT_TRUNC))
17402    (clobber (reg:CC FLAGS_REG))]
17403   "TARGET_USE_FANCY_MATH_387
17404    && flag_unsafe_math_optimizations
17405    && !(reload_completed || reload_in_progress)"
17406   "#"
17407   "&& 1"
17408   [(const_int 0)]
17409 {
17410   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17411
17412   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17413   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17414
17415   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17416                                         operands[2], operands[3]));
17417   DONE;
17418 }
17419   [(set_attr "type" "frndint")
17420    (set_attr "i387_cw" "trunc")
17421    (set_attr "mode" "XF")])
17422
17423 (define_insn "frndintxf2_trunc_i387"
17424   [(set (match_operand:XF 0 "register_operand" "=f")
17425         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17426          UNSPEC_FRNDINT_TRUNC))
17427    (use (match_operand:HI 2 "memory_operand" "m"))
17428    (use (match_operand:HI 3 "memory_operand" "m"))]
17429   "TARGET_USE_FANCY_MATH_387
17430    && flag_unsafe_math_optimizations"
17431   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17432   [(set_attr "type" "frndint")
17433    (set_attr "i387_cw" "trunc")
17434    (set_attr "mode" "XF")])
17435
17436 (define_expand "btruncxf2"
17437   [(use (match_operand:XF 0 "register_operand" ""))
17438    (use (match_operand:XF 1 "register_operand" ""))]
17439   "TARGET_USE_FANCY_MATH_387
17440    && flag_unsafe_math_optimizations && !optimize_size"
17441 {
17442   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17443   DONE;
17444 })
17445
17446 (define_expand "btruncdf2"
17447   [(use (match_operand:DF 0 "register_operand" ""))
17448    (use (match_operand:DF 1 "register_operand" ""))]
17449   "((TARGET_USE_FANCY_MATH_387
17450      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17451      && flag_unsafe_math_optimizations)
17452     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17453         && !flag_trapping_math))
17454    && !optimize_size"
17455 {
17456   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17457       && !flag_trapping_math)
17458     {
17459       if (TARGET_64BIT)
17460         ix86_expand_trunc (operand0, operand1);
17461       else
17462         ix86_expand_truncdf_32 (operand0, operand1);
17463     }
17464   else
17465     {
17466       rtx op0 = gen_reg_rtx (XFmode);
17467       rtx op1 = gen_reg_rtx (XFmode);
17468
17469       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17470       emit_insn (gen_frndintxf2_trunc (op0, op1));
17471
17472       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17473     }
17474   DONE;
17475 })
17476
17477 (define_expand "btruncsf2"
17478   [(use (match_operand:SF 0 "register_operand" ""))
17479    (use (match_operand:SF 1 "register_operand" ""))]
17480   "((TARGET_USE_FANCY_MATH_387
17481      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17482      && flag_unsafe_math_optimizations)
17483     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17484         && !flag_trapping_math))
17485    && !optimize_size"
17486 {
17487   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17488       && !flag_trapping_math)
17489     ix86_expand_trunc (operand0, operand1);
17490   else
17491     {
17492       rtx op0 = gen_reg_rtx (XFmode);
17493       rtx op1 = gen_reg_rtx (XFmode);
17494
17495       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17496       emit_insn (gen_frndintxf2_trunc (op0, op1));
17497
17498       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17499     }
17500   DONE;
17501 })
17502
17503 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17504 (define_insn_and_split "frndintxf2_mask_pm"
17505   [(set (match_operand:XF 0 "register_operand" "=f")
17506         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17507          UNSPEC_FRNDINT_MASK_PM))
17508    (clobber (reg:CC FLAGS_REG))]
17509   "TARGET_USE_FANCY_MATH_387
17510    && flag_unsafe_math_optimizations
17511    && !(reload_completed || reload_in_progress)"
17512   "#"
17513   "&& 1"
17514   [(const_int 0)]
17515 {
17516   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17517
17518   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17519   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17520
17521   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17522                                           operands[2], operands[3]));
17523   DONE;
17524 }
17525   [(set_attr "type" "frndint")
17526    (set_attr "i387_cw" "mask_pm")
17527    (set_attr "mode" "XF")])
17528
17529 (define_insn "frndintxf2_mask_pm_i387"
17530   [(set (match_operand:XF 0 "register_operand" "=f")
17531         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17532          UNSPEC_FRNDINT_MASK_PM))
17533    (use (match_operand:HI 2 "memory_operand" "m"))
17534    (use (match_operand:HI 3 "memory_operand" "m"))]
17535   "TARGET_USE_FANCY_MATH_387
17536    && flag_unsafe_math_optimizations"
17537   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17538   [(set_attr "type" "frndint")
17539    (set_attr "i387_cw" "mask_pm")
17540    (set_attr "mode" "XF")])
17541
17542 (define_expand "nearbyintxf2"
17543   [(use (match_operand:XF 0 "register_operand" ""))
17544    (use (match_operand:XF 1 "register_operand" ""))]
17545   "TARGET_USE_FANCY_MATH_387
17546    && flag_unsafe_math_optimizations"
17547 {
17548   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17549
17550   DONE;
17551 })
17552
17553 (define_expand "nearbyintdf2"
17554   [(use (match_operand:DF 0 "register_operand" ""))
17555    (use (match_operand:DF 1 "register_operand" ""))]
17556   "TARGET_USE_FANCY_MATH_387
17557    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17558    && flag_unsafe_math_optimizations"
17559 {
17560   rtx op0 = gen_reg_rtx (XFmode);
17561   rtx op1 = gen_reg_rtx (XFmode);
17562
17563   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17564   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17565
17566   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17567   DONE;
17568 })
17569
17570 (define_expand "nearbyintsf2"
17571   [(use (match_operand:SF 0 "register_operand" ""))
17572    (use (match_operand:SF 1 "register_operand" ""))]
17573   "TARGET_USE_FANCY_MATH_387
17574    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17575    && flag_unsafe_math_optimizations"
17576 {
17577   rtx op0 = gen_reg_rtx (XFmode);
17578   rtx op1 = gen_reg_rtx (XFmode);
17579
17580   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17581   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17582
17583   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17584   DONE;
17585 })
17586
17587 \f
17588 ;; Block operation instructions
17589
17590 (define_expand "movmemsi"
17591   [(use (match_operand:BLK 0 "memory_operand" ""))
17592    (use (match_operand:BLK 1 "memory_operand" ""))
17593    (use (match_operand:SI 2 "nonmemory_operand" ""))
17594    (use (match_operand:SI 3 "const_int_operand" ""))]
17595   ""
17596 {
17597  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17598                          operands[3], constm1_rtx))
17599    DONE;
17600  else
17601    FAIL;
17602 })
17603
17604 (define_expand "movmemdi"
17605   [(use (match_operand:BLK 0 "memory_operand" ""))
17606    (use (match_operand:BLK 1 "memory_operand" ""))
17607    (use (match_operand:DI 2 "nonmemory_operand" ""))
17608    (use (match_operand:DI 3 "const_int_operand" ""))]
17609   "TARGET_64BIT"
17610 {
17611  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17612                          operands[3], constm1_rtx))
17613    DONE;
17614  else
17615    FAIL;
17616 })
17617
17618 ;; Most CPUs don't like single string operations
17619 ;; Handle this case here to simplify previous expander.
17620
17621 (define_expand "strmov"
17622   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17623    (set (match_operand 1 "memory_operand" "") (match_dup 4))
17624    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17625               (clobber (reg:CC FLAGS_REG))])
17626    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17627               (clobber (reg:CC FLAGS_REG))])]
17628   ""
17629 {
17630   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17631
17632   /* If .md ever supports :P for Pmode, these can be directly
17633      in the pattern above.  */
17634   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17635   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17636
17637   if (TARGET_SINGLE_STRINGOP || optimize_size)
17638     {
17639       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17640                                       operands[2], operands[3],
17641                                       operands[5], operands[6]));
17642       DONE;
17643     }
17644
17645   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17646 })
17647
17648 (define_expand "strmov_singleop"
17649   [(parallel [(set (match_operand 1 "memory_operand" "")
17650                    (match_operand 3 "memory_operand" ""))
17651               (set (match_operand 0 "register_operand" "")
17652                    (match_operand 4 "" ""))
17653               (set (match_operand 2 "register_operand" "")
17654                    (match_operand 5 "" ""))])]
17655   "TARGET_SINGLE_STRINGOP || optimize_size"
17656   "")
17657
17658 (define_insn "*strmovdi_rex_1"
17659   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17660         (mem:DI (match_operand:DI 3 "register_operand" "1")))
17661    (set (match_operand:DI 0 "register_operand" "=D")
17662         (plus:DI (match_dup 2)
17663                  (const_int 8)))
17664    (set (match_operand:DI 1 "register_operand" "=S")
17665         (plus:DI (match_dup 3)
17666                  (const_int 8)))]
17667   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17668   "movsq"
17669   [(set_attr "type" "str")
17670    (set_attr "mode" "DI")
17671    (set_attr "memory" "both")])
17672
17673 (define_insn "*strmovsi_1"
17674   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17675         (mem:SI (match_operand:SI 3 "register_operand" "1")))
17676    (set (match_operand:SI 0 "register_operand" "=D")
17677         (plus:SI (match_dup 2)
17678                  (const_int 4)))
17679    (set (match_operand:SI 1 "register_operand" "=S")
17680         (plus:SI (match_dup 3)
17681                  (const_int 4)))]
17682   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17683   "{movsl|movsd}"
17684   [(set_attr "type" "str")
17685    (set_attr "mode" "SI")
17686    (set_attr "memory" "both")])
17687
17688 (define_insn "*strmovsi_rex_1"
17689   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17690         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17691    (set (match_operand:DI 0 "register_operand" "=D")
17692         (plus:DI (match_dup 2)
17693                  (const_int 4)))
17694    (set (match_operand:DI 1 "register_operand" "=S")
17695         (plus:DI (match_dup 3)
17696                  (const_int 4)))]
17697   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17698   "{movsl|movsd}"
17699   [(set_attr "type" "str")
17700    (set_attr "mode" "SI")
17701    (set_attr "memory" "both")])
17702
17703 (define_insn "*strmovhi_1"
17704   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17705         (mem:HI (match_operand:SI 3 "register_operand" "1")))
17706    (set (match_operand:SI 0 "register_operand" "=D")
17707         (plus:SI (match_dup 2)
17708                  (const_int 2)))
17709    (set (match_operand:SI 1 "register_operand" "=S")
17710         (plus:SI (match_dup 3)
17711                  (const_int 2)))]
17712   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17713   "movsw"
17714   [(set_attr "type" "str")
17715    (set_attr "memory" "both")
17716    (set_attr "mode" "HI")])
17717
17718 (define_insn "*strmovhi_rex_1"
17719   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17720         (mem:HI (match_operand:DI 3 "register_operand" "1")))
17721    (set (match_operand:DI 0 "register_operand" "=D")
17722         (plus:DI (match_dup 2)
17723                  (const_int 2)))
17724    (set (match_operand:DI 1 "register_operand" "=S")
17725         (plus:DI (match_dup 3)
17726                  (const_int 2)))]
17727   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17728   "movsw"
17729   [(set_attr "type" "str")
17730    (set_attr "memory" "both")
17731    (set_attr "mode" "HI")])
17732
17733 (define_insn "*strmovqi_1"
17734   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17735         (mem:QI (match_operand:SI 3 "register_operand" "1")))
17736    (set (match_operand:SI 0 "register_operand" "=D")
17737         (plus:SI (match_dup 2)
17738                  (const_int 1)))
17739    (set (match_operand:SI 1 "register_operand" "=S")
17740         (plus:SI (match_dup 3)
17741                  (const_int 1)))]
17742   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17743   "movsb"
17744   [(set_attr "type" "str")
17745    (set_attr "memory" "both")
17746    (set_attr "mode" "QI")])
17747
17748 (define_insn "*strmovqi_rex_1"
17749   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17750         (mem:QI (match_operand:DI 3 "register_operand" "1")))
17751    (set (match_operand:DI 0 "register_operand" "=D")
17752         (plus:DI (match_dup 2)
17753                  (const_int 1)))
17754    (set (match_operand:DI 1 "register_operand" "=S")
17755         (plus:DI (match_dup 3)
17756                  (const_int 1)))]
17757   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17758   "movsb"
17759   [(set_attr "type" "str")
17760    (set_attr "memory" "both")
17761    (set_attr "mode" "QI")])
17762
17763 (define_expand "rep_mov"
17764   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17765               (set (match_operand 0 "register_operand" "")
17766                    (match_operand 5 "" ""))
17767               (set (match_operand 2 "register_operand" "")
17768                    (match_operand 6 "" ""))
17769               (set (match_operand 1 "memory_operand" "")
17770                    (match_operand 3 "memory_operand" ""))
17771               (use (match_dup 4))])]
17772   ""
17773   "")
17774
17775 (define_insn "*rep_movdi_rex64"
17776   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17777    (set (match_operand:DI 0 "register_operand" "=D")
17778         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17779                             (const_int 3))
17780                  (match_operand:DI 3 "register_operand" "0")))
17781    (set (match_operand:DI 1 "register_operand" "=S")
17782         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17783                  (match_operand:DI 4 "register_operand" "1")))
17784    (set (mem:BLK (match_dup 3))
17785         (mem:BLK (match_dup 4)))
17786    (use (match_dup 5))]
17787   "TARGET_64BIT"
17788   "{rep\;movsq|rep movsq}"
17789   [(set_attr "type" "str")
17790    (set_attr "prefix_rep" "1")
17791    (set_attr "memory" "both")
17792    (set_attr "mode" "DI")])
17793
17794 (define_insn "*rep_movsi"
17795   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17796    (set (match_operand:SI 0 "register_operand" "=D")
17797         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17798                             (const_int 2))
17799                  (match_operand:SI 3 "register_operand" "0")))
17800    (set (match_operand:SI 1 "register_operand" "=S")
17801         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17802                  (match_operand:SI 4 "register_operand" "1")))
17803    (set (mem:BLK (match_dup 3))
17804         (mem:BLK (match_dup 4)))
17805    (use (match_dup 5))]
17806   "!TARGET_64BIT"
17807   "{rep\;movsl|rep movsd}"
17808   [(set_attr "type" "str")
17809    (set_attr "prefix_rep" "1")
17810    (set_attr "memory" "both")
17811    (set_attr "mode" "SI")])
17812
17813 (define_insn "*rep_movsi_rex64"
17814   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17815    (set (match_operand:DI 0 "register_operand" "=D")
17816         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17817                             (const_int 2))
17818                  (match_operand:DI 3 "register_operand" "0")))
17819    (set (match_operand:DI 1 "register_operand" "=S")
17820         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17821                  (match_operand:DI 4 "register_operand" "1")))
17822    (set (mem:BLK (match_dup 3))
17823         (mem:BLK (match_dup 4)))
17824    (use (match_dup 5))]
17825   "TARGET_64BIT"
17826   "{rep\;movsl|rep movsd}"
17827   [(set_attr "type" "str")
17828    (set_attr "prefix_rep" "1")
17829    (set_attr "memory" "both")
17830    (set_attr "mode" "SI")])
17831
17832 (define_insn "*rep_movqi"
17833   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17834    (set (match_operand:SI 0 "register_operand" "=D")
17835         (plus:SI (match_operand:SI 3 "register_operand" "0")
17836                  (match_operand:SI 5 "register_operand" "2")))
17837    (set (match_operand:SI 1 "register_operand" "=S")
17838         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17839    (set (mem:BLK (match_dup 3))
17840         (mem:BLK (match_dup 4)))
17841    (use (match_dup 5))]
17842   "!TARGET_64BIT"
17843   "{rep\;movsb|rep movsb}"
17844   [(set_attr "type" "str")
17845    (set_attr "prefix_rep" "1")
17846    (set_attr "memory" "both")
17847    (set_attr "mode" "SI")])
17848
17849 (define_insn "*rep_movqi_rex64"
17850   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17851    (set (match_operand:DI 0 "register_operand" "=D")
17852         (plus:DI (match_operand:DI 3 "register_operand" "0")
17853                  (match_operand:DI 5 "register_operand" "2")))
17854    (set (match_operand:DI 1 "register_operand" "=S")
17855         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17856    (set (mem:BLK (match_dup 3))
17857         (mem:BLK (match_dup 4)))
17858    (use (match_dup 5))]
17859   "TARGET_64BIT"
17860   "{rep\;movsb|rep movsb}"
17861   [(set_attr "type" "str")
17862    (set_attr "prefix_rep" "1")
17863    (set_attr "memory" "both")
17864    (set_attr "mode" "SI")])
17865
17866 (define_expand "setmemsi"
17867    [(use (match_operand:BLK 0 "memory_operand" ""))
17868     (use (match_operand:SI 1 "nonmemory_operand" ""))
17869     (use (match_operand 2 "const_int_operand" ""))
17870     (use (match_operand 3 "const_int_operand" ""))]
17871   ""
17872 {
17873  if (ix86_expand_setmem (operands[0], operands[1],
17874                          operands[2], operands[3],
17875                          operands[3], constm1_rtx))
17876    DONE;
17877  else
17878    FAIL;
17879 })
17880
17881 (define_expand "setmemdi"
17882    [(use (match_operand:BLK 0 "memory_operand" ""))
17883     (use (match_operand:DI 1 "nonmemory_operand" ""))
17884     (use (match_operand 2 "const_int_operand" ""))
17885     (use (match_operand 3 "const_int_operand" ""))
17886     (use (match_operand 4 "const_int_operand" ""))
17887     (use (match_operand 5 "const_int_operand" ""))]
17888   "TARGET_64BIT"
17889 {
17890  if (ix86_expand_setmem (operands[0], operands[1],
17891                          operands[2], operands[3],
17892                          operands[3], constm1_rtx))
17893    DONE;
17894  else
17895    FAIL;
17896 })
17897
17898 ;; Most CPUs don't like single string operations
17899 ;; Handle this case here to simplify previous expander.
17900
17901 (define_expand "strset"
17902   [(set (match_operand 1 "memory_operand" "")
17903         (match_operand 2 "register_operand" ""))
17904    (parallel [(set (match_operand 0 "register_operand" "")
17905                    (match_dup 3))
17906               (clobber (reg:CC FLAGS_REG))])]
17907   ""
17908 {
17909   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17910     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17911
17912   /* If .md ever supports :P for Pmode, this can be directly
17913      in the pattern above.  */
17914   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17915                               GEN_INT (GET_MODE_SIZE (GET_MODE
17916                                                       (operands[2]))));
17917   if (TARGET_SINGLE_STRINGOP || optimize_size)
17918     {
17919       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17920                                       operands[3]));
17921       DONE;
17922     }
17923 })
17924
17925 (define_expand "strset_singleop"
17926   [(parallel [(set (match_operand 1 "memory_operand" "")
17927                    (match_operand 2 "register_operand" ""))
17928               (set (match_operand 0 "register_operand" "")
17929                    (match_operand 3 "" ""))])]
17930   "TARGET_SINGLE_STRINGOP || optimize_size"
17931   "")
17932
17933 (define_insn "*strsetdi_rex_1"
17934   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17935         (match_operand:DI 2 "register_operand" "a"))
17936    (set (match_operand:DI 0 "register_operand" "=D")
17937         (plus:DI (match_dup 1)
17938                  (const_int 8)))]
17939   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17940   "stosq"
17941   [(set_attr "type" "str")
17942    (set_attr "memory" "store")
17943    (set_attr "mode" "DI")])
17944
17945 (define_insn "*strsetsi_1"
17946   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17947         (match_operand:SI 2 "register_operand" "a"))
17948    (set (match_operand:SI 0 "register_operand" "=D")
17949         (plus:SI (match_dup 1)
17950                  (const_int 4)))]
17951   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17952   "{stosl|stosd}"
17953   [(set_attr "type" "str")
17954    (set_attr "memory" "store")
17955    (set_attr "mode" "SI")])
17956
17957 (define_insn "*strsetsi_rex_1"
17958   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17959         (match_operand:SI 2 "register_operand" "a"))
17960    (set (match_operand:DI 0 "register_operand" "=D")
17961         (plus:DI (match_dup 1)
17962                  (const_int 4)))]
17963   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17964   "{stosl|stosd}"
17965   [(set_attr "type" "str")
17966    (set_attr "memory" "store")
17967    (set_attr "mode" "SI")])
17968
17969 (define_insn "*strsethi_1"
17970   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17971         (match_operand:HI 2 "register_operand" "a"))
17972    (set (match_operand:SI 0 "register_operand" "=D")
17973         (plus:SI (match_dup 1)
17974                  (const_int 2)))]
17975   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17976   "stosw"
17977   [(set_attr "type" "str")
17978    (set_attr "memory" "store")
17979    (set_attr "mode" "HI")])
17980
17981 (define_insn "*strsethi_rex_1"
17982   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17983         (match_operand:HI 2 "register_operand" "a"))
17984    (set (match_operand:DI 0 "register_operand" "=D")
17985         (plus:DI (match_dup 1)
17986                  (const_int 2)))]
17987   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17988   "stosw"
17989   [(set_attr "type" "str")
17990    (set_attr "memory" "store")
17991    (set_attr "mode" "HI")])
17992
17993 (define_insn "*strsetqi_1"
17994   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17995         (match_operand:QI 2 "register_operand" "a"))
17996    (set (match_operand:SI 0 "register_operand" "=D")
17997         (plus:SI (match_dup 1)
17998                  (const_int 1)))]
17999   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18000   "stosb"
18001   [(set_attr "type" "str")
18002    (set_attr "memory" "store")
18003    (set_attr "mode" "QI")])
18004
18005 (define_insn "*strsetqi_rex_1"
18006   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18007         (match_operand:QI 2 "register_operand" "a"))
18008    (set (match_operand:DI 0 "register_operand" "=D")
18009         (plus:DI (match_dup 1)
18010                  (const_int 1)))]
18011   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18012   "stosb"
18013   [(set_attr "type" "str")
18014    (set_attr "memory" "store")
18015    (set_attr "mode" "QI")])
18016
18017 (define_expand "rep_stos"
18018   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18019               (set (match_operand 0 "register_operand" "")
18020                    (match_operand 4 "" ""))
18021               (set (match_operand 2 "memory_operand" "") (const_int 0))
18022               (use (match_operand 3 "register_operand" ""))
18023               (use (match_dup 1))])]
18024   ""
18025   "")
18026
18027 (define_insn "*rep_stosdi_rex64"
18028   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18029    (set (match_operand:DI 0 "register_operand" "=D")
18030         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18031                             (const_int 3))
18032                  (match_operand:DI 3 "register_operand" "0")))
18033    (set (mem:BLK (match_dup 3))
18034         (const_int 0))
18035    (use (match_operand:DI 2 "register_operand" "a"))
18036    (use (match_dup 4))]
18037   "TARGET_64BIT"
18038   "{rep\;stosq|rep stosq}"
18039   [(set_attr "type" "str")
18040    (set_attr "prefix_rep" "1")
18041    (set_attr "memory" "store")
18042    (set_attr "mode" "DI")])
18043
18044 (define_insn "*rep_stossi"
18045   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18046    (set (match_operand:SI 0 "register_operand" "=D")
18047         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18048                             (const_int 2))
18049                  (match_operand:SI 3 "register_operand" "0")))
18050    (set (mem:BLK (match_dup 3))
18051         (const_int 0))
18052    (use (match_operand:SI 2 "register_operand" "a"))
18053    (use (match_dup 4))]
18054   "!TARGET_64BIT"
18055   "{rep\;stosl|rep stosd}"
18056   [(set_attr "type" "str")
18057    (set_attr "prefix_rep" "1")
18058    (set_attr "memory" "store")
18059    (set_attr "mode" "SI")])
18060
18061 (define_insn "*rep_stossi_rex64"
18062   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18063    (set (match_operand:DI 0 "register_operand" "=D")
18064         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18065                             (const_int 2))
18066                  (match_operand:DI 3 "register_operand" "0")))
18067    (set (mem:BLK (match_dup 3))
18068         (const_int 0))
18069    (use (match_operand:SI 2 "register_operand" "a"))
18070    (use (match_dup 4))]
18071   "TARGET_64BIT"
18072   "{rep\;stosl|rep stosd}"
18073   [(set_attr "type" "str")
18074    (set_attr "prefix_rep" "1")
18075    (set_attr "memory" "store")
18076    (set_attr "mode" "SI")])
18077
18078 (define_insn "*rep_stosqi"
18079   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18080    (set (match_operand:SI 0 "register_operand" "=D")
18081         (plus:SI (match_operand:SI 3 "register_operand" "0")
18082                  (match_operand:SI 4 "register_operand" "1")))
18083    (set (mem:BLK (match_dup 3))
18084         (const_int 0))
18085    (use (match_operand:QI 2 "register_operand" "a"))
18086    (use (match_dup 4))]
18087   "!TARGET_64BIT"
18088   "{rep\;stosb|rep stosb}"
18089   [(set_attr "type" "str")
18090    (set_attr "prefix_rep" "1")
18091    (set_attr "memory" "store")
18092    (set_attr "mode" "QI")])
18093
18094 (define_insn "*rep_stosqi_rex64"
18095   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18096    (set (match_operand:DI 0 "register_operand" "=D")
18097         (plus:DI (match_operand:DI 3 "register_operand" "0")
18098                  (match_operand:DI 4 "register_operand" "1")))
18099    (set (mem:BLK (match_dup 3))
18100         (const_int 0))
18101    (use (match_operand:QI 2 "register_operand" "a"))
18102    (use (match_dup 4))]
18103   "TARGET_64BIT"
18104   "{rep\;stosb|rep stosb}"
18105   [(set_attr "type" "str")
18106    (set_attr "prefix_rep" "1")
18107    (set_attr "memory" "store")
18108    (set_attr "mode" "QI")])
18109
18110 (define_expand "cmpstrnsi"
18111   [(set (match_operand:SI 0 "register_operand" "")
18112         (compare:SI (match_operand:BLK 1 "general_operand" "")
18113                     (match_operand:BLK 2 "general_operand" "")))
18114    (use (match_operand 3 "general_operand" ""))
18115    (use (match_operand 4 "immediate_operand" ""))]
18116   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18117 {
18118   rtx addr1, addr2, out, outlow, count, countreg, align;
18119
18120   /* Can't use this if the user has appropriated esi or edi.  */
18121   if (global_regs[4] || global_regs[5])
18122     FAIL;
18123
18124   out = operands[0];
18125   if (!REG_P (out))
18126     out = gen_reg_rtx (SImode);
18127
18128   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18129   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18130   if (addr1 != XEXP (operands[1], 0))
18131     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18132   if (addr2 != XEXP (operands[2], 0))
18133     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18134
18135   count = operands[3];
18136   countreg = ix86_zero_extend_to_Pmode (count);
18137
18138   /* %%% Iff we are testing strict equality, we can use known alignment
18139      to good advantage.  This may be possible with combine, particularly
18140      once cc0 is dead.  */
18141   align = operands[4];
18142
18143   if (CONST_INT_P (count))
18144     {
18145       if (INTVAL (count) == 0)
18146         {
18147           emit_move_insn (operands[0], const0_rtx);
18148           DONE;
18149         }
18150       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18151                                      operands[1], operands[2]));
18152     }
18153   else
18154     {
18155       if (TARGET_64BIT)
18156         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18157       else
18158         emit_insn (gen_cmpsi_1 (countreg, countreg));
18159       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18160                                   operands[1], operands[2]));
18161     }
18162
18163   outlow = gen_lowpart (QImode, out);
18164   emit_insn (gen_cmpintqi (outlow));
18165   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18166
18167   if (operands[0] != out)
18168     emit_move_insn (operands[0], out);
18169
18170   DONE;
18171 })
18172
18173 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18174
18175 (define_expand "cmpintqi"
18176   [(set (match_dup 1)
18177         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18178    (set (match_dup 2)
18179         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18180    (parallel [(set (match_operand:QI 0 "register_operand" "")
18181                    (minus:QI (match_dup 1)
18182                              (match_dup 2)))
18183               (clobber (reg:CC FLAGS_REG))])]
18184   ""
18185   "operands[1] = gen_reg_rtx (QImode);
18186    operands[2] = gen_reg_rtx (QImode);")
18187
18188 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18189 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18190
18191 (define_expand "cmpstrnqi_nz_1"
18192   [(parallel [(set (reg:CC FLAGS_REG)
18193                    (compare:CC (match_operand 4 "memory_operand" "")
18194                                (match_operand 5 "memory_operand" "")))
18195               (use (match_operand 2 "register_operand" ""))
18196               (use (match_operand:SI 3 "immediate_operand" ""))
18197               (clobber (match_operand 0 "register_operand" ""))
18198               (clobber (match_operand 1 "register_operand" ""))
18199               (clobber (match_dup 2))])]
18200   ""
18201   "")
18202
18203 (define_insn "*cmpstrnqi_nz_1"
18204   [(set (reg:CC FLAGS_REG)
18205         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18206                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18207    (use (match_operand:SI 6 "register_operand" "2"))
18208    (use (match_operand:SI 3 "immediate_operand" "i"))
18209    (clobber (match_operand:SI 0 "register_operand" "=S"))
18210    (clobber (match_operand:SI 1 "register_operand" "=D"))
18211    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18212   "!TARGET_64BIT"
18213   "repz{\;| }cmpsb"
18214   [(set_attr "type" "str")
18215    (set_attr "mode" "QI")
18216    (set_attr "prefix_rep" "1")])
18217
18218 (define_insn "*cmpstrnqi_nz_rex_1"
18219   [(set (reg:CC FLAGS_REG)
18220         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18221                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18222    (use (match_operand:DI 6 "register_operand" "2"))
18223    (use (match_operand:SI 3 "immediate_operand" "i"))
18224    (clobber (match_operand:DI 0 "register_operand" "=S"))
18225    (clobber (match_operand:DI 1 "register_operand" "=D"))
18226    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18227   "TARGET_64BIT"
18228   "repz{\;| }cmpsb"
18229   [(set_attr "type" "str")
18230    (set_attr "mode" "QI")
18231    (set_attr "prefix_rep" "1")])
18232
18233 ;; The same, but the count is not known to not be zero.
18234
18235 (define_expand "cmpstrnqi_1"
18236   [(parallel [(set (reg:CC FLAGS_REG)
18237                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18238                                      (const_int 0))
18239                   (compare:CC (match_operand 4 "memory_operand" "")
18240                               (match_operand 5 "memory_operand" ""))
18241                   (const_int 0)))
18242               (use (match_operand:SI 3 "immediate_operand" ""))
18243               (use (reg:CC FLAGS_REG))
18244               (clobber (match_operand 0 "register_operand" ""))
18245               (clobber (match_operand 1 "register_operand" ""))
18246               (clobber (match_dup 2))])]
18247   ""
18248   "")
18249
18250 (define_insn "*cmpstrnqi_1"
18251   [(set (reg:CC FLAGS_REG)
18252         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18253                              (const_int 0))
18254           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18255                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18256           (const_int 0)))
18257    (use (match_operand:SI 3 "immediate_operand" "i"))
18258    (use (reg:CC FLAGS_REG))
18259    (clobber (match_operand:SI 0 "register_operand" "=S"))
18260    (clobber (match_operand:SI 1 "register_operand" "=D"))
18261    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18262   "!TARGET_64BIT"
18263   "repz{\;| }cmpsb"
18264   [(set_attr "type" "str")
18265    (set_attr "mode" "QI")
18266    (set_attr "prefix_rep" "1")])
18267
18268 (define_insn "*cmpstrnqi_rex_1"
18269   [(set (reg:CC FLAGS_REG)
18270         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18271                              (const_int 0))
18272           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18273                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18274           (const_int 0)))
18275    (use (match_operand:SI 3 "immediate_operand" "i"))
18276    (use (reg:CC FLAGS_REG))
18277    (clobber (match_operand:DI 0 "register_operand" "=S"))
18278    (clobber (match_operand:DI 1 "register_operand" "=D"))
18279    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18280   "TARGET_64BIT"
18281   "repz{\;| }cmpsb"
18282   [(set_attr "type" "str")
18283    (set_attr "mode" "QI")
18284    (set_attr "prefix_rep" "1")])
18285
18286 (define_expand "strlensi"
18287   [(set (match_operand:SI 0 "register_operand" "")
18288         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18289                     (match_operand:QI 2 "immediate_operand" "")
18290                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18291   ""
18292 {
18293  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18294    DONE;
18295  else
18296    FAIL;
18297 })
18298
18299 (define_expand "strlendi"
18300   [(set (match_operand:DI 0 "register_operand" "")
18301         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18302                     (match_operand:QI 2 "immediate_operand" "")
18303                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18304   ""
18305 {
18306  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18307    DONE;
18308  else
18309    FAIL;
18310 })
18311
18312 (define_expand "strlenqi_1"
18313   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18314               (clobber (match_operand 1 "register_operand" ""))
18315               (clobber (reg:CC FLAGS_REG))])]
18316   ""
18317   "")
18318
18319 (define_insn "*strlenqi_1"
18320   [(set (match_operand:SI 0 "register_operand" "=&c")
18321         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18322                     (match_operand:QI 2 "register_operand" "a")
18323                     (match_operand:SI 3 "immediate_operand" "i")
18324                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18325    (clobber (match_operand:SI 1 "register_operand" "=D"))
18326    (clobber (reg:CC FLAGS_REG))]
18327   "!TARGET_64BIT"
18328   "repnz{\;| }scasb"
18329   [(set_attr "type" "str")
18330    (set_attr "mode" "QI")
18331    (set_attr "prefix_rep" "1")])
18332
18333 (define_insn "*strlenqi_rex_1"
18334   [(set (match_operand:DI 0 "register_operand" "=&c")
18335         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18336                     (match_operand:QI 2 "register_operand" "a")
18337                     (match_operand:DI 3 "immediate_operand" "i")
18338                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18339    (clobber (match_operand:DI 1 "register_operand" "=D"))
18340    (clobber (reg:CC FLAGS_REG))]
18341   "TARGET_64BIT"
18342   "repnz{\;| }scasb"
18343   [(set_attr "type" "str")
18344    (set_attr "mode" "QI")
18345    (set_attr "prefix_rep" "1")])
18346
18347 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18348 ;; handled in combine, but it is not currently up to the task.
18349 ;; When used for their truth value, the cmpstrn* expanders generate
18350 ;; code like this:
18351 ;;
18352 ;;   repz cmpsb
18353 ;;   seta       %al
18354 ;;   setb       %dl
18355 ;;   cmpb       %al, %dl
18356 ;;   jcc        label
18357 ;;
18358 ;; The intermediate three instructions are unnecessary.
18359
18360 ;; This one handles cmpstrn*_nz_1...
18361 (define_peephole2
18362   [(parallel[
18363      (set (reg:CC FLAGS_REG)
18364           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18365                       (mem:BLK (match_operand 5 "register_operand" ""))))
18366      (use (match_operand 6 "register_operand" ""))
18367      (use (match_operand:SI 3 "immediate_operand" ""))
18368      (clobber (match_operand 0 "register_operand" ""))
18369      (clobber (match_operand 1 "register_operand" ""))
18370      (clobber (match_operand 2 "register_operand" ""))])
18371    (set (match_operand:QI 7 "register_operand" "")
18372         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18373    (set (match_operand:QI 8 "register_operand" "")
18374         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18375    (set (reg FLAGS_REG)
18376         (compare (match_dup 7) (match_dup 8)))
18377   ]
18378   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18379   [(parallel[
18380      (set (reg:CC FLAGS_REG)
18381           (compare:CC (mem:BLK (match_dup 4))
18382                       (mem:BLK (match_dup 5))))
18383      (use (match_dup 6))
18384      (use (match_dup 3))
18385      (clobber (match_dup 0))
18386      (clobber (match_dup 1))
18387      (clobber (match_dup 2))])]
18388   "")
18389
18390 ;; ...and this one handles cmpstrn*_1.
18391 (define_peephole2
18392   [(parallel[
18393      (set (reg:CC FLAGS_REG)
18394           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18395                                (const_int 0))
18396             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18397                         (mem:BLK (match_operand 5 "register_operand" "")))
18398             (const_int 0)))
18399      (use (match_operand:SI 3 "immediate_operand" ""))
18400      (use (reg:CC FLAGS_REG))
18401      (clobber (match_operand 0 "register_operand" ""))
18402      (clobber (match_operand 1 "register_operand" ""))
18403      (clobber (match_operand 2 "register_operand" ""))])
18404    (set (match_operand:QI 7 "register_operand" "")
18405         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18406    (set (match_operand:QI 8 "register_operand" "")
18407         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18408    (set (reg FLAGS_REG)
18409         (compare (match_dup 7) (match_dup 8)))
18410   ]
18411   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18412   [(parallel[
18413      (set (reg:CC FLAGS_REG)
18414           (if_then_else:CC (ne (match_dup 6)
18415                                (const_int 0))
18416             (compare:CC (mem:BLK (match_dup 4))
18417                         (mem:BLK (match_dup 5)))
18418             (const_int 0)))
18419      (use (match_dup 3))
18420      (use (reg:CC FLAGS_REG))
18421      (clobber (match_dup 0))
18422      (clobber (match_dup 1))
18423      (clobber (match_dup 2))])]
18424   "")
18425
18426
18427 \f
18428 ;; Conditional move instructions.
18429
18430 (define_expand "movdicc"
18431   [(set (match_operand:DI 0 "register_operand" "")
18432         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18433                          (match_operand:DI 2 "general_operand" "")
18434                          (match_operand:DI 3 "general_operand" "")))]
18435   "TARGET_64BIT"
18436   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18437
18438 (define_insn "x86_movdicc_0_m1_rex64"
18439   [(set (match_operand:DI 0 "register_operand" "=r")
18440         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18441           (const_int -1)
18442           (const_int 0)))
18443    (clobber (reg:CC FLAGS_REG))]
18444   "TARGET_64BIT"
18445   "sbb{q}\t%0, %0"
18446   ; Since we don't have the proper number of operands for an alu insn,
18447   ; fill in all the blanks.
18448   [(set_attr "type" "alu")
18449    (set_attr "pent_pair" "pu")
18450    (set_attr "memory" "none")
18451    (set_attr "imm_disp" "false")
18452    (set_attr "mode" "DI")
18453    (set_attr "length_immediate" "0")])
18454
18455 (define_insn "*movdicc_c_rex64"
18456   [(set (match_operand:DI 0 "register_operand" "=r,r")
18457         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18458                                 [(reg FLAGS_REG) (const_int 0)])
18459                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18460                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18461   "TARGET_64BIT && TARGET_CMOVE
18462    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18463   "@
18464    cmov%O2%C1\t{%2, %0|%0, %2}
18465    cmov%O2%c1\t{%3, %0|%0, %3}"
18466   [(set_attr "type" "icmov")
18467    (set_attr "mode" "DI")])
18468
18469 (define_expand "movsicc"
18470   [(set (match_operand:SI 0 "register_operand" "")
18471         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18472                          (match_operand:SI 2 "general_operand" "")
18473                          (match_operand:SI 3 "general_operand" "")))]
18474   ""
18475   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18476
18477 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18478 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18479 ;; So just document what we're doing explicitly.
18480
18481 (define_insn "x86_movsicc_0_m1"
18482   [(set (match_operand:SI 0 "register_operand" "=r")
18483         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18484           (const_int -1)
18485           (const_int 0)))
18486    (clobber (reg:CC FLAGS_REG))]
18487   ""
18488   "sbb{l}\t%0, %0"
18489   ; Since we don't have the proper number of operands for an alu insn,
18490   ; fill in all the blanks.
18491   [(set_attr "type" "alu")
18492    (set_attr "pent_pair" "pu")
18493    (set_attr "memory" "none")
18494    (set_attr "imm_disp" "false")
18495    (set_attr "mode" "SI")
18496    (set_attr "length_immediate" "0")])
18497
18498 (define_insn "*movsicc_noc"
18499   [(set (match_operand:SI 0 "register_operand" "=r,r")
18500         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18501                                 [(reg FLAGS_REG) (const_int 0)])
18502                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18503                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18504   "TARGET_CMOVE
18505    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18506   "@
18507    cmov%O2%C1\t{%2, %0|%0, %2}
18508    cmov%O2%c1\t{%3, %0|%0, %3}"
18509   [(set_attr "type" "icmov")
18510    (set_attr "mode" "SI")])
18511
18512 (define_expand "movhicc"
18513   [(set (match_operand:HI 0 "register_operand" "")
18514         (if_then_else:HI (match_operand 1 "comparison_operator" "")
18515                          (match_operand:HI 2 "general_operand" "")
18516                          (match_operand:HI 3 "general_operand" "")))]
18517   "TARGET_HIMODE_MATH"
18518   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18519
18520 (define_insn "*movhicc_noc"
18521   [(set (match_operand:HI 0 "register_operand" "=r,r")
18522         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18523                                 [(reg FLAGS_REG) (const_int 0)])
18524                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18525                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18526   "TARGET_CMOVE
18527    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18528   "@
18529    cmov%O2%C1\t{%2, %0|%0, %2}
18530    cmov%O2%c1\t{%3, %0|%0, %3}"
18531   [(set_attr "type" "icmov")
18532    (set_attr "mode" "HI")])
18533
18534 (define_expand "movqicc"
18535   [(set (match_operand:QI 0 "register_operand" "")
18536         (if_then_else:QI (match_operand 1 "comparison_operator" "")
18537                          (match_operand:QI 2 "general_operand" "")
18538                          (match_operand:QI 3 "general_operand" "")))]
18539   "TARGET_QIMODE_MATH"
18540   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18541
18542 (define_insn_and_split "*movqicc_noc"
18543   [(set (match_operand:QI 0 "register_operand" "=r,r")
18544         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18545                                 [(match_operand 4 "flags_reg_operand" "")
18546                                  (const_int 0)])
18547                       (match_operand:QI 2 "register_operand" "r,0")
18548                       (match_operand:QI 3 "register_operand" "0,r")))]
18549   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18550   "#"
18551   "&& reload_completed"
18552   [(set (match_dup 0)
18553         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18554                       (match_dup 2)
18555                       (match_dup 3)))]
18556   "operands[0] = gen_lowpart (SImode, operands[0]);
18557    operands[2] = gen_lowpart (SImode, operands[2]);
18558    operands[3] = gen_lowpart (SImode, operands[3]);"
18559   [(set_attr "type" "icmov")
18560    (set_attr "mode" "SI")])
18561
18562 (define_expand "movsfcc"
18563   [(set (match_operand:SF 0 "register_operand" "")
18564         (if_then_else:SF (match_operand 1 "comparison_operator" "")
18565                          (match_operand:SF 2 "register_operand" "")
18566                          (match_operand:SF 3 "register_operand" "")))]
18567   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18568   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18569
18570 (define_insn "*movsfcc_1_387"
18571   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18572         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18573                                 [(reg FLAGS_REG) (const_int 0)])
18574                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18575                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18576   "TARGET_80387 && TARGET_CMOVE
18577    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18578   "@
18579    fcmov%F1\t{%2, %0|%0, %2}
18580    fcmov%f1\t{%3, %0|%0, %3}
18581    cmov%O2%C1\t{%2, %0|%0, %2}
18582    cmov%O2%c1\t{%3, %0|%0, %3}"
18583   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18584    (set_attr "mode" "SF,SF,SI,SI")])
18585
18586 (define_expand "movdfcc"
18587   [(set (match_operand:DF 0 "register_operand" "")
18588         (if_then_else:DF (match_operand 1 "comparison_operator" "")
18589                          (match_operand:DF 2 "register_operand" "")
18590                          (match_operand:DF 3 "register_operand" "")))]
18591   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18592   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18593
18594 (define_insn "*movdfcc_1"
18595   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
18596         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18597                                 [(reg FLAGS_REG) (const_int 0)])
18598                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18599                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18600   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18601    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18602   "@
18603    fcmov%F1\t{%2, %0|%0, %2}
18604    fcmov%f1\t{%3, %0|%0, %3}
18605    #
18606    #"
18607   [(set_attr "type" "fcmov,fcmov,multi,multi")
18608    (set_attr "mode" "DF")])
18609
18610 (define_insn "*movdfcc_1_rex64"
18611   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
18612         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18613                                 [(reg FLAGS_REG) (const_int 0)])
18614                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18615                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18616   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18617    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18618   "@
18619    fcmov%F1\t{%2, %0|%0, %2}
18620    fcmov%f1\t{%3, %0|%0, %3}
18621    cmov%O2%C1\t{%2, %0|%0, %2}
18622    cmov%O2%c1\t{%3, %0|%0, %3}"
18623   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18624    (set_attr "mode" "DF")])
18625
18626 (define_split
18627   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18628         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18629                                 [(match_operand 4 "flags_reg_operand" "")
18630                                  (const_int 0)])
18631                       (match_operand:DF 2 "nonimmediate_operand" "")
18632                       (match_operand:DF 3 "nonimmediate_operand" "")))]
18633   "!TARGET_64BIT && reload_completed"
18634   [(set (match_dup 2)
18635         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18636                       (match_dup 5)
18637                       (match_dup 7)))
18638    (set (match_dup 3)
18639         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18640                       (match_dup 6)
18641                       (match_dup 8)))]
18642   "split_di (operands+2, 1, operands+5, operands+6);
18643    split_di (operands+3, 1, operands+7, operands+8);
18644    split_di (operands, 1, operands+2, operands+3);")
18645
18646 (define_expand "movxfcc"
18647   [(set (match_operand:XF 0 "register_operand" "")
18648         (if_then_else:XF (match_operand 1 "comparison_operator" "")
18649                          (match_operand:XF 2 "register_operand" "")
18650                          (match_operand:XF 3 "register_operand" "")))]
18651   "TARGET_80387 && TARGET_CMOVE"
18652   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18653
18654 (define_insn "*movxfcc_1"
18655   [(set (match_operand:XF 0 "register_operand" "=f,f")
18656         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18657                                 [(reg FLAGS_REG) (const_int 0)])
18658                       (match_operand:XF 2 "register_operand" "f,0")
18659                       (match_operand:XF 3 "register_operand" "0,f")))]
18660   "TARGET_80387 && TARGET_CMOVE"
18661   "@
18662    fcmov%F1\t{%2, %0|%0, %2}
18663    fcmov%f1\t{%3, %0|%0, %3}"
18664   [(set_attr "type" "fcmov")
18665    (set_attr "mode" "XF")])
18666
18667 ;; These versions of the min/max patterns are intentionally ignorant of
18668 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18669 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18670 ;; are undefined in this condition, we're certain this is correct.
18671
18672 (define_insn "sminsf3"
18673   [(set (match_operand:SF 0 "register_operand" "=x")
18674         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18675                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18676   "TARGET_SSE_MATH"
18677   "minss\t{%2, %0|%0, %2}"
18678   [(set_attr "type" "sseadd")
18679    (set_attr "mode" "SF")])
18680
18681 (define_insn "smaxsf3"
18682   [(set (match_operand:SF 0 "register_operand" "=x")
18683         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18684                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18685   "TARGET_SSE_MATH"
18686   "maxss\t{%2, %0|%0, %2}"
18687   [(set_attr "type" "sseadd")
18688    (set_attr "mode" "SF")])
18689
18690 (define_insn "smindf3"
18691   [(set (match_operand:DF 0 "register_operand" "=x")
18692         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18693                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18694   "TARGET_SSE2 && TARGET_SSE_MATH"
18695   "minsd\t{%2, %0|%0, %2}"
18696   [(set_attr "type" "sseadd")
18697    (set_attr "mode" "DF")])
18698
18699 (define_insn "smaxdf3"
18700   [(set (match_operand:DF 0 "register_operand" "=x")
18701         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18702                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18703   "TARGET_SSE2 && TARGET_SSE_MATH"
18704   "maxsd\t{%2, %0|%0, %2}"
18705   [(set_attr "type" "sseadd")
18706    (set_attr "mode" "DF")])
18707
18708 ;; These versions of the min/max patterns implement exactly the operations
18709 ;;   min = (op1 < op2 ? op1 : op2)
18710 ;;   max = (!(op1 < op2) ? op1 : op2)
18711 ;; Their operands are not commutative, and thus they may be used in the
18712 ;; presence of -0.0 and NaN.
18713
18714 (define_insn "*ieee_sminsf3"
18715   [(set (match_operand:SF 0 "register_operand" "=x")
18716         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18717                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18718                    UNSPEC_IEEE_MIN))]
18719   "TARGET_SSE_MATH"
18720   "minss\t{%2, %0|%0, %2}"
18721   [(set_attr "type" "sseadd")
18722    (set_attr "mode" "SF")])
18723
18724 (define_insn "*ieee_smaxsf3"
18725   [(set (match_operand:SF 0 "register_operand" "=x")
18726         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18727                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18728                    UNSPEC_IEEE_MAX))]
18729   "TARGET_SSE_MATH"
18730   "maxss\t{%2, %0|%0, %2}"
18731   [(set_attr "type" "sseadd")
18732    (set_attr "mode" "SF")])
18733
18734 (define_insn "*ieee_smindf3"
18735   [(set (match_operand:DF 0 "register_operand" "=x")
18736         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18737                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18738                    UNSPEC_IEEE_MIN))]
18739   "TARGET_SSE2 && TARGET_SSE_MATH"
18740   "minsd\t{%2, %0|%0, %2}"
18741   [(set_attr "type" "sseadd")
18742    (set_attr "mode" "DF")])
18743
18744 (define_insn "*ieee_smaxdf3"
18745   [(set (match_operand:DF 0 "register_operand" "=x")
18746         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18747                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
18748                    UNSPEC_IEEE_MAX))]
18749   "TARGET_SSE2 && TARGET_SSE_MATH"
18750   "maxsd\t{%2, %0|%0, %2}"
18751   [(set_attr "type" "sseadd")
18752    (set_attr "mode" "DF")])
18753
18754 ;; Make two stack loads independent:
18755 ;;   fld aa              fld aa
18756 ;;   fld %st(0)     ->   fld bb
18757 ;;   fmul bb             fmul %st(1), %st
18758 ;;
18759 ;; Actually we only match the last two instructions for simplicity.
18760 (define_peephole2
18761   [(set (match_operand 0 "fp_register_operand" "")
18762         (match_operand 1 "fp_register_operand" ""))
18763    (set (match_dup 0)
18764         (match_operator 2 "binary_fp_operator"
18765            [(match_dup 0)
18766             (match_operand 3 "memory_operand" "")]))]
18767   "REGNO (operands[0]) != REGNO (operands[1])"
18768   [(set (match_dup 0) (match_dup 3))
18769    (set (match_dup 0) (match_dup 4))]
18770
18771   ;; The % modifier is not operational anymore in peephole2's, so we have to
18772   ;; swap the operands manually in the case of addition and multiplication.
18773   "if (COMMUTATIVE_ARITH_P (operands[2]))
18774      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18775                                  operands[0], operands[1]);
18776    else
18777      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18778                                  operands[1], operands[0]);")
18779
18780 ;; Conditional addition patterns
18781 (define_expand "addqicc"
18782   [(match_operand:QI 0 "register_operand" "")
18783    (match_operand 1 "comparison_operator" "")
18784    (match_operand:QI 2 "register_operand" "")
18785    (match_operand:QI 3 "const_int_operand" "")]
18786   ""
18787   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18788
18789 (define_expand "addhicc"
18790   [(match_operand:HI 0 "register_operand" "")
18791    (match_operand 1 "comparison_operator" "")
18792    (match_operand:HI 2 "register_operand" "")
18793    (match_operand:HI 3 "const_int_operand" "")]
18794   ""
18795   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18796
18797 (define_expand "addsicc"
18798   [(match_operand:SI 0 "register_operand" "")
18799    (match_operand 1 "comparison_operator" "")
18800    (match_operand:SI 2 "register_operand" "")
18801    (match_operand:SI 3 "const_int_operand" "")]
18802   ""
18803   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18804
18805 (define_expand "adddicc"
18806   [(match_operand:DI 0 "register_operand" "")
18807    (match_operand 1 "comparison_operator" "")
18808    (match_operand:DI 2 "register_operand" "")
18809    (match_operand:DI 3 "const_int_operand" "")]
18810   "TARGET_64BIT"
18811   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18812
18813 \f
18814 ;; Misc patterns (?)
18815
18816 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18817 ;; Otherwise there will be nothing to keep
18818 ;;
18819 ;; [(set (reg ebp) (reg esp))]
18820 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18821 ;;  (clobber (eflags)]
18822 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18823 ;;
18824 ;; in proper program order.
18825 (define_insn "pro_epilogue_adjust_stack_1"
18826   [(set (match_operand:SI 0 "register_operand" "=r,r")
18827         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18828                  (match_operand:SI 2 "immediate_operand" "i,i")))
18829    (clobber (reg:CC FLAGS_REG))
18830    (clobber (mem:BLK (scratch)))]
18831   "!TARGET_64BIT"
18832 {
18833   switch (get_attr_type (insn))
18834     {
18835     case TYPE_IMOV:
18836       return "mov{l}\t{%1, %0|%0, %1}";
18837
18838     case TYPE_ALU:
18839       if (CONST_INT_P (operands[2])
18840           && (INTVAL (operands[2]) == 128
18841               || (INTVAL (operands[2]) < 0
18842                   && INTVAL (operands[2]) != -128)))
18843         {
18844           operands[2] = GEN_INT (-INTVAL (operands[2]));
18845           return "sub{l}\t{%2, %0|%0, %2}";
18846         }
18847       return "add{l}\t{%2, %0|%0, %2}";
18848
18849     case TYPE_LEA:
18850       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18851       return "lea{l}\t{%a2, %0|%0, %a2}";
18852
18853     default:
18854       gcc_unreachable ();
18855     }
18856 }
18857   [(set (attr "type")
18858         (cond [(eq_attr "alternative" "0")
18859                  (const_string "alu")
18860                (match_operand:SI 2 "const0_operand" "")
18861                  (const_string "imov")
18862               ]
18863               (const_string "lea")))
18864    (set_attr "mode" "SI")])
18865
18866 (define_insn "pro_epilogue_adjust_stack_rex64"
18867   [(set (match_operand:DI 0 "register_operand" "=r,r")
18868         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18869                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18870    (clobber (reg:CC FLAGS_REG))
18871    (clobber (mem:BLK (scratch)))]
18872   "TARGET_64BIT"
18873 {
18874   switch (get_attr_type (insn))
18875     {
18876     case TYPE_IMOV:
18877       return "mov{q}\t{%1, %0|%0, %1}";
18878
18879     case TYPE_ALU:
18880       if (CONST_INT_P (operands[2])
18881           /* Avoid overflows.  */
18882           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18883           && (INTVAL (operands[2]) == 128
18884               || (INTVAL (operands[2]) < 0
18885                   && INTVAL (operands[2]) != -128)))
18886         {
18887           operands[2] = GEN_INT (-INTVAL (operands[2]));
18888           return "sub{q}\t{%2, %0|%0, %2}";
18889         }
18890       return "add{q}\t{%2, %0|%0, %2}";
18891
18892     case TYPE_LEA:
18893       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18894       return "lea{q}\t{%a2, %0|%0, %a2}";
18895
18896     default:
18897       gcc_unreachable ();
18898     }
18899 }
18900   [(set (attr "type")
18901         (cond [(eq_attr "alternative" "0")
18902                  (const_string "alu")
18903                (match_operand:DI 2 "const0_operand" "")
18904                  (const_string "imov")
18905               ]
18906               (const_string "lea")))
18907    (set_attr "mode" "DI")])
18908
18909 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18910   [(set (match_operand:DI 0 "register_operand" "=r,r")
18911         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18912                  (match_operand:DI 3 "immediate_operand" "i,i")))
18913    (use (match_operand:DI 2 "register_operand" "r,r"))
18914    (clobber (reg:CC FLAGS_REG))
18915    (clobber (mem:BLK (scratch)))]
18916   "TARGET_64BIT"
18917 {
18918   switch (get_attr_type (insn))
18919     {
18920     case TYPE_ALU:
18921       return "add{q}\t{%2, %0|%0, %2}";
18922
18923     case TYPE_LEA:
18924       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18925       return "lea{q}\t{%a2, %0|%0, %a2}";
18926
18927     default:
18928       gcc_unreachable ();
18929     }
18930 }
18931   [(set_attr "type" "alu,lea")
18932    (set_attr "mode" "DI")])
18933
18934 (define_expand "allocate_stack_worker"
18935   [(match_operand:SI 0 "register_operand" "")]
18936   "TARGET_STACK_PROBE"
18937 {
18938   if (reload_completed)
18939     {
18940       if (TARGET_64BIT)
18941         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18942       else
18943         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18944     }
18945   else
18946     {
18947       if (TARGET_64BIT)
18948         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18949       else
18950         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18951     }
18952   DONE;
18953 })
18954
18955 (define_insn "allocate_stack_worker_1"
18956   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18957     UNSPECV_STACK_PROBE)
18958    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18959    (clobber (match_scratch:SI 1 "=0"))
18960    (clobber (reg:CC FLAGS_REG))]
18961   "!TARGET_64BIT && TARGET_STACK_PROBE"
18962   "call\t__alloca"
18963   [(set_attr "type" "multi")
18964    (set_attr "length" "5")])
18965
18966 (define_expand "allocate_stack_worker_postreload"
18967   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18968                                     UNSPECV_STACK_PROBE)
18969               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18970               (clobber (match_dup 0))
18971               (clobber (reg:CC FLAGS_REG))])]
18972   ""
18973   "")
18974
18975 (define_insn "allocate_stack_worker_rex64"
18976   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18977     UNSPECV_STACK_PROBE)
18978    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18979    (clobber (match_scratch:DI 1 "=0"))
18980    (clobber (reg:CC FLAGS_REG))]
18981   "TARGET_64BIT && TARGET_STACK_PROBE"
18982   "call\t__alloca"
18983   [(set_attr "type" "multi")
18984    (set_attr "length" "5")])
18985
18986 (define_expand "allocate_stack_worker_rex64_postreload"
18987   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18988                                     UNSPECV_STACK_PROBE)
18989               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18990               (clobber (match_dup 0))
18991               (clobber (reg:CC FLAGS_REG))])]
18992   ""
18993   "")
18994
18995 (define_expand "allocate_stack"
18996   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18997                    (minus:SI (reg:SI SP_REG)
18998                              (match_operand:SI 1 "general_operand" "")))
18999               (clobber (reg:CC FLAGS_REG))])
19000    (parallel [(set (reg:SI SP_REG)
19001                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
19002               (clobber (reg:CC FLAGS_REG))])]
19003   "TARGET_STACK_PROBE"
19004 {
19005 #ifdef CHECK_STACK_LIMIT
19006   if (CONST_INT_P (operands[1])
19007       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19008     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19009                            operands[1]));
19010   else
19011 #endif
19012     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19013                                                             operands[1])));
19014
19015   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19016   DONE;
19017 })
19018
19019 (define_expand "builtin_setjmp_receiver"
19020   [(label_ref (match_operand 0 "" ""))]
19021   "!TARGET_64BIT && flag_pic"
19022 {
19023   if (TARGET_MACHO)
19024     {
19025       rtx xops[3];
19026       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19027       rtx label_rtx = gen_label_rtx ();
19028       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19029       xops[0] = xops[1] = picreg;
19030       xops[2] = gen_rtx_CONST (SImode,
19031                   gen_rtx_MINUS (SImode,
19032                     gen_rtx_LABEL_REF (SImode, label_rtx),
19033                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19034       ix86_expand_binary_operator (MINUS, SImode, xops);
19035     }
19036   else
19037     emit_insn (gen_set_got (pic_offset_table_rtx));
19038   DONE;
19039 })
19040 \f
19041 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19042
19043 (define_split
19044   [(set (match_operand 0 "register_operand" "")
19045         (match_operator 3 "promotable_binary_operator"
19046            [(match_operand 1 "register_operand" "")
19047             (match_operand 2 "aligned_operand" "")]))
19048    (clobber (reg:CC FLAGS_REG))]
19049   "! TARGET_PARTIAL_REG_STALL && reload_completed
19050    && ((GET_MODE (operands[0]) == HImode
19051         && ((!optimize_size && !TARGET_FAST_PREFIX)
19052             /* ??? next two lines just !satisfies_constraint_K (...) */
19053             || !CONST_INT_P (operands[2])
19054             || satisfies_constraint_K (operands[2])))
19055        || (GET_MODE (operands[0]) == QImode
19056            && (TARGET_PROMOTE_QImode || optimize_size)))"
19057   [(parallel [(set (match_dup 0)
19058                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19059               (clobber (reg:CC FLAGS_REG))])]
19060   "operands[0] = gen_lowpart (SImode, operands[0]);
19061    operands[1] = gen_lowpart (SImode, operands[1]);
19062    if (GET_CODE (operands[3]) != ASHIFT)
19063      operands[2] = gen_lowpart (SImode, operands[2]);
19064    PUT_MODE (operands[3], SImode);")
19065
19066 ; Promote the QImode tests, as i386 has encoding of the AND
19067 ; instruction with 32-bit sign-extended immediate and thus the
19068 ; instruction size is unchanged, except in the %eax case for
19069 ; which it is increased by one byte, hence the ! optimize_size.
19070 (define_split
19071   [(set (match_operand 0 "flags_reg_operand" "")
19072         (match_operator 2 "compare_operator"
19073           [(and (match_operand 3 "aligned_operand" "")
19074                 (match_operand 4 "const_int_operand" ""))
19075            (const_int 0)]))
19076    (set (match_operand 1 "register_operand" "")
19077         (and (match_dup 3) (match_dup 4)))]
19078   "! TARGET_PARTIAL_REG_STALL && reload_completed
19079    /* Ensure that the operand will remain sign-extended immediate.  */
19080    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19081    && ! optimize_size
19082    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19083        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19084   [(parallel [(set (match_dup 0)
19085                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19086                                     (const_int 0)]))
19087               (set (match_dup 1)
19088                    (and:SI (match_dup 3) (match_dup 4)))])]
19089 {
19090   operands[4]
19091     = gen_int_mode (INTVAL (operands[4])
19092                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19093   operands[1] = gen_lowpart (SImode, operands[1]);
19094   operands[3] = gen_lowpart (SImode, operands[3]);
19095 })
19096
19097 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19098 ; the TEST instruction with 32-bit sign-extended immediate and thus
19099 ; the instruction size would at least double, which is not what we
19100 ; want even with ! optimize_size.
19101 (define_split
19102   [(set (match_operand 0 "flags_reg_operand" "")
19103         (match_operator 1 "compare_operator"
19104           [(and (match_operand:HI 2 "aligned_operand" "")
19105                 (match_operand:HI 3 "const_int_operand" ""))
19106            (const_int 0)]))]
19107   "! TARGET_PARTIAL_REG_STALL && reload_completed
19108    /* Ensure that the operand will remain sign-extended immediate.  */
19109    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19110    && ! TARGET_FAST_PREFIX
19111    && ! optimize_size"
19112   [(set (match_dup 0)
19113         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19114                          (const_int 0)]))]
19115 {
19116   operands[3]
19117     = gen_int_mode (INTVAL (operands[3])
19118                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19119   operands[2] = gen_lowpart (SImode, operands[2]);
19120 })
19121
19122 (define_split
19123   [(set (match_operand 0 "register_operand" "")
19124         (neg (match_operand 1 "register_operand" "")))
19125    (clobber (reg:CC FLAGS_REG))]
19126   "! TARGET_PARTIAL_REG_STALL && reload_completed
19127    && (GET_MODE (operands[0]) == HImode
19128        || (GET_MODE (operands[0]) == QImode
19129            && (TARGET_PROMOTE_QImode || optimize_size)))"
19130   [(parallel [(set (match_dup 0)
19131                    (neg:SI (match_dup 1)))
19132               (clobber (reg:CC FLAGS_REG))])]
19133   "operands[0] = gen_lowpart (SImode, operands[0]);
19134    operands[1] = gen_lowpart (SImode, operands[1]);")
19135
19136 (define_split
19137   [(set (match_operand 0 "register_operand" "")
19138         (not (match_operand 1 "register_operand" "")))]
19139   "! TARGET_PARTIAL_REG_STALL && reload_completed
19140    && (GET_MODE (operands[0]) == HImode
19141        || (GET_MODE (operands[0]) == QImode
19142            && (TARGET_PROMOTE_QImode || optimize_size)))"
19143   [(set (match_dup 0)
19144         (not:SI (match_dup 1)))]
19145   "operands[0] = gen_lowpart (SImode, operands[0]);
19146    operands[1] = gen_lowpart (SImode, operands[1]);")
19147
19148 (define_split
19149   [(set (match_operand 0 "register_operand" "")
19150         (if_then_else (match_operator 1 "comparison_operator"
19151                                 [(reg FLAGS_REG) (const_int 0)])
19152                       (match_operand 2 "register_operand" "")
19153                       (match_operand 3 "register_operand" "")))]
19154   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19155    && (GET_MODE (operands[0]) == HImode
19156        || (GET_MODE (operands[0]) == QImode
19157            && (TARGET_PROMOTE_QImode || optimize_size)))"
19158   [(set (match_dup 0)
19159         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19160   "operands[0] = gen_lowpart (SImode, operands[0]);
19161    operands[2] = gen_lowpart (SImode, operands[2]);
19162    operands[3] = gen_lowpart (SImode, operands[3]);")
19163
19164 \f
19165 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19166 ;; transform a complex memory operation into two memory to register operations.
19167
19168 ;; Don't push memory operands
19169 (define_peephole2
19170   [(set (match_operand:SI 0 "push_operand" "")
19171         (match_operand:SI 1 "memory_operand" ""))
19172    (match_scratch:SI 2 "r")]
19173   "!optimize_size && !TARGET_PUSH_MEMORY
19174    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19175   [(set (match_dup 2) (match_dup 1))
19176    (set (match_dup 0) (match_dup 2))]
19177   "")
19178
19179 (define_peephole2
19180   [(set (match_operand:DI 0 "push_operand" "")
19181         (match_operand:DI 1 "memory_operand" ""))
19182    (match_scratch:DI 2 "r")]
19183   "!optimize_size && !TARGET_PUSH_MEMORY
19184    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19185   [(set (match_dup 2) (match_dup 1))
19186    (set (match_dup 0) (match_dup 2))]
19187   "")
19188
19189 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19190 ;; SImode pushes.
19191 (define_peephole2
19192   [(set (match_operand:SF 0 "push_operand" "")
19193         (match_operand:SF 1 "memory_operand" ""))
19194    (match_scratch:SF 2 "r")]
19195   "!optimize_size && !TARGET_PUSH_MEMORY
19196    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19197   [(set (match_dup 2) (match_dup 1))
19198    (set (match_dup 0) (match_dup 2))]
19199   "")
19200
19201 (define_peephole2
19202   [(set (match_operand:HI 0 "push_operand" "")
19203         (match_operand:HI 1 "memory_operand" ""))
19204    (match_scratch:HI 2 "r")]
19205   "!optimize_size && !TARGET_PUSH_MEMORY
19206    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19207   [(set (match_dup 2) (match_dup 1))
19208    (set (match_dup 0) (match_dup 2))]
19209   "")
19210
19211 (define_peephole2
19212   [(set (match_operand:QI 0 "push_operand" "")
19213         (match_operand:QI 1 "memory_operand" ""))
19214    (match_scratch:QI 2 "q")]
19215   "!optimize_size && !TARGET_PUSH_MEMORY
19216    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19217   [(set (match_dup 2) (match_dup 1))
19218    (set (match_dup 0) (match_dup 2))]
19219   "")
19220
19221 ;; Don't move an immediate directly to memory when the instruction
19222 ;; gets too big.
19223 (define_peephole2
19224   [(match_scratch:SI 1 "r")
19225    (set (match_operand:SI 0 "memory_operand" "")
19226         (const_int 0))]
19227   "! optimize_size
19228    && ! TARGET_USE_MOV0
19229    && TARGET_SPLIT_LONG_MOVES
19230    && get_attr_length (insn) >= ix86_cost->large_insn
19231    && peep2_regno_dead_p (0, FLAGS_REG)"
19232   [(parallel [(set (match_dup 1) (const_int 0))
19233               (clobber (reg:CC FLAGS_REG))])
19234    (set (match_dup 0) (match_dup 1))]
19235   "")
19236
19237 (define_peephole2
19238   [(match_scratch:HI 1 "r")
19239    (set (match_operand:HI 0 "memory_operand" "")
19240         (const_int 0))]
19241   "! optimize_size
19242    && ! TARGET_USE_MOV0
19243    && TARGET_SPLIT_LONG_MOVES
19244    && get_attr_length (insn) >= ix86_cost->large_insn
19245    && peep2_regno_dead_p (0, FLAGS_REG)"
19246   [(parallel [(set (match_dup 2) (const_int 0))
19247               (clobber (reg:CC FLAGS_REG))])
19248    (set (match_dup 0) (match_dup 1))]
19249   "operands[2] = gen_lowpart (SImode, operands[1]);")
19250
19251 (define_peephole2
19252   [(match_scratch:QI 1 "q")
19253    (set (match_operand:QI 0 "memory_operand" "")
19254         (const_int 0))]
19255   "! optimize_size
19256    && ! TARGET_USE_MOV0
19257    && TARGET_SPLIT_LONG_MOVES
19258    && get_attr_length (insn) >= ix86_cost->large_insn
19259    && peep2_regno_dead_p (0, FLAGS_REG)"
19260   [(parallel [(set (match_dup 2) (const_int 0))
19261               (clobber (reg:CC FLAGS_REG))])
19262    (set (match_dup 0) (match_dup 1))]
19263   "operands[2] = gen_lowpart (SImode, operands[1]);")
19264
19265 (define_peephole2
19266   [(match_scratch:SI 2 "r")
19267    (set (match_operand:SI 0 "memory_operand" "")
19268         (match_operand:SI 1 "immediate_operand" ""))]
19269   "! optimize_size
19270    && get_attr_length (insn) >= ix86_cost->large_insn
19271    && TARGET_SPLIT_LONG_MOVES"
19272   [(set (match_dup 2) (match_dup 1))
19273    (set (match_dup 0) (match_dup 2))]
19274   "")
19275
19276 (define_peephole2
19277   [(match_scratch:HI 2 "r")
19278    (set (match_operand:HI 0 "memory_operand" "")
19279         (match_operand:HI 1 "immediate_operand" ""))]
19280   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19281   && TARGET_SPLIT_LONG_MOVES"
19282   [(set (match_dup 2) (match_dup 1))
19283    (set (match_dup 0) (match_dup 2))]
19284   "")
19285
19286 (define_peephole2
19287   [(match_scratch:QI 2 "q")
19288    (set (match_operand:QI 0 "memory_operand" "")
19289         (match_operand:QI 1 "immediate_operand" ""))]
19290   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19291   && TARGET_SPLIT_LONG_MOVES"
19292   [(set (match_dup 2) (match_dup 1))
19293    (set (match_dup 0) (match_dup 2))]
19294   "")
19295
19296 ;; Don't compare memory with zero, load and use a test instead.
19297 (define_peephole2
19298   [(set (match_operand 0 "flags_reg_operand" "")
19299         (match_operator 1 "compare_operator"
19300           [(match_operand:SI 2 "memory_operand" "")
19301            (const_int 0)]))
19302    (match_scratch:SI 3 "r")]
19303   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19304   [(set (match_dup 3) (match_dup 2))
19305    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19306   "")
19307
19308 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19309 ;; Don't split NOTs with a displacement operand, because resulting XOR
19310 ;; will not be pairable anyway.
19311 ;;
19312 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19313 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19314 ;; so this split helps here as well.
19315 ;;
19316 ;; Note: Can't do this as a regular split because we can't get proper
19317 ;; lifetime information then.
19318
19319 (define_peephole2
19320   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19321         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19322   "!optimize_size
19323    && peep2_regno_dead_p (0, FLAGS_REG)
19324    && ((TARGET_PENTIUM
19325         && (!MEM_P (operands[0])
19326             || !memory_displacement_operand (operands[0], SImode)))
19327        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19328   [(parallel [(set (match_dup 0)
19329                    (xor:SI (match_dup 1) (const_int -1)))
19330               (clobber (reg:CC FLAGS_REG))])]
19331   "")
19332
19333 (define_peephole2
19334   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19335         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19336   "!optimize_size
19337    && peep2_regno_dead_p (0, FLAGS_REG)
19338    && ((TARGET_PENTIUM
19339         && (!MEM_P (operands[0])
19340             || !memory_displacement_operand (operands[0], HImode)))
19341        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19342   [(parallel [(set (match_dup 0)
19343                    (xor:HI (match_dup 1) (const_int -1)))
19344               (clobber (reg:CC FLAGS_REG))])]
19345   "")
19346
19347 (define_peephole2
19348   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19349         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19350   "!optimize_size
19351    && peep2_regno_dead_p (0, FLAGS_REG)
19352    && ((TARGET_PENTIUM
19353         && (!MEM_P (operands[0])
19354             || !memory_displacement_operand (operands[0], QImode)))
19355        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19356   [(parallel [(set (match_dup 0)
19357                    (xor:QI (match_dup 1) (const_int -1)))
19358               (clobber (reg:CC FLAGS_REG))])]
19359   "")
19360
19361 ;; Non pairable "test imm, reg" instructions can be translated to
19362 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19363 ;; byte opcode instead of two, have a short form for byte operands),
19364 ;; so do it for other CPUs as well.  Given that the value was dead,
19365 ;; this should not create any new dependencies.  Pass on the sub-word
19366 ;; versions if we're concerned about partial register stalls.
19367
19368 (define_peephole2
19369   [(set (match_operand 0 "flags_reg_operand" "")
19370         (match_operator 1 "compare_operator"
19371           [(and:SI (match_operand:SI 2 "register_operand" "")
19372                    (match_operand:SI 3 "immediate_operand" ""))
19373            (const_int 0)]))]
19374   "ix86_match_ccmode (insn, CCNOmode)
19375    && (true_regnum (operands[2]) != 0
19376        || satisfies_constraint_K (operands[3]))
19377    && peep2_reg_dead_p (1, operands[2])"
19378   [(parallel
19379      [(set (match_dup 0)
19380            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19381                             (const_int 0)]))
19382       (set (match_dup 2)
19383            (and:SI (match_dup 2) (match_dup 3)))])]
19384   "")
19385
19386 ;; We don't need to handle HImode case, because it will be promoted to SImode
19387 ;; on ! TARGET_PARTIAL_REG_STALL
19388
19389 (define_peephole2
19390   [(set (match_operand 0 "flags_reg_operand" "")
19391         (match_operator 1 "compare_operator"
19392           [(and:QI (match_operand:QI 2 "register_operand" "")
19393                    (match_operand:QI 3 "immediate_operand" ""))
19394            (const_int 0)]))]
19395   "! TARGET_PARTIAL_REG_STALL
19396    && ix86_match_ccmode (insn, CCNOmode)
19397    && true_regnum (operands[2]) != 0
19398    && peep2_reg_dead_p (1, operands[2])"
19399   [(parallel
19400      [(set (match_dup 0)
19401            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19402                             (const_int 0)]))
19403       (set (match_dup 2)
19404            (and:QI (match_dup 2) (match_dup 3)))])]
19405   "")
19406
19407 (define_peephole2
19408   [(set (match_operand 0 "flags_reg_operand" "")
19409         (match_operator 1 "compare_operator"
19410           [(and:SI
19411              (zero_extract:SI
19412                (match_operand 2 "ext_register_operand" "")
19413                (const_int 8)
19414                (const_int 8))
19415              (match_operand 3 "const_int_operand" ""))
19416            (const_int 0)]))]
19417   "! TARGET_PARTIAL_REG_STALL
19418    && ix86_match_ccmode (insn, CCNOmode)
19419    && true_regnum (operands[2]) != 0
19420    && peep2_reg_dead_p (1, operands[2])"
19421   [(parallel [(set (match_dup 0)
19422                    (match_op_dup 1
19423                      [(and:SI
19424                         (zero_extract:SI
19425                           (match_dup 2)
19426                           (const_int 8)
19427                           (const_int 8))
19428                         (match_dup 3))
19429                       (const_int 0)]))
19430               (set (zero_extract:SI (match_dup 2)
19431                                     (const_int 8)
19432                                     (const_int 8))
19433                    (and:SI
19434                      (zero_extract:SI
19435                        (match_dup 2)
19436                        (const_int 8)
19437                        (const_int 8))
19438                      (match_dup 3)))])]
19439   "")
19440
19441 ;; Don't do logical operations with memory inputs.
19442 (define_peephole2
19443   [(match_scratch:SI 2 "r")
19444    (parallel [(set (match_operand:SI 0 "register_operand" "")
19445                    (match_operator:SI 3 "arith_or_logical_operator"
19446                      [(match_dup 0)
19447                       (match_operand:SI 1 "memory_operand" "")]))
19448               (clobber (reg:CC FLAGS_REG))])]
19449   "! optimize_size && ! TARGET_READ_MODIFY"
19450   [(set (match_dup 2) (match_dup 1))
19451    (parallel [(set (match_dup 0)
19452                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19453               (clobber (reg:CC FLAGS_REG))])]
19454   "")
19455
19456 (define_peephole2
19457   [(match_scratch:SI 2 "r")
19458    (parallel [(set (match_operand:SI 0 "register_operand" "")
19459                    (match_operator:SI 3 "arith_or_logical_operator"
19460                      [(match_operand:SI 1 "memory_operand" "")
19461                       (match_dup 0)]))
19462               (clobber (reg:CC FLAGS_REG))])]
19463   "! optimize_size && ! TARGET_READ_MODIFY"
19464   [(set (match_dup 2) (match_dup 1))
19465    (parallel [(set (match_dup 0)
19466                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19467               (clobber (reg:CC FLAGS_REG))])]
19468   "")
19469
19470 ; Don't do logical operations with memory outputs
19471 ;
19472 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19473 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19474 ; the same decoder scheduling characteristics as the original.
19475
19476 (define_peephole2
19477   [(match_scratch:SI 2 "r")
19478    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19479                    (match_operator:SI 3 "arith_or_logical_operator"
19480                      [(match_dup 0)
19481                       (match_operand:SI 1 "nonmemory_operand" "")]))
19482               (clobber (reg:CC FLAGS_REG))])]
19483   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19484   [(set (match_dup 2) (match_dup 0))
19485    (parallel [(set (match_dup 2)
19486                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19487               (clobber (reg:CC FLAGS_REG))])
19488    (set (match_dup 0) (match_dup 2))]
19489   "")
19490
19491 (define_peephole2
19492   [(match_scratch:SI 2 "r")
19493    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19494                    (match_operator:SI 3 "arith_or_logical_operator"
19495                      [(match_operand:SI 1 "nonmemory_operand" "")
19496                       (match_dup 0)]))
19497               (clobber (reg:CC FLAGS_REG))])]
19498   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19499   [(set (match_dup 2) (match_dup 0))
19500    (parallel [(set (match_dup 2)
19501                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19502               (clobber (reg:CC FLAGS_REG))])
19503    (set (match_dup 0) (match_dup 2))]
19504   "")
19505
19506 ;; Attempt to always use XOR for zeroing registers.
19507 (define_peephole2
19508   [(set (match_operand 0 "register_operand" "")
19509         (match_operand 1 "const0_operand" ""))]
19510   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19511    && (! TARGET_USE_MOV0 || optimize_size)
19512    && GENERAL_REG_P (operands[0])
19513    && peep2_regno_dead_p (0, FLAGS_REG)"
19514   [(parallel [(set (match_dup 0) (const_int 0))
19515               (clobber (reg:CC FLAGS_REG))])]
19516 {
19517   operands[0] = gen_lowpart (word_mode, operands[0]);
19518 })
19519
19520 (define_peephole2
19521   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19522         (const_int 0))]
19523   "(GET_MODE (operands[0]) == QImode
19524     || GET_MODE (operands[0]) == HImode)
19525    && (! TARGET_USE_MOV0 || optimize_size)
19526    && peep2_regno_dead_p (0, FLAGS_REG)"
19527   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19528               (clobber (reg:CC FLAGS_REG))])])
19529
19530 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19531 (define_peephole2
19532   [(set (match_operand 0 "register_operand" "")
19533         (const_int -1))]
19534   "(GET_MODE (operands[0]) == HImode
19535     || GET_MODE (operands[0]) == SImode
19536     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19537    && (optimize_size || TARGET_PENTIUM)
19538    && peep2_regno_dead_p (0, FLAGS_REG)"
19539   [(parallel [(set (match_dup 0) (const_int -1))
19540               (clobber (reg:CC FLAGS_REG))])]
19541   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19542                               operands[0]);")
19543
19544 ;; Attempt to convert simple leas to adds. These can be created by
19545 ;; move expanders.
19546 (define_peephole2
19547   [(set (match_operand:SI 0 "register_operand" "")
19548         (plus:SI (match_dup 0)
19549                  (match_operand:SI 1 "nonmemory_operand" "")))]
19550   "peep2_regno_dead_p (0, FLAGS_REG)"
19551   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19552               (clobber (reg:CC FLAGS_REG))])]
19553   "")
19554
19555 (define_peephole2
19556   [(set (match_operand:SI 0 "register_operand" "")
19557         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19558                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19559   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19560   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19561               (clobber (reg:CC FLAGS_REG))])]
19562   "operands[2] = gen_lowpart (SImode, operands[2]);")
19563
19564 (define_peephole2
19565   [(set (match_operand:DI 0 "register_operand" "")
19566         (plus:DI (match_dup 0)
19567                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19568   "peep2_regno_dead_p (0, FLAGS_REG)"
19569   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19570               (clobber (reg:CC FLAGS_REG))])]
19571   "")
19572
19573 (define_peephole2
19574   [(set (match_operand:SI 0 "register_operand" "")
19575         (mult:SI (match_dup 0)
19576                  (match_operand:SI 1 "const_int_operand" "")))]
19577   "exact_log2 (INTVAL (operands[1])) >= 0
19578    && peep2_regno_dead_p (0, FLAGS_REG)"
19579   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19580               (clobber (reg:CC FLAGS_REG))])]
19581   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19582
19583 (define_peephole2
19584   [(set (match_operand:DI 0 "register_operand" "")
19585         (mult:DI (match_dup 0)
19586                  (match_operand:DI 1 "const_int_operand" "")))]
19587   "exact_log2 (INTVAL (operands[1])) >= 0
19588    && peep2_regno_dead_p (0, FLAGS_REG)"
19589   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19590               (clobber (reg:CC FLAGS_REG))])]
19591   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19592
19593 (define_peephole2
19594   [(set (match_operand:SI 0 "register_operand" "")
19595         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19596                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19597   "exact_log2 (INTVAL (operands[2])) >= 0
19598    && REGNO (operands[0]) == REGNO (operands[1])
19599    && peep2_regno_dead_p (0, FLAGS_REG)"
19600   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19601               (clobber (reg:CC FLAGS_REG))])]
19602   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19603
19604 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19605 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19606 ;; many CPUs it is also faster, since special hardware to avoid esp
19607 ;; dependencies is present.
19608
19609 ;; While some of these conversions may be done using splitters, we use peepholes
19610 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19611
19612 ;; Convert prologue esp subtractions to push.
19613 ;; We need register to push.  In order to keep verify_flow_info happy we have
19614 ;; two choices
19615 ;; - use scratch and clobber it in order to avoid dependencies
19616 ;; - use already live register
19617 ;; We can't use the second way right now, since there is no reliable way how to
19618 ;; verify that given register is live.  First choice will also most likely in
19619 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19620 ;; call clobbered registers are dead.  We may want to use base pointer as an
19621 ;; alternative when no register is available later.
19622
19623 (define_peephole2
19624   [(match_scratch:SI 0 "r")
19625    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19626               (clobber (reg:CC FLAGS_REG))
19627               (clobber (mem:BLK (scratch)))])]
19628   "optimize_size || !TARGET_SUB_ESP_4"
19629   [(clobber (match_dup 0))
19630    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19631               (clobber (mem:BLK (scratch)))])])
19632
19633 (define_peephole2
19634   [(match_scratch:SI 0 "r")
19635    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19636               (clobber (reg:CC FLAGS_REG))
19637               (clobber (mem:BLK (scratch)))])]
19638   "optimize_size || !TARGET_SUB_ESP_8"
19639   [(clobber (match_dup 0))
19640    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19641    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19642               (clobber (mem:BLK (scratch)))])])
19643
19644 ;; Convert esp subtractions to push.
19645 (define_peephole2
19646   [(match_scratch:SI 0 "r")
19647    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19648               (clobber (reg:CC FLAGS_REG))])]
19649   "optimize_size || !TARGET_SUB_ESP_4"
19650   [(clobber (match_dup 0))
19651    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19652
19653 (define_peephole2
19654   [(match_scratch:SI 0 "r")
19655    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19656               (clobber (reg:CC FLAGS_REG))])]
19657   "optimize_size || !TARGET_SUB_ESP_8"
19658   [(clobber (match_dup 0))
19659    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19660    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19661
19662 ;; Convert epilogue deallocator to pop.
19663 (define_peephole2
19664   [(match_scratch:SI 0 "r")
19665    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19666               (clobber (reg:CC FLAGS_REG))
19667               (clobber (mem:BLK (scratch)))])]
19668   "optimize_size || !TARGET_ADD_ESP_4"
19669   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19670               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19671               (clobber (mem:BLK (scratch)))])]
19672   "")
19673
19674 ;; Two pops case is tricky, since pop causes dependency on destination register.
19675 ;; We use two registers if available.
19676 (define_peephole2
19677   [(match_scratch:SI 0 "r")
19678    (match_scratch:SI 1 "r")
19679    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19680               (clobber (reg:CC FLAGS_REG))
19681               (clobber (mem:BLK (scratch)))])]
19682   "optimize_size || !TARGET_ADD_ESP_8"
19683   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19684               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19685               (clobber (mem:BLK (scratch)))])
19686    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19687               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19688   "")
19689
19690 (define_peephole2
19691   [(match_scratch:SI 0 "r")
19692    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19693               (clobber (reg:CC FLAGS_REG))
19694               (clobber (mem:BLK (scratch)))])]
19695   "optimize_size"
19696   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19697               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19698               (clobber (mem:BLK (scratch)))])
19699    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19700               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19701   "")
19702
19703 ;; Convert esp additions to pop.
19704 (define_peephole2
19705   [(match_scratch:SI 0 "r")
19706    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19707               (clobber (reg:CC FLAGS_REG))])]
19708   ""
19709   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19710               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19711   "")
19712
19713 ;; Two pops case is tricky, since pop causes dependency on destination register.
19714 ;; We use two registers if available.
19715 (define_peephole2
19716   [(match_scratch:SI 0 "r")
19717    (match_scratch:SI 1 "r")
19718    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19719               (clobber (reg:CC FLAGS_REG))])]
19720   ""
19721   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19722               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19723    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19724               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19725   "")
19726
19727 (define_peephole2
19728   [(match_scratch:SI 0 "r")
19729    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19730               (clobber (reg:CC FLAGS_REG))])]
19731   "optimize_size"
19732   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19733               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19734    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19735               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19736   "")
19737 \f
19738 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19739 ;; required and register dies.  Similarly for 128 to plus -128.
19740 (define_peephole2
19741   [(set (match_operand 0 "flags_reg_operand" "")
19742         (match_operator 1 "compare_operator"
19743           [(match_operand 2 "register_operand" "")
19744            (match_operand 3 "const_int_operand" "")]))]
19745   "(INTVAL (operands[3]) == -1
19746     || INTVAL (operands[3]) == 1
19747     || INTVAL (operands[3]) == 128)
19748    && ix86_match_ccmode (insn, CCGCmode)
19749    && peep2_reg_dead_p (1, operands[2])"
19750   [(parallel [(set (match_dup 0)
19751                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19752               (clobber (match_dup 2))])]
19753   "")
19754 \f
19755 (define_peephole2
19756   [(match_scratch:DI 0 "r")
19757    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19758               (clobber (reg:CC FLAGS_REG))
19759               (clobber (mem:BLK (scratch)))])]
19760   "optimize_size || !TARGET_SUB_ESP_4"
19761   [(clobber (match_dup 0))
19762    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19763               (clobber (mem:BLK (scratch)))])])
19764
19765 (define_peephole2
19766   [(match_scratch:DI 0 "r")
19767    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19768               (clobber (reg:CC FLAGS_REG))
19769               (clobber (mem:BLK (scratch)))])]
19770   "optimize_size || !TARGET_SUB_ESP_8"
19771   [(clobber (match_dup 0))
19772    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19773    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19774               (clobber (mem:BLK (scratch)))])])
19775
19776 ;; Convert esp subtractions to push.
19777 (define_peephole2
19778   [(match_scratch:DI 0 "r")
19779    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19780               (clobber (reg:CC FLAGS_REG))])]
19781   "optimize_size || !TARGET_SUB_ESP_4"
19782   [(clobber (match_dup 0))
19783    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19784
19785 (define_peephole2
19786   [(match_scratch:DI 0 "r")
19787    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19788               (clobber (reg:CC FLAGS_REG))])]
19789   "optimize_size || !TARGET_SUB_ESP_8"
19790   [(clobber (match_dup 0))
19791    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19792    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19793
19794 ;; Convert epilogue deallocator to pop.
19795 (define_peephole2
19796   [(match_scratch:DI 0 "r")
19797    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19798               (clobber (reg:CC FLAGS_REG))
19799               (clobber (mem:BLK (scratch)))])]
19800   "optimize_size || !TARGET_ADD_ESP_4"
19801   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19802               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19803               (clobber (mem:BLK (scratch)))])]
19804   "")
19805
19806 ;; Two pops case is tricky, since pop causes dependency on destination register.
19807 ;; We use two registers if available.
19808 (define_peephole2
19809   [(match_scratch:DI 0 "r")
19810    (match_scratch:DI 1 "r")
19811    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19812               (clobber (reg:CC FLAGS_REG))
19813               (clobber (mem:BLK (scratch)))])]
19814   "optimize_size || !TARGET_ADD_ESP_8"
19815   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19816               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19817               (clobber (mem:BLK (scratch)))])
19818    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19819               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19820   "")
19821
19822 (define_peephole2
19823   [(match_scratch:DI 0 "r")
19824    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19825               (clobber (reg:CC FLAGS_REG))
19826               (clobber (mem:BLK (scratch)))])]
19827   "optimize_size"
19828   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19829               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19830               (clobber (mem:BLK (scratch)))])
19831    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19832               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19833   "")
19834
19835 ;; Convert esp additions to pop.
19836 (define_peephole2
19837   [(match_scratch:DI 0 "r")
19838    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19839               (clobber (reg:CC FLAGS_REG))])]
19840   ""
19841   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19842               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19843   "")
19844
19845 ;; Two pops case is tricky, since pop causes dependency on destination register.
19846 ;; We use two registers if available.
19847 (define_peephole2
19848   [(match_scratch:DI 0 "r")
19849    (match_scratch:DI 1 "r")
19850    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19851               (clobber (reg:CC FLAGS_REG))])]
19852   ""
19853   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19854               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19855    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19856               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19857   "")
19858
19859 (define_peephole2
19860   [(match_scratch:DI 0 "r")
19861    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19862               (clobber (reg:CC FLAGS_REG))])]
19863   "optimize_size"
19864   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19865               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19866    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19867               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19868   "")
19869 \f
19870 ;; Convert imul by three, five and nine into lea
19871 (define_peephole2
19872   [(parallel
19873     [(set (match_operand:SI 0 "register_operand" "")
19874           (mult:SI (match_operand:SI 1 "register_operand" "")
19875                    (match_operand:SI 2 "const_int_operand" "")))
19876      (clobber (reg:CC FLAGS_REG))])]
19877   "INTVAL (operands[2]) == 3
19878    || INTVAL (operands[2]) == 5
19879    || INTVAL (operands[2]) == 9"
19880   [(set (match_dup 0)
19881         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19882                  (match_dup 1)))]
19883   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19884
19885 (define_peephole2
19886   [(parallel
19887     [(set (match_operand:SI 0 "register_operand" "")
19888           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19889                    (match_operand:SI 2 "const_int_operand" "")))
19890      (clobber (reg:CC FLAGS_REG))])]
19891   "!optimize_size
19892    && (INTVAL (operands[2]) == 3
19893        || INTVAL (operands[2]) == 5
19894        || INTVAL (operands[2]) == 9)"
19895   [(set (match_dup 0) (match_dup 1))
19896    (set (match_dup 0)
19897         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19898                  (match_dup 0)))]
19899   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19900
19901 (define_peephole2
19902   [(parallel
19903     [(set (match_operand:DI 0 "register_operand" "")
19904           (mult:DI (match_operand:DI 1 "register_operand" "")
19905                    (match_operand:DI 2 "const_int_operand" "")))
19906      (clobber (reg:CC FLAGS_REG))])]
19907   "TARGET_64BIT
19908    && (INTVAL (operands[2]) == 3
19909        || INTVAL (operands[2]) == 5
19910        || INTVAL (operands[2]) == 9)"
19911   [(set (match_dup 0)
19912         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19913                  (match_dup 1)))]
19914   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19915
19916 (define_peephole2
19917   [(parallel
19918     [(set (match_operand:DI 0 "register_operand" "")
19919           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19920                    (match_operand:DI 2 "const_int_operand" "")))
19921      (clobber (reg:CC FLAGS_REG))])]
19922   "TARGET_64BIT
19923    && !optimize_size
19924    && (INTVAL (operands[2]) == 3
19925        || INTVAL (operands[2]) == 5
19926        || INTVAL (operands[2]) == 9)"
19927   [(set (match_dup 0) (match_dup 1))
19928    (set (match_dup 0)
19929         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19930                  (match_dup 0)))]
19931   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19932
19933 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19934 ;; imul $32bit_imm, reg, reg is direct decoded.
19935 (define_peephole2
19936   [(match_scratch:DI 3 "r")
19937    (parallel [(set (match_operand:DI 0 "register_operand" "")
19938                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19939                             (match_operand:DI 2 "immediate_operand" "")))
19940               (clobber (reg:CC FLAGS_REG))])]
19941   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19942    && !satisfies_constraint_K (operands[2])"
19943   [(set (match_dup 3) (match_dup 1))
19944    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19945               (clobber (reg:CC FLAGS_REG))])]
19946 "")
19947
19948 (define_peephole2
19949   [(match_scratch:SI 3 "r")
19950    (parallel [(set (match_operand:SI 0 "register_operand" "")
19951                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19952                             (match_operand:SI 2 "immediate_operand" "")))
19953               (clobber (reg:CC FLAGS_REG))])]
19954   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19955    && !satisfies_constraint_K (operands[2])"
19956   [(set (match_dup 3) (match_dup 1))
19957    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19958               (clobber (reg:CC FLAGS_REG))])]
19959 "")
19960
19961 (define_peephole2
19962   [(match_scratch:SI 3 "r")
19963    (parallel [(set (match_operand:DI 0 "register_operand" "")
19964                    (zero_extend:DI
19965                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19966                               (match_operand:SI 2 "immediate_operand" ""))))
19967               (clobber (reg:CC FLAGS_REG))])]
19968   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19969    && !satisfies_constraint_K (operands[2])"
19970   [(set (match_dup 3) (match_dup 1))
19971    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19972               (clobber (reg:CC FLAGS_REG))])]
19973 "")
19974
19975 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19976 ;; Convert it into imul reg, reg
19977 ;; It would be better to force assembler to encode instruction using long
19978 ;; immediate, but there is apparently no way to do so.
19979 (define_peephole2
19980   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19981                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19982                             (match_operand:DI 2 "const_int_operand" "")))
19983               (clobber (reg:CC FLAGS_REG))])
19984    (match_scratch:DI 3 "r")]
19985   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19986    && satisfies_constraint_K (operands[2])"
19987   [(set (match_dup 3) (match_dup 2))
19988    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19989               (clobber (reg:CC FLAGS_REG))])]
19990 {
19991   if (!rtx_equal_p (operands[0], operands[1]))
19992     emit_move_insn (operands[0], operands[1]);
19993 })
19994
19995 (define_peephole2
19996   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19997                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19998                             (match_operand:SI 2 "const_int_operand" "")))
19999               (clobber (reg:CC FLAGS_REG))])
20000    (match_scratch:SI 3 "r")]
20001   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20002    && satisfies_constraint_K (operands[2])"
20003   [(set (match_dup 3) (match_dup 2))
20004    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20005               (clobber (reg:CC FLAGS_REG))])]
20006 {
20007   if (!rtx_equal_p (operands[0], operands[1]))
20008     emit_move_insn (operands[0], operands[1]);
20009 })
20010
20011 (define_peephole2
20012   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20013                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20014                             (match_operand:HI 2 "immediate_operand" "")))
20015               (clobber (reg:CC FLAGS_REG))])
20016    (match_scratch:HI 3 "r")]
20017   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20018   [(set (match_dup 3) (match_dup 2))
20019    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20020               (clobber (reg:CC FLAGS_REG))])]
20021 {
20022   if (!rtx_equal_p (operands[0], operands[1]))
20023     emit_move_insn (operands[0], operands[1]);
20024 })
20025
20026 ;; After splitting up read-modify operations, array accesses with memory
20027 ;; operands might end up in form:
20028 ;;  sall    $2, %eax
20029 ;;  movl    4(%esp), %edx
20030 ;;  addl    %edx, %eax
20031 ;; instead of pre-splitting:
20032 ;;  sall    $2, %eax
20033 ;;  addl    4(%esp), %eax
20034 ;; Turn it into:
20035 ;;  movl    4(%esp), %edx
20036 ;;  leal    (%edx,%eax,4), %eax
20037
20038 (define_peephole2
20039   [(parallel [(set (match_operand 0 "register_operand" "")
20040                    (ashift (match_operand 1 "register_operand" "")
20041                            (match_operand 2 "const_int_operand" "")))
20042                (clobber (reg:CC FLAGS_REG))])
20043    (set (match_operand 3 "register_operand")
20044         (match_operand 4 "x86_64_general_operand" ""))
20045    (parallel [(set (match_operand 5 "register_operand" "")
20046                    (plus (match_operand 6 "register_operand" "")
20047                          (match_operand 7 "register_operand" "")))
20048                    (clobber (reg:CC FLAGS_REG))])]
20049   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20050    /* Validate MODE for lea.  */
20051    && ((!TARGET_PARTIAL_REG_STALL
20052         && (GET_MODE (operands[0]) == QImode
20053             || GET_MODE (operands[0]) == HImode))
20054        || GET_MODE (operands[0]) == SImode
20055        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20056    /* We reorder load and the shift.  */
20057    && !rtx_equal_p (operands[1], operands[3])
20058    && !reg_overlap_mentioned_p (operands[0], operands[4])
20059    /* Last PLUS must consist of operand 0 and 3.  */
20060    && !rtx_equal_p (operands[0], operands[3])
20061    && (rtx_equal_p (operands[3], operands[6])
20062        || rtx_equal_p (operands[3], operands[7]))
20063    && (rtx_equal_p (operands[0], operands[6])
20064        || rtx_equal_p (operands[0], operands[7]))
20065    /* The intermediate operand 0 must die or be same as output.  */
20066    && (rtx_equal_p (operands[0], operands[5])
20067        || peep2_reg_dead_p (3, operands[0]))"
20068   [(set (match_dup 3) (match_dup 4))
20069    (set (match_dup 0) (match_dup 1))]
20070 {
20071   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20072   int scale = 1 << INTVAL (operands[2]);
20073   rtx index = gen_lowpart (Pmode, operands[1]);
20074   rtx base = gen_lowpart (Pmode, operands[3]);
20075   rtx dest = gen_lowpart (mode, operands[5]);
20076
20077   operands[1] = gen_rtx_PLUS (Pmode, base,
20078                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20079   if (mode != Pmode)
20080     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20081   operands[0] = dest;
20082 })
20083 \f
20084 ;; Call-value patterns last so that the wildcard operand does not
20085 ;; disrupt insn-recog's switch tables.
20086
20087 (define_insn "*call_value_pop_0"
20088   [(set (match_operand 0 "" "")
20089         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20090               (match_operand:SI 2 "" "")))
20091    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20092                             (match_operand:SI 3 "immediate_operand" "")))]
20093   "!TARGET_64BIT"
20094 {
20095   if (SIBLING_CALL_P (insn))
20096     return "jmp\t%P1";
20097   else
20098     return "call\t%P1";
20099 }
20100   [(set_attr "type" "callv")])
20101
20102 (define_insn "*call_value_pop_1"
20103   [(set (match_operand 0 "" "")
20104         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20105               (match_operand:SI 2 "" "")))
20106    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20107                             (match_operand:SI 3 "immediate_operand" "i")))]
20108   "!TARGET_64BIT"
20109 {
20110   if (constant_call_address_operand (operands[1], Pmode))
20111     {
20112       if (SIBLING_CALL_P (insn))
20113         return "jmp\t%P1";
20114       else
20115         return "call\t%P1";
20116     }
20117   if (SIBLING_CALL_P (insn))
20118     return "jmp\t%A1";
20119   else
20120     return "call\t%A1";
20121 }
20122   [(set_attr "type" "callv")])
20123
20124 (define_insn "*call_value_0"
20125   [(set (match_operand 0 "" "")
20126         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20127               (match_operand:SI 2 "" "")))]
20128   "!TARGET_64BIT"
20129 {
20130   if (SIBLING_CALL_P (insn))
20131     return "jmp\t%P1";
20132   else
20133     return "call\t%P1";
20134 }
20135   [(set_attr "type" "callv")])
20136
20137 (define_insn "*call_value_0_rex64"
20138   [(set (match_operand 0 "" "")
20139         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20140               (match_operand:DI 2 "const_int_operand" "")))]
20141   "TARGET_64BIT"
20142 {
20143   if (SIBLING_CALL_P (insn))
20144     return "jmp\t%P1";
20145   else
20146     return "call\t%P1";
20147 }
20148   [(set_attr "type" "callv")])
20149
20150 (define_insn "*call_value_1"
20151   [(set (match_operand 0 "" "")
20152         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20153               (match_operand:SI 2 "" "")))]
20154   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20155 {
20156   if (constant_call_address_operand (operands[1], Pmode))
20157     return "call\t%P1";
20158   return "call\t%A1";
20159 }
20160   [(set_attr "type" "callv")])
20161
20162 (define_insn "*sibcall_value_1"
20163   [(set (match_operand 0 "" "")
20164         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20165               (match_operand:SI 2 "" "")))]
20166   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20167 {
20168   if (constant_call_address_operand (operands[1], Pmode))
20169     return "jmp\t%P1";
20170   return "jmp\t%A1";
20171 }
20172   [(set_attr "type" "callv")])
20173
20174 (define_insn "*call_value_1_rex64"
20175   [(set (match_operand 0 "" "")
20176         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20177               (match_operand:DI 2 "" "")))]
20178   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20179 {
20180   if (constant_call_address_operand (operands[1], Pmode))
20181     return "call\t%P1";
20182   return "call\t%A1";
20183 }
20184   [(set_attr "type" "callv")])
20185
20186 (define_insn "*sibcall_value_1_rex64"
20187   [(set (match_operand 0 "" "")
20188         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20189               (match_operand:DI 2 "" "")))]
20190   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20191   "jmp\t%P1"
20192   [(set_attr "type" "callv")])
20193
20194 (define_insn "*sibcall_value_1_rex64_v"
20195   [(set (match_operand 0 "" "")
20196         (call (mem:QI (reg:DI R11_REG))
20197               (match_operand:DI 1 "" "")))]
20198   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20199   "jmp\t*%%r11"
20200   [(set_attr "type" "callv")])
20201 \f
20202 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20203 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20204 ;; caught for use by garbage collectors and the like.  Using an insn that
20205 ;; maps to SIGILL makes it more likely the program will rightfully die.
20206 ;; Keeping with tradition, "6" is in honor of #UD.
20207 (define_insn "trap"
20208   [(trap_if (const_int 1) (const_int 6))]
20209   ""
20210   { return ASM_SHORT "0x0b0f"; }
20211   [(set_attr "length" "2")])
20212
20213 (define_expand "sse_prologue_save"
20214   [(parallel [(set (match_operand:BLK 0 "" "")
20215                    (unspec:BLK [(reg:DI 21)
20216                                 (reg:DI 22)
20217                                 (reg:DI 23)
20218                                 (reg:DI 24)
20219                                 (reg:DI 25)
20220                                 (reg:DI 26)
20221                                 (reg:DI 27)
20222                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20223               (use (match_operand:DI 1 "register_operand" ""))
20224               (use (match_operand:DI 2 "immediate_operand" ""))
20225               (use (label_ref:DI (match_operand 3 "" "")))])]
20226   "TARGET_64BIT"
20227   "")
20228
20229 (define_insn "*sse_prologue_save_insn"
20230   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20231                           (match_operand:DI 4 "const_int_operand" "n")))
20232         (unspec:BLK [(reg:DI 21)
20233                      (reg:DI 22)
20234                      (reg:DI 23)
20235                      (reg:DI 24)
20236                      (reg:DI 25)
20237                      (reg:DI 26)
20238                      (reg:DI 27)
20239                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20240    (use (match_operand:DI 1 "register_operand" "r"))
20241    (use (match_operand:DI 2 "const_int_operand" "i"))
20242    (use (label_ref:DI (match_operand 3 "" "X")))]
20243   "TARGET_64BIT
20244    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20245    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20246   "*
20247 {
20248   int i;
20249   operands[0] = gen_rtx_MEM (Pmode,
20250                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20251   output_asm_insn (\"jmp\\t%A1\", operands);
20252   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20253     {
20254       operands[4] = adjust_address (operands[0], DImode, i*16);
20255       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20256       PUT_MODE (operands[4], TImode);
20257       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20258         output_asm_insn (\"rex\", operands);
20259       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20260     }
20261   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20262                              CODE_LABEL_NUMBER (operands[3]));
20263   return \"\";
20264 }
20265   "
20266   [(set_attr "type" "other")
20267    (set_attr "length_immediate" "0")
20268    (set_attr "length_address" "0")
20269    (set_attr "length" "135")
20270    (set_attr "memory" "store")
20271    (set_attr "modrm" "0")
20272    (set_attr "mode" "DI")])
20273
20274 (define_expand "prefetch"
20275   [(prefetch (match_operand 0 "address_operand" "")
20276              (match_operand:SI 1 "const_int_operand" "")
20277              (match_operand:SI 2 "const_int_operand" ""))]
20278   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20279 {
20280   int rw = INTVAL (operands[1]);
20281   int locality = INTVAL (operands[2]);
20282
20283   gcc_assert (rw == 0 || rw == 1);
20284   gcc_assert (locality >= 0 && locality <= 3);
20285   gcc_assert (GET_MODE (operands[0]) == Pmode
20286               || GET_MODE (operands[0]) == VOIDmode);
20287
20288   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20289      supported by SSE counterpart or the SSE prefetch is not available
20290      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20291      of locality.  */
20292   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20293     operands[2] = GEN_INT (3);
20294   else
20295     operands[1] = const0_rtx;
20296 })
20297
20298 (define_insn "*prefetch_sse"
20299   [(prefetch (match_operand:SI 0 "address_operand" "p")
20300              (const_int 0)
20301              (match_operand:SI 1 "const_int_operand" ""))]
20302   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20303 {
20304   static const char * const patterns[4] = {
20305    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20306   };
20307
20308   int locality = INTVAL (operands[1]);
20309   gcc_assert (locality >= 0 && locality <= 3);
20310
20311   return patterns[locality];
20312 }
20313   [(set_attr "type" "sse")
20314    (set_attr "memory" "none")])
20315
20316 (define_insn "*prefetch_sse_rex"
20317   [(prefetch (match_operand:DI 0 "address_operand" "p")
20318              (const_int 0)
20319              (match_operand:SI 1 "const_int_operand" ""))]
20320   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20321 {
20322   static const char * const patterns[4] = {
20323    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20324   };
20325
20326   int locality = INTVAL (operands[1]);
20327   gcc_assert (locality >= 0 && locality <= 3);
20328
20329   return patterns[locality];
20330 }
20331   [(set_attr "type" "sse")
20332    (set_attr "memory" "none")])
20333
20334 (define_insn "*prefetch_3dnow"
20335   [(prefetch (match_operand:SI 0 "address_operand" "p")
20336              (match_operand:SI 1 "const_int_operand" "n")
20337              (const_int 3))]
20338   "TARGET_3DNOW && !TARGET_64BIT"
20339 {
20340   if (INTVAL (operands[1]) == 0)
20341     return "prefetch\t%a0";
20342   else
20343     return "prefetchw\t%a0";
20344 }
20345   [(set_attr "type" "mmx")
20346    (set_attr "memory" "none")])
20347
20348 (define_insn "*prefetch_3dnow_rex"
20349   [(prefetch (match_operand:DI 0 "address_operand" "p")
20350              (match_operand:SI 1 "const_int_operand" "n")
20351              (const_int 3))]
20352   "TARGET_3DNOW && TARGET_64BIT"
20353 {
20354   if (INTVAL (operands[1]) == 0)
20355     return "prefetch\t%a0";
20356   else
20357     return "prefetchw\t%a0";
20358 }
20359   [(set_attr "type" "mmx")
20360    (set_attr "memory" "none")])
20361
20362 (define_expand "stack_protect_set"
20363   [(match_operand 0 "memory_operand" "")
20364    (match_operand 1 "memory_operand" "")]
20365   ""
20366 {
20367 #ifdef TARGET_THREAD_SSP_OFFSET
20368   if (TARGET_64BIT)
20369     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20370                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20371   else
20372     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20373                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20374 #else
20375   if (TARGET_64BIT)
20376     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20377   else
20378     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20379 #endif
20380   DONE;
20381 })
20382
20383 (define_insn "stack_protect_set_si"
20384   [(set (match_operand:SI 0 "memory_operand" "=m")
20385         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20386    (set (match_scratch:SI 2 "=&r") (const_int 0))
20387    (clobber (reg:CC FLAGS_REG))]
20388   ""
20389   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20390   [(set_attr "type" "multi")])
20391
20392 (define_insn "stack_protect_set_di"
20393   [(set (match_operand:DI 0 "memory_operand" "=m")
20394         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20395    (set (match_scratch:DI 2 "=&r") (const_int 0))
20396    (clobber (reg:CC FLAGS_REG))]
20397   "TARGET_64BIT"
20398   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20399   [(set_attr "type" "multi")])
20400
20401 (define_insn "stack_tls_protect_set_si"
20402   [(set (match_operand:SI 0 "memory_operand" "=m")
20403         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20404    (set (match_scratch:SI 2 "=&r") (const_int 0))
20405    (clobber (reg:CC FLAGS_REG))]
20406   ""
20407   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20408   [(set_attr "type" "multi")])
20409
20410 (define_insn "stack_tls_protect_set_di"
20411   [(set (match_operand:DI 0 "memory_operand" "=m")
20412         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20413    (set (match_scratch:DI 2 "=&r") (const_int 0))
20414    (clobber (reg:CC FLAGS_REG))]
20415   "TARGET_64BIT"
20416   {
20417      /* The kernel uses a different segment register for performance reasons; a
20418         system call would not have to trash the userspace segment register,
20419         which would be expensive */
20420      if (ix86_cmodel != CM_KERNEL)
20421         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20422      else
20423         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20424   }
20425   [(set_attr "type" "multi")])
20426
20427 (define_expand "stack_protect_test"
20428   [(match_operand 0 "memory_operand" "")
20429    (match_operand 1 "memory_operand" "")
20430    (match_operand 2 "" "")]
20431   ""
20432 {
20433   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20434   ix86_compare_op0 = operands[0];
20435   ix86_compare_op1 = operands[1];
20436   ix86_compare_emitted = flags;
20437
20438 #ifdef TARGET_THREAD_SSP_OFFSET
20439   if (TARGET_64BIT)
20440     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20441                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20442   else
20443     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20444                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20445 #else
20446   if (TARGET_64BIT)
20447     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20448   else
20449     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20450 #endif
20451   emit_jump_insn (gen_beq (operands[2]));
20452   DONE;
20453 })
20454
20455 (define_insn "stack_protect_test_si"
20456   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20457         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20458                      (match_operand:SI 2 "memory_operand" "m")]
20459                     UNSPEC_SP_TEST))
20460    (clobber (match_scratch:SI 3 "=&r"))]
20461   ""
20462   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20463   [(set_attr "type" "multi")])
20464
20465 (define_insn "stack_protect_test_di"
20466   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20467         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20468                      (match_operand:DI 2 "memory_operand" "m")]
20469                     UNSPEC_SP_TEST))
20470    (clobber (match_scratch:DI 3 "=&r"))]
20471   "TARGET_64BIT"
20472   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20473   [(set_attr "type" "multi")])
20474
20475 (define_insn "stack_tls_protect_test_si"
20476   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20477         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20478                      (match_operand:SI 2 "const_int_operand" "i")]
20479                     UNSPEC_SP_TLS_TEST))
20480    (clobber (match_scratch:SI 3 "=r"))]
20481   ""
20482   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20483   [(set_attr "type" "multi")])
20484
20485 (define_insn "stack_tls_protect_test_di"
20486   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20487         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20488                      (match_operand:DI 2 "const_int_operand" "i")]
20489                     UNSPEC_SP_TLS_TEST))
20490    (clobber (match_scratch:DI 3 "=r"))]
20491   "TARGET_64BIT"
20492   {
20493      /* The kernel uses a different segment register for performance reasons; a
20494         system call would not have to trash the userspace segment register,
20495         which would be expensive */
20496      if (ix86_cmodel != CM_KERNEL)
20497         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20498      else
20499         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20500   }
20501   [(set_attr "type" "multi")])
20502
20503 (include "mmx.md")
20504 (include "sse.md")
20505 (include "sync.md")