OSDN Git Service

* config/i386/i386.md (*fpatanxf3_i387, fpatan_extend<mode>xf3_i387):
[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 (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
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 (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
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 (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
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 (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
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 (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
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   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
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   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
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   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
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   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
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 (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
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    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
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   "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1487 {
1488   switch (get_attr_type (insn))
1489     {
1490     case TYPE_IMOVX:
1491       gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
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 (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
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    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
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    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
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    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
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    && GET_CODE (operands[1]) == MEM
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   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
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   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
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    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
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    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
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    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
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    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
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    && GET_CODE (operands[1]) == MEM
2897    && (GET_MODE (operands[0]) == XFmode
2898        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2899    && constant_pool_reference_p (operands[1])"
2900   [(set (match_dup 0) (match_dup 1))]
2901 {
2902   rtx c = avoid_constant_pool_reference (operands[1]);
2903   rtx r = operands[0];
2904
2905   if (GET_CODE (r) == SUBREG)
2906     r = SUBREG_REG (r);
2907
2908   if (SSE_REG_P (r))
2909     {
2910       if (!standard_sse_constant_p (c))
2911         FAIL;
2912     }
2913   else if (FP_REG_P (r))
2914     {
2915       if (!standard_80387_constant_p (c))
2916         FAIL;
2917     }
2918   else if (MMX_REG_P (r))
2919     FAIL;
2920
2921   operands[1] = c;
2922 })
2923
2924 (define_split
2925   [(set (match_operand 0 "register_operand" "")
2926         (float_extend (match_operand 1 "memory_operand" "")))]
2927   "reload_completed
2928    && GET_CODE (operands[1]) == MEM
2929    && (GET_MODE (operands[0]) == XFmode
2930        || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2931    && constant_pool_reference_p (operands[1])"
2932   [(set (match_dup 0) (match_dup 1))]
2933 {
2934   rtx c = avoid_constant_pool_reference (SET_SRC (PATTERN (curr_insn)));
2935   rtx r = operands[0];
2936
2937   if (GET_CODE (r) == SUBREG)
2938     r = SUBREG_REG (r);
2939
2940   if (SSE_REG_P (r))
2941     {
2942       if (!standard_sse_constant_p (c))
2943         FAIL;
2944     }
2945   else if (FP_REG_P (r))
2946     {
2947       if (!standard_80387_constant_p (c))
2948         FAIL;
2949     }
2950   else if (MMX_REG_P (r))
2951     FAIL;
2952
2953   operands[1] = c;
2954 })
2955
2956 (define_insn "swapxf"
2957   [(set (match_operand:XF 0 "register_operand" "+f")
2958         (match_operand:XF 1 "register_operand" "+f"))
2959    (set (match_dup 1)
2960         (match_dup 0))]
2961   "TARGET_80387"
2962 {
2963   if (STACK_TOP_P (operands[0]))
2964     return "fxch\t%1";
2965   else
2966     return "fxch\t%0";
2967 }
2968   [(set_attr "type" "fxch")
2969    (set_attr "mode" "XF")])
2970
2971 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
2972 (define_split
2973   [(set (match_operand:X87MODEF 0 "register_operand" "")
2974         (match_operand:X87MODEF 1 "immediate_operand" ""))]
2975   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
2976    && (standard_80387_constant_p (operands[1]) == 8
2977        || standard_80387_constant_p (operands[1]) == 9)"
2978   [(set (match_dup 0)(match_dup 1))
2979    (set (match_dup 0)
2980         (neg:X87MODEF (match_dup 0)))]
2981 {
2982   REAL_VALUE_TYPE r;
2983
2984   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2985   if (real_isnegzero (&r))
2986     operands[1] = CONST0_RTX (<MODE>mode);
2987   else
2988     operands[1] = CONST1_RTX (<MODE>mode);
2989 })
2990
2991 (define_expand "movtf"
2992   [(set (match_operand:TF 0 "nonimmediate_operand" "")
2993         (match_operand:TF 1 "nonimmediate_operand" ""))]
2994   "TARGET_64BIT"
2995 {
2996   ix86_expand_move (TFmode, operands);
2997   DONE;
2998 })
2999
3000 (define_insn "*movtf_internal"
3001   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3002         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3003   "TARGET_64BIT
3004    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3005 {
3006   switch (which_alternative)
3007     {
3008     case 0:
3009     case 1:
3010       return "#";
3011     case 2:
3012       if (get_attr_mode (insn) == MODE_V4SF)
3013         return "xorps\t%0, %0";
3014       else
3015         return "pxor\t%0, %0";
3016     case 3:
3017     case 4:
3018       if (get_attr_mode (insn) == MODE_V4SF)
3019         return "movaps\t{%1, %0|%0, %1}";
3020       else
3021         return "movdqa\t{%1, %0|%0, %1}";
3022     default:
3023       gcc_unreachable ();
3024     }
3025 }
3026   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3027    (set (attr "mode")
3028         (cond [(eq_attr "alternative" "2,3")
3029                  (if_then_else
3030                    (ne (symbol_ref "optimize_size")
3031                        (const_int 0))
3032                    (const_string "V4SF")
3033                    (const_string "TI"))
3034                (eq_attr "alternative" "4")
3035                  (if_then_else
3036                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3037                             (const_int 0))
3038                         (ne (symbol_ref "optimize_size")
3039                             (const_int 0)))
3040                    (const_string "V4SF")
3041                    (const_string "TI"))]
3042                (const_string "DI")))])
3043
3044 (define_split
3045   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3046         (match_operand:TF 1 "general_operand" ""))]
3047   "reload_completed && !SSE_REG_P (operands[0])
3048    && !SSE_REG_P (operands[1])"
3049   [(const_int 0)]
3050   "ix86_split_long_move (operands); DONE;")
3051 \f
3052 ;; Zero extension instructions
3053
3054 (define_expand "zero_extendhisi2"
3055   [(set (match_operand:SI 0 "register_operand" "")
3056      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3057   ""
3058 {
3059   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3060     {
3061       operands[1] = force_reg (HImode, operands[1]);
3062       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3063       DONE;
3064     }
3065 })
3066
3067 (define_insn "zero_extendhisi2_and"
3068   [(set (match_operand:SI 0 "register_operand" "=r")
3069      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3070    (clobber (reg:CC FLAGS_REG))]
3071   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3072   "#"
3073   [(set_attr "type" "alu1")
3074    (set_attr "mode" "SI")])
3075
3076 (define_split
3077   [(set (match_operand:SI 0 "register_operand" "")
3078         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3079    (clobber (reg:CC FLAGS_REG))]
3080   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3081   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3082               (clobber (reg:CC FLAGS_REG))])]
3083   "")
3084
3085 (define_insn "*zero_extendhisi2_movzwl"
3086   [(set (match_operand:SI 0 "register_operand" "=r")
3087      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3088   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3089   "movz{wl|x}\t{%1, %0|%0, %1}"
3090   [(set_attr "type" "imovx")
3091    (set_attr "mode" "SI")])
3092
3093 (define_expand "zero_extendqihi2"
3094   [(parallel
3095     [(set (match_operand:HI 0 "register_operand" "")
3096        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3097      (clobber (reg:CC FLAGS_REG))])]
3098   ""
3099   "")
3100
3101 (define_insn "*zero_extendqihi2_and"
3102   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3103      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3104    (clobber (reg:CC FLAGS_REG))]
3105   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3106   "#"
3107   [(set_attr "type" "alu1")
3108    (set_attr "mode" "HI")])
3109
3110 (define_insn "*zero_extendqihi2_movzbw_and"
3111   [(set (match_operand:HI 0 "register_operand" "=r,r")
3112      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3113    (clobber (reg:CC FLAGS_REG))]
3114   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3115   "#"
3116   [(set_attr "type" "imovx,alu1")
3117    (set_attr "mode" "HI")])
3118
3119 ; zero extend to SImode here to avoid partial register stalls
3120 (define_insn "*zero_extendqihi2_movzbl"
3121   [(set (match_operand:HI 0 "register_operand" "=r")
3122      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3123   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3124   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3125   [(set_attr "type" "imovx")
3126    (set_attr "mode" "SI")])
3127
3128 ;; For the movzbw case strip only the clobber
3129 (define_split
3130   [(set (match_operand:HI 0 "register_operand" "")
3131         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3132    (clobber (reg:CC FLAGS_REG))]
3133   "reload_completed
3134    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3135    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3136   [(set (match_operand:HI 0 "register_operand" "")
3137         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3138
3139 ;; When source and destination does not overlap, clear destination
3140 ;; first and then do the movb
3141 (define_split
3142   [(set (match_operand:HI 0 "register_operand" "")
3143         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3144    (clobber (reg:CC FLAGS_REG))]
3145   "reload_completed
3146    && ANY_QI_REG_P (operands[0])
3147    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3148    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3149   [(set (match_dup 0) (const_int 0))
3150    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3151   "operands[2] = gen_lowpart (QImode, operands[0]);")
3152
3153 ;; Rest is handled by single and.
3154 (define_split
3155   [(set (match_operand:HI 0 "register_operand" "")
3156         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3157    (clobber (reg:CC FLAGS_REG))]
3158   "reload_completed
3159    && true_regnum (operands[0]) == true_regnum (operands[1])"
3160   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3161               (clobber (reg:CC FLAGS_REG))])]
3162   "")
3163
3164 (define_expand "zero_extendqisi2"
3165   [(parallel
3166     [(set (match_operand:SI 0 "register_operand" "")
3167        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3168      (clobber (reg:CC FLAGS_REG))])]
3169   ""
3170   "")
3171
3172 (define_insn "*zero_extendqisi2_and"
3173   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3174      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3175    (clobber (reg:CC FLAGS_REG))]
3176   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3177   "#"
3178   [(set_attr "type" "alu1")
3179    (set_attr "mode" "SI")])
3180
3181 (define_insn "*zero_extendqisi2_movzbw_and"
3182   [(set (match_operand:SI 0 "register_operand" "=r,r")
3183      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3184    (clobber (reg:CC FLAGS_REG))]
3185   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3186   "#"
3187   [(set_attr "type" "imovx,alu1")
3188    (set_attr "mode" "SI")])
3189
3190 (define_insn "*zero_extendqisi2_movzbw"
3191   [(set (match_operand:SI 0 "register_operand" "=r")
3192      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3193   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3194   "movz{bl|x}\t{%1, %0|%0, %1}"
3195   [(set_attr "type" "imovx")
3196    (set_attr "mode" "SI")])
3197
3198 ;; For the movzbl case strip only the clobber
3199 (define_split
3200   [(set (match_operand:SI 0 "register_operand" "")
3201         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3202    (clobber (reg:CC FLAGS_REG))]
3203   "reload_completed
3204    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3205    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3206   [(set (match_dup 0)
3207         (zero_extend:SI (match_dup 1)))])
3208
3209 ;; When source and destination does not overlap, clear destination
3210 ;; first and then do the movb
3211 (define_split
3212   [(set (match_operand:SI 0 "register_operand" "")
3213         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3214    (clobber (reg:CC FLAGS_REG))]
3215   "reload_completed
3216    && ANY_QI_REG_P (operands[0])
3217    && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3218    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3219    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3220   [(set (match_dup 0) (const_int 0))
3221    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3222   "operands[2] = gen_lowpart (QImode, operands[0]);")
3223
3224 ;; Rest is handled by single and.
3225 (define_split
3226   [(set (match_operand:SI 0 "register_operand" "")
3227         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3228    (clobber (reg:CC FLAGS_REG))]
3229   "reload_completed
3230    && true_regnum (operands[0]) == true_regnum (operands[1])"
3231   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3232               (clobber (reg:CC FLAGS_REG))])]
3233   "")
3234
3235 ;; %%% Kill me once multi-word ops are sane.
3236 (define_expand "zero_extendsidi2"
3237   [(set (match_operand:DI 0 "register_operand" "=r")
3238      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3239   ""
3240   "if (!TARGET_64BIT)
3241      {
3242        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3243        DONE;
3244      }
3245   ")
3246
3247 (define_insn "zero_extendsidi2_32"
3248   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3249         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3250    (clobber (reg:CC FLAGS_REG))]
3251   "!TARGET_64BIT"
3252   "@
3253    #
3254    #
3255    #
3256    movd\t{%1, %0|%0, %1}
3257    movd\t{%1, %0|%0, %1}"
3258   [(set_attr "mode" "SI,SI,SI,DI,TI")
3259    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3260
3261 (define_insn "zero_extendsidi2_rex64"
3262   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3263      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3264   "TARGET_64BIT"
3265   "@
3266    mov\t{%k1, %k0|%k0, %k1}
3267    #
3268    movd\t{%1, %0|%0, %1}
3269    movd\t{%1, %0|%0, %1}"
3270   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3271    (set_attr "mode" "SI,DI,SI,SI")])
3272
3273 (define_split
3274   [(set (match_operand:DI 0 "memory_operand" "")
3275      (zero_extend:DI (match_dup 0)))]
3276   "TARGET_64BIT"
3277   [(set (match_dup 4) (const_int 0))]
3278   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3279
3280 (define_split
3281   [(set (match_operand:DI 0 "register_operand" "")
3282         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3283    (clobber (reg:CC FLAGS_REG))]
3284   "!TARGET_64BIT && reload_completed
3285    && true_regnum (operands[0]) == true_regnum (operands[1])"
3286   [(set (match_dup 4) (const_int 0))]
3287   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3288
3289 (define_split
3290   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3291         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3292    (clobber (reg:CC FLAGS_REG))]
3293   "!TARGET_64BIT && reload_completed
3294    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3295   [(set (match_dup 3) (match_dup 1))
3296    (set (match_dup 4) (const_int 0))]
3297   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3298
3299 (define_insn "zero_extendhidi2"
3300   [(set (match_operand:DI 0 "register_operand" "=r")
3301      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3302   "TARGET_64BIT"
3303   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3304   [(set_attr "type" "imovx")
3305    (set_attr "mode" "DI")])
3306
3307 (define_insn "zero_extendqidi2"
3308   [(set (match_operand:DI 0 "register_operand" "=r")
3309      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3310   "TARGET_64BIT"
3311   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3312   [(set_attr "type" "imovx")
3313    (set_attr "mode" "DI")])
3314 \f
3315 ;; Sign extension instructions
3316
3317 (define_expand "extendsidi2"
3318   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3319                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3320               (clobber (reg:CC FLAGS_REG))
3321               (clobber (match_scratch:SI 2 ""))])]
3322   ""
3323 {
3324   if (TARGET_64BIT)
3325     {
3326       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3327       DONE;
3328     }
3329 })
3330
3331 (define_insn "*extendsidi2_1"
3332   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3333         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3334    (clobber (reg:CC FLAGS_REG))
3335    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3336   "!TARGET_64BIT"
3337   "#")
3338
3339 (define_insn "extendsidi2_rex64"
3340   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3341         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3342   "TARGET_64BIT"
3343   "@
3344    {cltq|cdqe}
3345    movs{lq|x}\t{%1,%0|%0, %1}"
3346   [(set_attr "type" "imovx")
3347    (set_attr "mode" "DI")
3348    (set_attr "prefix_0f" "0")
3349    (set_attr "modrm" "0,1")])
3350
3351 (define_insn "extendhidi2"
3352   [(set (match_operand:DI 0 "register_operand" "=r")
3353         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3354   "TARGET_64BIT"
3355   "movs{wq|x}\t{%1,%0|%0, %1}"
3356   [(set_attr "type" "imovx")
3357    (set_attr "mode" "DI")])
3358
3359 (define_insn "extendqidi2"
3360   [(set (match_operand:DI 0 "register_operand" "=r")
3361         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3362   "TARGET_64BIT"
3363   "movs{bq|x}\t{%1,%0|%0, %1}"
3364    [(set_attr "type" "imovx")
3365     (set_attr "mode" "DI")])
3366
3367 ;; Extend to memory case when source register does die.
3368 (define_split
3369   [(set (match_operand:DI 0 "memory_operand" "")
3370         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3371    (clobber (reg:CC FLAGS_REG))
3372    (clobber (match_operand:SI 2 "register_operand" ""))]
3373   "(reload_completed
3374     && dead_or_set_p (insn, operands[1])
3375     && !reg_mentioned_p (operands[1], operands[0]))"
3376   [(set (match_dup 3) (match_dup 1))
3377    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3378               (clobber (reg:CC FLAGS_REG))])
3379    (set (match_dup 4) (match_dup 1))]
3380   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3381
3382 ;; Extend to memory case when source register does not die.
3383 (define_split
3384   [(set (match_operand:DI 0 "memory_operand" "")
3385         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3386    (clobber (reg:CC FLAGS_REG))
3387    (clobber (match_operand:SI 2 "register_operand" ""))]
3388   "reload_completed"
3389   [(const_int 0)]
3390 {
3391   split_di (&operands[0], 1, &operands[3], &operands[4]);
3392
3393   emit_move_insn (operands[3], operands[1]);
3394
3395   /* Generate a cltd if possible and doing so it profitable.  */
3396   if (true_regnum (operands[1]) == 0
3397       && true_regnum (operands[2]) == 1
3398       && (optimize_size || TARGET_USE_CLTD))
3399     {
3400       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3401     }
3402   else
3403     {
3404       emit_move_insn (operands[2], operands[1]);
3405       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3406     }
3407   emit_move_insn (operands[4], operands[2]);
3408   DONE;
3409 })
3410
3411 ;; Extend to register case.  Optimize case where source and destination
3412 ;; registers match and cases where we can use cltd.
3413 (define_split
3414   [(set (match_operand:DI 0 "register_operand" "")
3415         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3416    (clobber (reg:CC FLAGS_REG))
3417    (clobber (match_scratch:SI 2 ""))]
3418   "reload_completed"
3419   [(const_int 0)]
3420 {
3421   split_di (&operands[0], 1, &operands[3], &operands[4]);
3422
3423   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3424     emit_move_insn (operands[3], operands[1]);
3425
3426   /* Generate a cltd if possible and doing so it profitable.  */
3427   if (true_regnum (operands[3]) == 0
3428       && (optimize_size || TARGET_USE_CLTD))
3429     {
3430       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3431       DONE;
3432     }
3433
3434   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3435     emit_move_insn (operands[4], operands[1]);
3436
3437   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3438   DONE;
3439 })
3440
3441 (define_insn "extendhisi2"
3442   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3443         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3444   ""
3445 {
3446   switch (get_attr_prefix_0f (insn))
3447     {
3448     case 0:
3449       return "{cwtl|cwde}";
3450     default:
3451       return "movs{wl|x}\t{%1,%0|%0, %1}";
3452     }
3453 }
3454   [(set_attr "type" "imovx")
3455    (set_attr "mode" "SI")
3456    (set (attr "prefix_0f")
3457      ;; movsx is short decodable while cwtl is vector decoded.
3458      (if_then_else (and (eq_attr "cpu" "!k6")
3459                         (eq_attr "alternative" "0"))
3460         (const_string "0")
3461         (const_string "1")))
3462    (set (attr "modrm")
3463      (if_then_else (eq_attr "prefix_0f" "0")
3464         (const_string "0")
3465         (const_string "1")))])
3466
3467 (define_insn "*extendhisi2_zext"
3468   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3469         (zero_extend:DI
3470           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3471   "TARGET_64BIT"
3472 {
3473   switch (get_attr_prefix_0f (insn))
3474     {
3475     case 0:
3476       return "{cwtl|cwde}";
3477     default:
3478       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3479     }
3480 }
3481   [(set_attr "type" "imovx")
3482    (set_attr "mode" "SI")
3483    (set (attr "prefix_0f")
3484      ;; movsx is short decodable while cwtl is vector decoded.
3485      (if_then_else (and (eq_attr "cpu" "!k6")
3486                         (eq_attr "alternative" "0"))
3487         (const_string "0")
3488         (const_string "1")))
3489    (set (attr "modrm")
3490      (if_then_else (eq_attr "prefix_0f" "0")
3491         (const_string "0")
3492         (const_string "1")))])
3493
3494 (define_insn "extendqihi2"
3495   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3496         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3497   ""
3498 {
3499   switch (get_attr_prefix_0f (insn))
3500     {
3501     case 0:
3502       return "{cbtw|cbw}";
3503     default:
3504       return "movs{bw|x}\t{%1,%0|%0, %1}";
3505     }
3506 }
3507   [(set_attr "type" "imovx")
3508    (set_attr "mode" "HI")
3509    (set (attr "prefix_0f")
3510      ;; movsx is short decodable while cwtl is vector decoded.
3511      (if_then_else (and (eq_attr "cpu" "!k6")
3512                         (eq_attr "alternative" "0"))
3513         (const_string "0")
3514         (const_string "1")))
3515    (set (attr "modrm")
3516      (if_then_else (eq_attr "prefix_0f" "0")
3517         (const_string "0")
3518         (const_string "1")))])
3519
3520 (define_insn "extendqisi2"
3521   [(set (match_operand:SI 0 "register_operand" "=r")
3522         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3523   ""
3524   "movs{bl|x}\t{%1,%0|%0, %1}"
3525    [(set_attr "type" "imovx")
3526     (set_attr "mode" "SI")])
3527
3528 (define_insn "*extendqisi2_zext"
3529   [(set (match_operand:DI 0 "register_operand" "=r")
3530         (zero_extend:DI
3531           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3532   "TARGET_64BIT"
3533   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3534    [(set_attr "type" "imovx")
3535     (set_attr "mode" "SI")])
3536 \f
3537 ;; Conversions between float and double.
3538
3539 ;; These are all no-ops in the model used for the 80387.  So just
3540 ;; emit moves.
3541
3542 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3543 (define_insn "*dummy_extendsfdf2"
3544   [(set (match_operand:DF 0 "push_operand" "=<")
3545         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3546   "0"
3547   "#")
3548
3549 (define_split
3550   [(set (match_operand:DF 0 "push_operand" "")
3551         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3552   "!TARGET_64BIT"
3553   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3554    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3555
3556 (define_split
3557   [(set (match_operand:DF 0 "push_operand" "")
3558         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3559   "TARGET_64BIT"
3560   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3561    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3562
3563 (define_insn "*dummy_extendsfxf2"
3564   [(set (match_operand:XF 0 "push_operand" "=<")
3565         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3566   "0"
3567   "#")
3568
3569 (define_split
3570   [(set (match_operand:XF 0 "push_operand" "")
3571         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3572   ""
3573   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3574    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3575   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3576
3577 (define_split
3578   [(set (match_operand:XF 0 "push_operand" "")
3579         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3580   "TARGET_64BIT"
3581   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3582    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3583   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3584
3585 (define_split
3586   [(set (match_operand:XF 0 "push_operand" "")
3587         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3588   ""
3589   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3590    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3591   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3592
3593 (define_split
3594   [(set (match_operand:XF 0 "push_operand" "")
3595         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3596   "TARGET_64BIT"
3597   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3598    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3599   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3600
3601 (define_expand "extendsfdf2"
3602   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3603         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3604   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3605 {
3606   /* ??? Needed for compress_float_constant since all fp constants
3607      are LEGITIMATE_CONSTANT_P.  */
3608   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3609     {
3610       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3611           && standard_80387_constant_p (operands[1]) > 0)
3612         {
3613           operands[1] = simplify_const_unary_operation
3614             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3615           emit_move_insn_1 (operands[0], operands[1]);
3616           DONE;
3617         }
3618       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3619     }
3620 })
3621
3622 (define_insn "*extendsfdf2_mixed"
3623   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3624         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3625   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3626 {
3627   switch (which_alternative)
3628     {
3629     case 0:
3630       return output_387_reg_move (insn, operands);
3631
3632     case 1:
3633       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3634         return "fstp%z0\t%y0";
3635       else
3636         return "fst%z0\t%y0";
3637
3638     case 2:
3639       return "cvtss2sd\t{%1, %0|%0, %1}";
3640
3641     default:
3642       gcc_unreachable ();
3643     }
3644 }
3645   [(set_attr "type" "fmov,fmov,ssecvt")
3646    (set_attr "mode" "SF,XF,DF")])
3647
3648 (define_insn "*extendsfdf2_sse"
3649   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3650         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3651   "TARGET_SSE2 && TARGET_SSE_MATH"
3652   "cvtss2sd\t{%1, %0|%0, %1}"
3653   [(set_attr "type" "ssecvt")
3654    (set_attr "mode" "DF")])
3655
3656 (define_insn "*extendsfdf2_i387"
3657   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3658         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3659   "TARGET_80387"
3660 {
3661   switch (which_alternative)
3662     {
3663     case 0:
3664       return output_387_reg_move (insn, operands);
3665
3666     case 1:
3667       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3668         return "fstp%z0\t%y0";
3669       else
3670         return "fst%z0\t%y0";
3671
3672     default:
3673       gcc_unreachable ();
3674     }
3675 }
3676   [(set_attr "type" "fmov")
3677    (set_attr "mode" "SF,XF")])
3678
3679 (define_expand "extendsfxf2"
3680   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3681         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3682   "TARGET_80387"
3683 {
3684   /* ??? Needed for compress_float_constant since all fp constants
3685      are LEGITIMATE_CONSTANT_P.  */
3686   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3687     {
3688       if (standard_80387_constant_p (operands[1]) > 0)
3689         {
3690           operands[1] = simplify_const_unary_operation
3691             (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3692           emit_move_insn_1 (operands[0], operands[1]);
3693           DONE;
3694         }
3695       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3696     }
3697 })
3698
3699 (define_insn "*extendsfxf2_i387"
3700   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3701         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3702   "TARGET_80387"
3703 {
3704   switch (which_alternative)
3705     {
3706     case 0:
3707       return output_387_reg_move (insn, operands);
3708
3709     case 1:
3710       /* There is no non-popping store to memory for XFmode.  So if
3711          we need one, follow the store with a load.  */
3712       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3713         return "fstp%z0\t%y0";
3714       else
3715         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3716
3717     default:
3718       gcc_unreachable ();
3719     }
3720 }
3721   [(set_attr "type" "fmov")
3722    (set_attr "mode" "SF,XF")])
3723
3724 (define_expand "extenddfxf2"
3725   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3726         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3727   "TARGET_80387"
3728 {
3729   /* ??? Needed for compress_float_constant since all fp constants
3730      are LEGITIMATE_CONSTANT_P.  */
3731   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3732     {
3733       if (standard_80387_constant_p (operands[1]) > 0)
3734         {
3735           operands[1] = simplify_const_unary_operation
3736             (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3737           emit_move_insn_1 (operands[0], operands[1]);
3738           DONE;
3739         }
3740       operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3741     }
3742 })
3743
3744 (define_insn "*extenddfxf2_i387"
3745   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3746         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3747   "TARGET_80387"
3748 {
3749   switch (which_alternative)
3750     {
3751     case 0:
3752       return output_387_reg_move (insn, operands);
3753
3754     case 1:
3755       /* There is no non-popping store to memory for XFmode.  So if
3756          we need one, follow the store with a load.  */
3757       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3758         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3759       else
3760         return "fstp%z0\t%y0";
3761
3762     default:
3763       gcc_unreachable ();
3764     }
3765 }
3766   [(set_attr "type" "fmov")
3767    (set_attr "mode" "DF,XF")])
3768
3769 ;; %%% This seems bad bad news.
3770 ;; This cannot output into an f-reg because there is no way to be sure
3771 ;; of truncating in that case.  Otherwise this is just like a simple move
3772 ;; insn.  So we pretend we can output to a reg in order to get better
3773 ;; register preferencing, but we really use a stack slot.
3774
3775 ;; Conversion from DFmode to SFmode.
3776
3777 (define_expand "truncdfsf2"
3778   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3779         (float_truncate:SF
3780           (match_operand:DF 1 "nonimmediate_operand" "")))]
3781   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3782 {
3783   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3784     ;
3785   else if (flag_unsafe_math_optimizations)
3786     ;
3787   else
3788     {
3789       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3790       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3791       DONE;
3792     }
3793 })
3794
3795 (define_expand "truncdfsf2_with_temp"
3796   [(parallel [(set (match_operand:SF 0 "" "")
3797                    (float_truncate:SF (match_operand:DF 1 "" "")))
3798               (clobber (match_operand:SF 2 "" ""))])]
3799   "")
3800
3801 (define_insn "*truncdfsf_fast_mixed"
3802   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3803         (float_truncate:SF
3804           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3805   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3806 {
3807   switch (which_alternative)
3808     {
3809     case 0:
3810       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3811         return "fstp%z0\t%y0";
3812       else
3813         return "fst%z0\t%y0";
3814     case 1:
3815       return output_387_reg_move (insn, operands);
3816     case 2:
3817       return "cvtsd2ss\t{%1, %0|%0, %1}";
3818     default:
3819       gcc_unreachable ();
3820     }
3821 }
3822   [(set_attr "type" "fmov,fmov,ssecvt")
3823    (set_attr "mode" "SF")])
3824
3825 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3826 ;; because nothing we do here is unsafe.
3827 (define_insn "*truncdfsf_fast_sse"
3828   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3829         (float_truncate:SF
3830           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3831   "TARGET_SSE2 && TARGET_SSE_MATH"
3832   "cvtsd2ss\t{%1, %0|%0, %1}"
3833   [(set_attr "type" "ssecvt")
3834    (set_attr "mode" "SF")])
3835
3836 (define_insn "*truncdfsf_fast_i387"
3837   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3838         (float_truncate:SF
3839           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3840   "TARGET_80387 && flag_unsafe_math_optimizations"
3841   "* return output_387_reg_move (insn, operands);"
3842   [(set_attr "type" "fmov")
3843    (set_attr "mode" "SF")])
3844
3845 (define_insn "*truncdfsf_mixed"
3846   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3847         (float_truncate:SF
3848           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3849    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3850   "TARGET_MIX_SSE_I387"
3851 {
3852   switch (which_alternative)
3853     {
3854     case 0:
3855       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3856         return "fstp%z0\t%y0";
3857       else
3858         return "fst%z0\t%y0";
3859     case 1:
3860       return "#";
3861     case 2:
3862       return "cvtsd2ss\t{%1, %0|%0, %1}";
3863     default:
3864       gcc_unreachable ();
3865     }
3866 }
3867   [(set_attr "type" "fmov,multi,ssecvt")
3868    (set_attr "unit" "*,i387,*")
3869    (set_attr "mode" "SF")])
3870
3871 (define_insn "*truncdfsf_i387"
3872   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3873         (float_truncate:SF
3874           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3875    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3876   "TARGET_80387"
3877 {
3878   switch (which_alternative)
3879     {
3880     case 0:
3881       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3882         return "fstp%z0\t%y0";
3883       else
3884         return "fst%z0\t%y0";
3885     case 1:
3886       return "#";
3887     default:
3888       gcc_unreachable ();
3889     }
3890 }
3891   [(set_attr "type" "fmov,multi")
3892    (set_attr "unit" "*,i387")
3893    (set_attr "mode" "SF")])
3894
3895 (define_insn "*truncdfsf2_i387_1"
3896   [(set (match_operand:SF 0 "memory_operand" "=m")
3897         (float_truncate:SF
3898           (match_operand:DF 1 "register_operand" "f")))]
3899   "TARGET_80387
3900    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3901    && !TARGET_MIX_SSE_I387"
3902 {
3903   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3904     return "fstp%z0\t%y0";
3905   else
3906     return "fst%z0\t%y0";
3907 }
3908   [(set_attr "type" "fmov")
3909    (set_attr "mode" "SF")])
3910
3911 (define_split
3912   [(set (match_operand:SF 0 "register_operand" "")
3913         (float_truncate:SF
3914          (match_operand:DF 1 "fp_register_operand" "")))
3915    (clobber (match_operand 2 "" ""))]
3916   "reload_completed"
3917   [(set (match_dup 2) (match_dup 1))
3918    (set (match_dup 0) (match_dup 2))]
3919 {
3920   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3921 })
3922
3923 ;; Conversion from XFmode to SFmode.
3924
3925 (define_expand "truncxfsf2"
3926   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3927                    (float_truncate:SF
3928                     (match_operand:XF 1 "register_operand" "")))
3929               (clobber (match_dup 2))])]
3930   "TARGET_80387"
3931 {
3932   if (flag_unsafe_math_optimizations)
3933     {
3934       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3935       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3936       if (reg != operands[0])
3937         emit_move_insn (operands[0], reg);
3938       DONE;
3939     }
3940   else
3941     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3942 })
3943
3944 (define_insn "*truncxfsf2_mixed"
3945   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3946         (float_truncate:SF
3947          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3948    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3949   "TARGET_80387"
3950 {
3951   gcc_assert (!which_alternative);
3952   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3953     return "fstp%z0\t%y0";
3954   else
3955     return "fst%z0\t%y0";
3956 }
3957   [(set_attr "type" "fmov,multi,multi,multi")
3958    (set_attr "unit" "*,i387,i387,i387")
3959    (set_attr "mode" "SF")])
3960
3961 (define_insn "truncxfsf2_i387_noop"
3962   [(set (match_operand:SF 0 "register_operand" "=f")
3963         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3964   "TARGET_80387 && flag_unsafe_math_optimizations"
3965   "* return output_387_reg_move (insn, operands);"
3966   [(set_attr "type" "fmov")
3967    (set_attr "mode" "SF")])
3968
3969 (define_insn "*truncxfsf2_i387"
3970   [(set (match_operand:SF 0 "memory_operand" "=m")
3971         (float_truncate:SF
3972          (match_operand:XF 1 "register_operand" "f")))]
3973   "TARGET_80387"
3974 {
3975   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3976     return "fstp%z0\t%y0";
3977   else
3978     return "fst%z0\t%y0";
3979 }
3980   [(set_attr "type" "fmov")
3981    (set_attr "mode" "SF")])
3982
3983 (define_split
3984   [(set (match_operand:SF 0 "register_operand" "")
3985         (float_truncate:SF
3986          (match_operand:XF 1 "register_operand" "")))
3987    (clobber (match_operand:SF 2 "memory_operand" ""))]
3988   "TARGET_80387 && reload_completed"
3989   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3990    (set (match_dup 0) (match_dup 2))]
3991   "")
3992
3993 (define_split
3994   [(set (match_operand:SF 0 "memory_operand" "")
3995         (float_truncate:SF
3996          (match_operand:XF 1 "register_operand" "")))
3997    (clobber (match_operand:SF 2 "memory_operand" ""))]
3998   "TARGET_80387"
3999   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4000   "")
4001
4002 ;; Conversion from XFmode to DFmode.
4003
4004 (define_expand "truncxfdf2"
4005   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4006                    (float_truncate:DF
4007                     (match_operand:XF 1 "register_operand" "")))
4008               (clobber (match_dup 2))])]
4009   "TARGET_80387"
4010 {
4011   if (flag_unsafe_math_optimizations)
4012     {
4013       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
4014       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
4015       if (reg != operands[0])
4016         emit_move_insn (operands[0], reg);
4017       DONE;
4018     }
4019   else
4020     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
4021 })
4022
4023 (define_insn "*truncxfdf2_mixed"
4024   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
4025         (float_truncate:DF
4026          (match_operand:XF 1 "register_operand" "f,f,f,f")))
4027    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4028   "TARGET_80387"
4029 {
4030   gcc_assert (!which_alternative);
4031   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4032     return "fstp%z0\t%y0";
4033   else
4034     return "fst%z0\t%y0";
4035 }
4036   [(set_attr "type" "fmov,multi,multi,multi")
4037    (set_attr "unit" "*,i387,i387,i387")
4038    (set_attr "mode" "DF")])
4039
4040 (define_insn "truncxfdf2_i387_noop"
4041   [(set (match_operand:DF 0 "register_operand" "=f")
4042         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4043   "TARGET_80387 && flag_unsafe_math_optimizations"
4044   "* return output_387_reg_move (insn, operands);"
4045   [(set_attr "type" "fmov")
4046    (set_attr "mode" "DF")])
4047
4048 (define_insn "*truncxfdf2_i387"
4049   [(set (match_operand:DF 0 "memory_operand" "=m")
4050         (float_truncate:DF
4051           (match_operand:XF 1 "register_operand" "f")))]
4052   "TARGET_80387"
4053 {
4054   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4055     return "fstp%z0\t%y0";
4056   else
4057     return "fst%z0\t%y0";
4058 }
4059   [(set_attr "type" "fmov")
4060    (set_attr "mode" "DF")])
4061
4062 (define_split
4063   [(set (match_operand:DF 0 "register_operand" "")
4064         (float_truncate:DF
4065          (match_operand:XF 1 "register_operand" "")))
4066    (clobber (match_operand:DF 2 "memory_operand" ""))]
4067   "TARGET_80387 && reload_completed"
4068   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4069    (set (match_dup 0) (match_dup 2))]
4070   "")
4071
4072 (define_split
4073   [(set (match_operand:DF 0 "memory_operand" "")
4074         (float_truncate:DF
4075          (match_operand:XF 1 "register_operand" "")))
4076    (clobber (match_operand:DF 2 "memory_operand" ""))]
4077   "TARGET_80387"
4078   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4079   "")
4080 \f
4081 ;; Signed conversion to DImode.
4082
4083 (define_expand "fix_truncxfdi2"
4084   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4085                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4086               (clobber (reg:CC FLAGS_REG))])]
4087   "TARGET_80387"
4088 {
4089   if (TARGET_FISTTP)
4090    {
4091      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4092      DONE;
4093    }
4094 })
4095
4096 (define_expand "fix_trunc<mode>di2"
4097   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4098                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4099               (clobber (reg:CC FLAGS_REG))])]
4100   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4101 {
4102   if (TARGET_FISTTP
4103       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4104    {
4105      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4106      DONE;
4107    }
4108   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4109    {
4110      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4111      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4112      if (out != operands[0])
4113         emit_move_insn (operands[0], out);
4114      DONE;
4115    }
4116 })
4117
4118 ;; Signed conversion to SImode.
4119
4120 (define_expand "fix_truncxfsi2"
4121   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4122                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4123               (clobber (reg:CC FLAGS_REG))])]
4124   "TARGET_80387"
4125 {
4126   if (TARGET_FISTTP)
4127    {
4128      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4129      DONE;
4130    }
4131 })
4132
4133 (define_expand "fix_trunc<mode>si2"
4134   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4135                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4136               (clobber (reg:CC FLAGS_REG))])]
4137   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4138 {
4139   if (TARGET_FISTTP
4140       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4141    {
4142      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4143      DONE;
4144    }
4145   if (SSE_FLOAT_MODE_P (<MODE>mode))
4146    {
4147      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4148      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4149      if (out != operands[0])
4150         emit_move_insn (operands[0], out);
4151      DONE;
4152    }
4153 })
4154
4155 ;; Signed conversion to HImode.
4156
4157 (define_expand "fix_trunc<mode>hi2"
4158   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4159                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4160               (clobber (reg:CC FLAGS_REG))])]
4161   "TARGET_80387
4162    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4163 {
4164   if (TARGET_FISTTP)
4165    {
4166      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4167      DONE;
4168    }
4169 })
4170
4171 ;; When SSE is available, it is always faster to use it!
4172 (define_insn "fix_truncsfdi_sse"
4173   [(set (match_operand:DI 0 "register_operand" "=r,r")
4174         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4175   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4176   "cvttss2si{q}\t{%1, %0|%0, %1}"
4177   [(set_attr "type" "sseicvt")
4178    (set_attr "mode" "SF")
4179    (set_attr "athlon_decode" "double,vector")])
4180
4181 (define_insn "fix_truncdfdi_sse"
4182   [(set (match_operand:DI 0 "register_operand" "=r,r")
4183         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4184   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4185   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4186   [(set_attr "type" "sseicvt")
4187    (set_attr "mode" "DF")
4188    (set_attr "athlon_decode" "double,vector")])
4189
4190 (define_insn "fix_truncsfsi_sse"
4191   [(set (match_operand:SI 0 "register_operand" "=r,r")
4192         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4193   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4194   "cvttss2si\t{%1, %0|%0, %1}"
4195   [(set_attr "type" "sseicvt")
4196    (set_attr "mode" "DF")
4197    (set_attr "athlon_decode" "double,vector")])
4198
4199 (define_insn "fix_truncdfsi_sse"
4200   [(set (match_operand:SI 0 "register_operand" "=r,r")
4201         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4202   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4203   "cvttsd2si\t{%1, %0|%0, %1}"
4204   [(set_attr "type" "sseicvt")
4205    (set_attr "mode" "DF")
4206    (set_attr "athlon_decode" "double,vector")])
4207
4208 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4209 (define_peephole2
4210   [(set (match_operand:DF 0 "register_operand" "")
4211         (match_operand:DF 1 "memory_operand" ""))
4212    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4213         (fix:SSEMODEI24 (match_dup 0)))]
4214   "!TARGET_K8
4215    && peep2_reg_dead_p (2, operands[0])"
4216   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4217   "")
4218
4219 (define_peephole2
4220   [(set (match_operand:SF 0 "register_operand" "")
4221         (match_operand:SF 1 "memory_operand" ""))
4222    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4223         (fix:SSEMODEI24 (match_dup 0)))]
4224   "!TARGET_K8
4225    && peep2_reg_dead_p (2, operands[0])"
4226   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4227   "")
4228
4229 ;; Avoid vector decoded forms of the instruction.
4230 (define_peephole2
4231   [(match_scratch:DF 2 "Y")
4232    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4233         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4234   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4235   [(set (match_dup 2) (match_dup 1))
4236    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4237   "")
4238
4239 (define_peephole2
4240   [(match_scratch:SF 2 "x")
4241    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4242         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4243   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4244   [(set (match_dup 2) (match_dup 1))
4245    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4246   "")
4247
4248 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4249   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4250         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4251   "TARGET_FISTTP
4252    && FLOAT_MODE_P (GET_MODE (operands[1]))
4253    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4254          && (TARGET_64BIT || <MODE>mode != DImode))
4255         && TARGET_SSE_MATH)
4256    && !(reload_completed || reload_in_progress)"
4257   "#"
4258   "&& 1"
4259   [(const_int 0)]
4260 {
4261   if (memory_operand (operands[0], VOIDmode))
4262     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4263   else
4264     {
4265       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4266       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4267                                                             operands[1],
4268                                                             operands[2]));
4269     }
4270   DONE;
4271 }
4272   [(set_attr "type" "fisttp")
4273    (set_attr "mode" "<MODE>")])
4274
4275 (define_insn "fix_trunc<mode>_i387_fisttp"
4276   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4277         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4278    (clobber (match_scratch:XF 2 "=&1f"))]
4279   "TARGET_FISTTP
4280    && FLOAT_MODE_P (GET_MODE (operands[1]))
4281    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4282          && (TARGET_64BIT || <MODE>mode != DImode))
4283         && TARGET_SSE_MATH)"
4284   "* return output_fix_trunc (insn, operands, 1);"
4285   [(set_attr "type" "fisttp")
4286    (set_attr "mode" "<MODE>")])
4287
4288 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4289   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4290         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4291    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4292    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4293   "TARGET_FISTTP
4294    && FLOAT_MODE_P (GET_MODE (operands[1]))
4295    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4296         && (TARGET_64BIT || <MODE>mode != DImode))
4297         && TARGET_SSE_MATH)"
4298   "#"
4299   [(set_attr "type" "fisttp")
4300    (set_attr "mode" "<MODE>")])
4301
4302 (define_split
4303   [(set (match_operand:X87MODEI 0 "register_operand" "")
4304         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4305    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4306    (clobber (match_scratch 3 ""))]
4307   "reload_completed"
4308   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4309               (clobber (match_dup 3))])
4310    (set (match_dup 0) (match_dup 2))]
4311   "")
4312
4313 (define_split
4314   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4315         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4316    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4317    (clobber (match_scratch 3 ""))]
4318   "reload_completed"
4319   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4320               (clobber (match_dup 3))])]
4321   "")
4322
4323 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4324 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4325 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4326 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4327 ;; function in i386.c.
4328 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4329   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4330         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4331    (clobber (reg:CC FLAGS_REG))]
4332   "TARGET_80387 && !TARGET_FISTTP
4333    && FLOAT_MODE_P (GET_MODE (operands[1]))
4334    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4335          && (TARGET_64BIT || <MODE>mode != DImode))
4336    && !(reload_completed || reload_in_progress)"
4337   "#"
4338   "&& 1"
4339   [(const_int 0)]
4340 {
4341   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4342
4343   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4344   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4345   if (memory_operand (operands[0], VOIDmode))
4346     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4347                                          operands[2], operands[3]));
4348   else
4349     {
4350       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4351       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4352                                                      operands[2], operands[3],
4353                                                      operands[4]));
4354     }
4355   DONE;
4356 }
4357   [(set_attr "type" "fistp")
4358    (set_attr "i387_cw" "trunc")
4359    (set_attr "mode" "<MODE>")])
4360
4361 (define_insn "fix_truncdi_i387"
4362   [(set (match_operand:DI 0 "memory_operand" "=m")
4363         (fix:DI (match_operand 1 "register_operand" "f")))
4364    (use (match_operand:HI 2 "memory_operand" "m"))
4365    (use (match_operand:HI 3 "memory_operand" "m"))
4366    (clobber (match_scratch:XF 4 "=&1f"))]
4367   "TARGET_80387 && !TARGET_FISTTP
4368    && FLOAT_MODE_P (GET_MODE (operands[1]))
4369    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4370   "* return output_fix_trunc (insn, operands, 0);"
4371   [(set_attr "type" "fistp")
4372    (set_attr "i387_cw" "trunc")
4373    (set_attr "mode" "DI")])
4374
4375 (define_insn "fix_truncdi_i387_with_temp"
4376   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4377         (fix:DI (match_operand 1 "register_operand" "f,f")))
4378    (use (match_operand:HI 2 "memory_operand" "m,m"))
4379    (use (match_operand:HI 3 "memory_operand" "m,m"))
4380    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4381    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4382   "TARGET_80387 && !TARGET_FISTTP
4383    && FLOAT_MODE_P (GET_MODE (operands[1]))
4384    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4385   "#"
4386   [(set_attr "type" "fistp")
4387    (set_attr "i387_cw" "trunc")
4388    (set_attr "mode" "DI")])
4389
4390 (define_split
4391   [(set (match_operand:DI 0 "register_operand" "")
4392         (fix:DI (match_operand 1 "register_operand" "")))
4393    (use (match_operand:HI 2 "memory_operand" ""))
4394    (use (match_operand:HI 3 "memory_operand" ""))
4395    (clobber (match_operand:DI 4 "memory_operand" ""))
4396    (clobber (match_scratch 5 ""))]
4397   "reload_completed"
4398   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4399               (use (match_dup 2))
4400               (use (match_dup 3))
4401               (clobber (match_dup 5))])
4402    (set (match_dup 0) (match_dup 4))]
4403   "")
4404
4405 (define_split
4406   [(set (match_operand:DI 0 "memory_operand" "")
4407         (fix:DI (match_operand 1 "register_operand" "")))
4408    (use (match_operand:HI 2 "memory_operand" ""))
4409    (use (match_operand:HI 3 "memory_operand" ""))
4410    (clobber (match_operand:DI 4 "memory_operand" ""))
4411    (clobber (match_scratch 5 ""))]
4412   "reload_completed"
4413   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4414               (use (match_dup 2))
4415               (use (match_dup 3))
4416               (clobber (match_dup 5))])]
4417   "")
4418
4419 (define_insn "fix_trunc<mode>_i387"
4420   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4421         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4422    (use (match_operand:HI 2 "memory_operand" "m"))
4423    (use (match_operand:HI 3 "memory_operand" "m"))]
4424   "TARGET_80387 && !TARGET_FISTTP
4425    && FLOAT_MODE_P (GET_MODE (operands[1]))
4426    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4427   "* return output_fix_trunc (insn, operands, 0);"
4428   [(set_attr "type" "fistp")
4429    (set_attr "i387_cw" "trunc")
4430    (set_attr "mode" "<MODE>")])
4431
4432 (define_insn "fix_trunc<mode>_i387_with_temp"
4433   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4434         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4435    (use (match_operand:HI 2 "memory_operand" "m,m"))
4436    (use (match_operand:HI 3 "memory_operand" "m,m"))
4437    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4438   "TARGET_80387 && !TARGET_FISTTP
4439    && FLOAT_MODE_P (GET_MODE (operands[1]))
4440    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4441   "#"
4442   [(set_attr "type" "fistp")
4443    (set_attr "i387_cw" "trunc")
4444    (set_attr "mode" "<MODE>")])
4445
4446 (define_split
4447   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4448         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4449    (use (match_operand:HI 2 "memory_operand" ""))
4450    (use (match_operand:HI 3 "memory_operand" ""))
4451    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4452   "reload_completed"
4453   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4454               (use (match_dup 2))
4455               (use (match_dup 3))])
4456    (set (match_dup 0) (match_dup 4))]
4457   "")
4458
4459 (define_split
4460   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4461         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4462    (use (match_operand:HI 2 "memory_operand" ""))
4463    (use (match_operand:HI 3 "memory_operand" ""))
4464    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4465   "reload_completed"
4466   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4467               (use (match_dup 2))
4468               (use (match_dup 3))])]
4469   "")
4470
4471 (define_insn "x86_fnstcw_1"
4472   [(set (match_operand:HI 0 "memory_operand" "=m")
4473         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4474   "TARGET_80387"
4475   "fnstcw\t%0"
4476   [(set_attr "length" "2")
4477    (set_attr "mode" "HI")
4478    (set_attr "unit" "i387")])
4479
4480 (define_insn "x86_fldcw_1"
4481   [(set (reg:HI FPCR_REG)
4482         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4483   "TARGET_80387"
4484   "fldcw\t%0"
4485   [(set_attr "length" "2")
4486    (set_attr "mode" "HI")
4487    (set_attr "unit" "i387")
4488    (set_attr "athlon_decode" "vector")])
4489 \f
4490 ;; Conversion between fixed point and floating point.
4491
4492 ;; Even though we only accept memory inputs, the backend _really_
4493 ;; wants to be able to do this between registers.
4494
4495 (define_expand "floathisf2"
4496   [(set (match_operand:SF 0 "register_operand" "")
4497         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4498   "TARGET_80387 || TARGET_SSE_MATH"
4499 {
4500   if (TARGET_SSE_MATH)
4501     {
4502       emit_insn (gen_floatsisf2 (operands[0],
4503                                  convert_to_mode (SImode, operands[1], 0)));
4504       DONE;
4505     }
4506 })
4507
4508 (define_insn "*floathisf2_i387"
4509   [(set (match_operand:SF 0 "register_operand" "=f,f")
4510         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4511   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4512   "@
4513    fild%z1\t%1
4514    #"
4515   [(set_attr "type" "fmov,multi")
4516    (set_attr "mode" "SF")
4517    (set_attr "unit" "*,i387")
4518    (set_attr "fp_int_src" "true")])
4519
4520 (define_expand "floatsisf2"
4521   [(set (match_operand:SF 0 "register_operand" "")
4522         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4523   "TARGET_80387 || TARGET_SSE_MATH"
4524   "")
4525
4526 (define_insn "*floatsisf2_mixed"
4527   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4528         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4529   "TARGET_MIX_SSE_I387"
4530   "@
4531    fild%z1\t%1
4532    #
4533    cvtsi2ss\t{%1, %0|%0, %1}
4534    cvtsi2ss\t{%1, %0|%0, %1}"
4535   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4536    (set_attr "mode" "SF")
4537    (set_attr "unit" "*,i387,*,*")
4538    (set_attr "athlon_decode" "*,*,vector,double")
4539    (set_attr "fp_int_src" "true")])
4540
4541 (define_insn "*floatsisf2_sse"
4542   [(set (match_operand:SF 0 "register_operand" "=x,x")
4543         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4544   "TARGET_SSE_MATH"
4545   "cvtsi2ss\t{%1, %0|%0, %1}"
4546   [(set_attr "type" "sseicvt")
4547    (set_attr "mode" "SF")
4548    (set_attr "athlon_decode" "vector,double")
4549    (set_attr "fp_int_src" "true")])
4550
4551 (define_insn "*floatsisf2_i387"
4552   [(set (match_operand:SF 0 "register_operand" "=f,f")
4553         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4554   "TARGET_80387"
4555   "@
4556    fild%z1\t%1
4557    #"
4558   [(set_attr "type" "fmov,multi")
4559    (set_attr "mode" "SF")
4560    (set_attr "unit" "*,i387")
4561    (set_attr "fp_int_src" "true")])
4562
4563 (define_expand "floatdisf2"
4564   [(set (match_operand:SF 0 "register_operand" "")
4565         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4566   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4567   "")
4568
4569 (define_insn "*floatdisf2_mixed"
4570   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4571         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4572   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4573   "@
4574    fild%z1\t%1
4575    #
4576    cvtsi2ss{q}\t{%1, %0|%0, %1}
4577    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4578   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4579    (set_attr "mode" "SF")
4580    (set_attr "unit" "*,i387,*,*")
4581    (set_attr "athlon_decode" "*,*,vector,double")
4582    (set_attr "fp_int_src" "true")])
4583
4584 (define_insn "*floatdisf2_sse"
4585   [(set (match_operand:SF 0 "register_operand" "=x,x")
4586         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4587   "TARGET_64BIT && TARGET_SSE_MATH"
4588   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4589   [(set_attr "type" "sseicvt")
4590    (set_attr "mode" "SF")
4591    (set_attr "athlon_decode" "vector,double")
4592    (set_attr "fp_int_src" "true")])
4593
4594 (define_insn "*floatdisf2_i387"
4595   [(set (match_operand:SF 0 "register_operand" "=f,f")
4596         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4597   "TARGET_80387"
4598   "@
4599    fild%z1\t%1
4600    #"
4601   [(set_attr "type" "fmov,multi")
4602    (set_attr "mode" "SF")
4603    (set_attr "unit" "*,i387")
4604    (set_attr "fp_int_src" "true")])
4605
4606 (define_expand "floathidf2"
4607   [(set (match_operand:DF 0 "register_operand" "")
4608         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4609   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4610 {
4611   if (TARGET_SSE2 && TARGET_SSE_MATH)
4612     {
4613       emit_insn (gen_floatsidf2 (operands[0],
4614                                  convert_to_mode (SImode, operands[1], 0)));
4615       DONE;
4616     }
4617 })
4618
4619 (define_insn "*floathidf2_i387"
4620   [(set (match_operand:DF 0 "register_operand" "=f,f")
4621         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4622   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4623   "@
4624    fild%z1\t%1
4625    #"
4626   [(set_attr "type" "fmov,multi")
4627    (set_attr "mode" "DF")
4628    (set_attr "unit" "*,i387")
4629    (set_attr "fp_int_src" "true")])
4630
4631 (define_expand "floatsidf2"
4632   [(set (match_operand:DF 0 "register_operand" "")
4633         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4634   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4635   "")
4636
4637 (define_insn "*floatsidf2_mixed"
4638   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4639         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4640   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4641   "@
4642    fild%z1\t%1
4643    #
4644    cvtsi2sd\t{%1, %0|%0, %1}
4645    cvtsi2sd\t{%1, %0|%0, %1}"
4646   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4647    (set_attr "mode" "DF")
4648    (set_attr "unit" "*,i387,*,*")
4649    (set_attr "athlon_decode" "*,*,double,direct")
4650    (set_attr "fp_int_src" "true")])
4651
4652 (define_insn "*floatsidf2_sse"
4653   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4654         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4655   "TARGET_SSE2 && TARGET_SSE_MATH"
4656   "cvtsi2sd\t{%1, %0|%0, %1}"
4657   [(set_attr "type" "sseicvt")
4658    (set_attr "mode" "DF")
4659    (set_attr "athlon_decode" "double,direct")
4660    (set_attr "fp_int_src" "true")])
4661
4662 (define_insn "*floatsidf2_i387"
4663   [(set (match_operand:DF 0 "register_operand" "=f,f")
4664         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4665   "TARGET_80387"
4666   "@
4667    fild%z1\t%1
4668    #"
4669   [(set_attr "type" "fmov,multi")
4670    (set_attr "mode" "DF")
4671    (set_attr "unit" "*,i387")
4672    (set_attr "fp_int_src" "true")])
4673
4674 (define_expand "floatdidf2"
4675   [(set (match_operand:DF 0 "register_operand" "")
4676         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4677   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4678   "")
4679
4680 (define_insn "*floatdidf2_mixed"
4681   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4682         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4683   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4684   "@
4685    fild%z1\t%1
4686    #
4687    cvtsi2sd{q}\t{%1, %0|%0, %1}
4688    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4689   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4690    (set_attr "mode" "DF")
4691    (set_attr "unit" "*,i387,*,*")
4692    (set_attr "athlon_decode" "*,*,double,direct")
4693    (set_attr "fp_int_src" "true")])
4694
4695 (define_insn "*floatdidf2_sse"
4696   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4697         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4698   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4699   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4700   [(set_attr "type" "sseicvt")
4701    (set_attr "mode" "DF")
4702    (set_attr "athlon_decode" "double,direct")
4703    (set_attr "fp_int_src" "true")])
4704
4705 (define_insn "*floatdidf2_i387"
4706   [(set (match_operand:DF 0 "register_operand" "=f,f")
4707         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4708   "TARGET_80387"
4709   "@
4710    fild%z1\t%1
4711    #"
4712   [(set_attr "type" "fmov,multi")
4713    (set_attr "mode" "DF")
4714    (set_attr "unit" "*,i387")
4715    (set_attr "fp_int_src" "true")])
4716
4717 (define_insn "floathixf2"
4718   [(set (match_operand:XF 0 "register_operand" "=f,f")
4719         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4720   "TARGET_80387"
4721   "@
4722    fild%z1\t%1
4723    #"
4724   [(set_attr "type" "fmov,multi")
4725    (set_attr "mode" "XF")
4726    (set_attr "unit" "*,i387")
4727    (set_attr "fp_int_src" "true")])
4728
4729 (define_insn "floatsixf2"
4730   [(set (match_operand:XF 0 "register_operand" "=f,f")
4731         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4732   "TARGET_80387"
4733   "@
4734    fild%z1\t%1
4735    #"
4736   [(set_attr "type" "fmov,multi")
4737    (set_attr "mode" "XF")
4738    (set_attr "unit" "*,i387")
4739    (set_attr "fp_int_src" "true")])
4740
4741 (define_insn "floatdixf2"
4742   [(set (match_operand:XF 0 "register_operand" "=f,f")
4743         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4744   "TARGET_80387"
4745   "@
4746    fild%z1\t%1
4747    #"
4748   [(set_attr "type" "fmov,multi")
4749    (set_attr "mode" "XF")
4750    (set_attr "unit" "*,i387")
4751    (set_attr "fp_int_src" "true")])
4752
4753 ;; %%% Kill these when reload knows how to do it.
4754 (define_split
4755   [(set (match_operand 0 "fp_register_operand" "")
4756         (float (match_operand 1 "register_operand" "")))]
4757   "reload_completed
4758    && TARGET_80387
4759    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4760   [(const_int 0)]
4761 {
4762   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4763   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4764   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4765   ix86_free_from_memory (GET_MODE (operands[1]));
4766   DONE;
4767 })
4768
4769 (define_expand "floatunssisf2"
4770   [(use (match_operand:SF 0 "register_operand" ""))
4771    (use (match_operand:SI 1 "register_operand" ""))]
4772   "!TARGET_64BIT && TARGET_SSE_MATH"
4773   "x86_emit_floatuns (operands); DONE;")
4774
4775 (define_expand "floatunsdisf2"
4776   [(use (match_operand:SF 0 "register_operand" ""))
4777    (use (match_operand:DI 1 "register_operand" ""))]
4778   "TARGET_64BIT && TARGET_SSE_MATH"
4779   "x86_emit_floatuns (operands); DONE;")
4780
4781 (define_expand "floatunsdidf2"
4782   [(use (match_operand:DF 0 "register_operand" ""))
4783    (use (match_operand:DI 1 "register_operand" ""))]
4784   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4785   "x86_emit_floatuns (operands); DONE;")
4786 \f
4787 ;; SSE extract/set expanders
4788
4789 \f
4790 ;; Add instructions
4791
4792 ;; %%% splits for addditi3
4793
4794 (define_expand "addti3"
4795   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4796         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4797                  (match_operand:TI 2 "x86_64_general_operand" "")))
4798    (clobber (reg:CC FLAGS_REG))]
4799   "TARGET_64BIT"
4800   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4801
4802 (define_insn "*addti3_1"
4803   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4804         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4805                  (match_operand:TI 2 "general_operand" "roiF,riF")))
4806    (clobber (reg:CC FLAGS_REG))]
4807   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4808   "#")
4809
4810 (define_split
4811   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4812         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4813                  (match_operand:TI 2 "general_operand" "")))
4814    (clobber (reg:CC FLAGS_REG))]
4815   "TARGET_64BIT && reload_completed"
4816   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4817                                           UNSPEC_ADD_CARRY))
4818               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4819    (parallel [(set (match_dup 3)
4820                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4821                                      (match_dup 4))
4822                             (match_dup 5)))
4823               (clobber (reg:CC FLAGS_REG))])]
4824   "split_ti (operands+0, 1, operands+0, operands+3);
4825    split_ti (operands+1, 1, operands+1, operands+4);
4826    split_ti (operands+2, 1, operands+2, operands+5);")
4827
4828 ;; %%% splits for addsidi3
4829 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4830 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4831 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4832
4833 (define_expand "adddi3"
4834   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4835         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4836                  (match_operand:DI 2 "x86_64_general_operand" "")))
4837    (clobber (reg:CC FLAGS_REG))]
4838   ""
4839   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4840
4841 (define_insn "*adddi3_1"
4842   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4843         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4844                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4845    (clobber (reg:CC FLAGS_REG))]
4846   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4847   "#")
4848
4849 (define_split
4850   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4851         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4852                  (match_operand:DI 2 "general_operand" "")))
4853    (clobber (reg:CC FLAGS_REG))]
4854   "!TARGET_64BIT && reload_completed"
4855   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4856                                           UNSPEC_ADD_CARRY))
4857               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4858    (parallel [(set (match_dup 3)
4859                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4860                                      (match_dup 4))
4861                             (match_dup 5)))
4862               (clobber (reg:CC FLAGS_REG))])]
4863   "split_di (operands+0, 1, operands+0, operands+3);
4864    split_di (operands+1, 1, operands+1, operands+4);
4865    split_di (operands+2, 1, operands+2, operands+5);")
4866
4867 (define_insn "adddi3_carry_rex64"
4868   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4869           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4870                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4871                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4872    (clobber (reg:CC FLAGS_REG))]
4873   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4874   "adc{q}\t{%2, %0|%0, %2}"
4875   [(set_attr "type" "alu")
4876    (set_attr "pent_pair" "pu")
4877    (set_attr "mode" "DI")])
4878
4879 (define_insn "*adddi3_cc_rex64"
4880   [(set (reg:CC FLAGS_REG)
4881         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4882                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4883                    UNSPEC_ADD_CARRY))
4884    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4885         (plus:DI (match_dup 1) (match_dup 2)))]
4886   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4887   "add{q}\t{%2, %0|%0, %2}"
4888   [(set_attr "type" "alu")
4889    (set_attr "mode" "DI")])
4890
4891 (define_insn "addqi3_carry"
4892   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4893           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4894                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4895                    (match_operand:QI 2 "general_operand" "qi,qm")))
4896    (clobber (reg:CC FLAGS_REG))]
4897   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4898   "adc{b}\t{%2, %0|%0, %2}"
4899   [(set_attr "type" "alu")
4900    (set_attr "pent_pair" "pu")
4901    (set_attr "mode" "QI")])
4902
4903 (define_insn "addhi3_carry"
4904   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4905           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4906                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4907                    (match_operand:HI 2 "general_operand" "ri,rm")))
4908    (clobber (reg:CC FLAGS_REG))]
4909   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4910   "adc{w}\t{%2, %0|%0, %2}"
4911   [(set_attr "type" "alu")
4912    (set_attr "pent_pair" "pu")
4913    (set_attr "mode" "HI")])
4914
4915 (define_insn "addsi3_carry"
4916   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4917           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4918                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4919                    (match_operand:SI 2 "general_operand" "ri,rm")))
4920    (clobber (reg:CC FLAGS_REG))]
4921   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4922   "adc{l}\t{%2, %0|%0, %2}"
4923   [(set_attr "type" "alu")
4924    (set_attr "pent_pair" "pu")
4925    (set_attr "mode" "SI")])
4926
4927 (define_insn "*addsi3_carry_zext"
4928   [(set (match_operand:DI 0 "register_operand" "=r")
4929           (zero_extend:DI
4930             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4931                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4932                      (match_operand:SI 2 "general_operand" "rim"))))
4933    (clobber (reg:CC FLAGS_REG))]
4934   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4935   "adc{l}\t{%2, %k0|%k0, %2}"
4936   [(set_attr "type" "alu")
4937    (set_attr "pent_pair" "pu")
4938    (set_attr "mode" "SI")])
4939
4940 (define_insn "*addsi3_cc"
4941   [(set (reg:CC FLAGS_REG)
4942         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4943                     (match_operand:SI 2 "general_operand" "ri,rm")]
4944                    UNSPEC_ADD_CARRY))
4945    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4946         (plus:SI (match_dup 1) (match_dup 2)))]
4947   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4948   "add{l}\t{%2, %0|%0, %2}"
4949   [(set_attr "type" "alu")
4950    (set_attr "mode" "SI")])
4951
4952 (define_insn "addqi3_cc"
4953   [(set (reg:CC FLAGS_REG)
4954         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4955                     (match_operand:QI 2 "general_operand" "qi,qm")]
4956                    UNSPEC_ADD_CARRY))
4957    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4958         (plus:QI (match_dup 1) (match_dup 2)))]
4959   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4960   "add{b}\t{%2, %0|%0, %2}"
4961   [(set_attr "type" "alu")
4962    (set_attr "mode" "QI")])
4963
4964 (define_expand "addsi3"
4965   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4966                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4967                             (match_operand:SI 2 "general_operand" "")))
4968               (clobber (reg:CC FLAGS_REG))])]
4969   ""
4970   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4971
4972 (define_insn "*lea_1"
4973   [(set (match_operand:SI 0 "register_operand" "=r")
4974         (match_operand:SI 1 "no_seg_address_operand" "p"))]
4975   "!TARGET_64BIT"
4976   "lea{l}\t{%a1, %0|%0, %a1}"
4977   [(set_attr "type" "lea")
4978    (set_attr "mode" "SI")])
4979
4980 (define_insn "*lea_1_rex64"
4981   [(set (match_operand:SI 0 "register_operand" "=r")
4982         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4983   "TARGET_64BIT"
4984   "lea{l}\t{%a1, %0|%0, %a1}"
4985   [(set_attr "type" "lea")
4986    (set_attr "mode" "SI")])
4987
4988 (define_insn "*lea_1_zext"
4989   [(set (match_operand:DI 0 "register_operand" "=r")
4990         (zero_extend:DI
4991          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4992   "TARGET_64BIT"
4993   "lea{l}\t{%a1, %k0|%k0, %a1}"
4994   [(set_attr "type" "lea")
4995    (set_attr "mode" "SI")])
4996
4997 (define_insn "*lea_2_rex64"
4998   [(set (match_operand:DI 0 "register_operand" "=r")
4999         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5000   "TARGET_64BIT"
5001   "lea{q}\t{%a1, %0|%0, %a1}"
5002   [(set_attr "type" "lea")
5003    (set_attr "mode" "DI")])
5004
5005 ;; The lea patterns for non-Pmodes needs to be matched by several
5006 ;; insns converted to real lea by splitters.
5007
5008 (define_insn_and_split "*lea_general_1"
5009   [(set (match_operand 0 "register_operand" "=r")
5010         (plus (plus (match_operand 1 "index_register_operand" "l")
5011                     (match_operand 2 "register_operand" "r"))
5012               (match_operand 3 "immediate_operand" "i")))]
5013   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5014     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5015    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5016    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5017    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5018    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5019        || GET_MODE (operands[3]) == VOIDmode)"
5020   "#"
5021   "&& reload_completed"
5022   [(const_int 0)]
5023 {
5024   rtx pat;
5025   operands[0] = gen_lowpart (SImode, operands[0]);
5026   operands[1] = gen_lowpart (Pmode, operands[1]);
5027   operands[2] = gen_lowpart (Pmode, operands[2]);
5028   operands[3] = gen_lowpart (Pmode, operands[3]);
5029   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5030                       operands[3]);
5031   if (Pmode != SImode)
5032     pat = gen_rtx_SUBREG (SImode, pat, 0);
5033   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5034   DONE;
5035 }
5036   [(set_attr "type" "lea")
5037    (set_attr "mode" "SI")])
5038
5039 (define_insn_and_split "*lea_general_1_zext"
5040   [(set (match_operand:DI 0 "register_operand" "=r")
5041         (zero_extend:DI
5042           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5043                             (match_operand:SI 2 "register_operand" "r"))
5044                    (match_operand:SI 3 "immediate_operand" "i"))))]
5045   "TARGET_64BIT"
5046   "#"
5047   "&& reload_completed"
5048   [(set (match_dup 0)
5049         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5050                                                      (match_dup 2))
5051                                             (match_dup 3)) 0)))]
5052 {
5053   operands[1] = gen_lowpart (Pmode, operands[1]);
5054   operands[2] = gen_lowpart (Pmode, operands[2]);
5055   operands[3] = gen_lowpart (Pmode, operands[3]);
5056 }
5057   [(set_attr "type" "lea")
5058    (set_attr "mode" "SI")])
5059
5060 (define_insn_and_split "*lea_general_2"
5061   [(set (match_operand 0 "register_operand" "=r")
5062         (plus (mult (match_operand 1 "index_register_operand" "l")
5063                     (match_operand 2 "const248_operand" "i"))
5064               (match_operand 3 "nonmemory_operand" "ri")))]
5065   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5066     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5067    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5068    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5069    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5070        || GET_MODE (operands[3]) == VOIDmode)"
5071   "#"
5072   "&& reload_completed"
5073   [(const_int 0)]
5074 {
5075   rtx pat;
5076   operands[0] = gen_lowpart (SImode, operands[0]);
5077   operands[1] = gen_lowpart (Pmode, operands[1]);
5078   operands[3] = gen_lowpart (Pmode, operands[3]);
5079   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5080                       operands[3]);
5081   if (Pmode != SImode)
5082     pat = gen_rtx_SUBREG (SImode, pat, 0);
5083   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5084   DONE;
5085 }
5086   [(set_attr "type" "lea")
5087    (set_attr "mode" "SI")])
5088
5089 (define_insn_and_split "*lea_general_2_zext"
5090   [(set (match_operand:DI 0 "register_operand" "=r")
5091         (zero_extend:DI
5092           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5093                             (match_operand:SI 2 "const248_operand" "n"))
5094                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5095   "TARGET_64BIT"
5096   "#"
5097   "&& reload_completed"
5098   [(set (match_dup 0)
5099         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5100                                                      (match_dup 2))
5101                                             (match_dup 3)) 0)))]
5102 {
5103   operands[1] = gen_lowpart (Pmode, operands[1]);
5104   operands[3] = gen_lowpart (Pmode, operands[3]);
5105 }
5106   [(set_attr "type" "lea")
5107    (set_attr "mode" "SI")])
5108
5109 (define_insn_and_split "*lea_general_3"
5110   [(set (match_operand 0 "register_operand" "=r")
5111         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5112                           (match_operand 2 "const248_operand" "i"))
5113                     (match_operand 3 "register_operand" "r"))
5114               (match_operand 4 "immediate_operand" "i")))]
5115   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5116     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5117    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5118    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5119    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5120   "#"
5121   "&& reload_completed"
5122   [(const_int 0)]
5123 {
5124   rtx pat;
5125   operands[0] = gen_lowpart (SImode, operands[0]);
5126   operands[1] = gen_lowpart (Pmode, operands[1]);
5127   operands[3] = gen_lowpart (Pmode, operands[3]);
5128   operands[4] = gen_lowpart (Pmode, operands[4]);
5129   pat = gen_rtx_PLUS (Pmode,
5130                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5131                                                          operands[2]),
5132                                     operands[3]),
5133                       operands[4]);
5134   if (Pmode != SImode)
5135     pat = gen_rtx_SUBREG (SImode, pat, 0);
5136   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5137   DONE;
5138 }
5139   [(set_attr "type" "lea")
5140    (set_attr "mode" "SI")])
5141
5142 (define_insn_and_split "*lea_general_3_zext"
5143   [(set (match_operand:DI 0 "register_operand" "=r")
5144         (zero_extend:DI
5145           (plus:SI (plus:SI (mult:SI
5146                               (match_operand:SI 1 "index_register_operand" "l")
5147                               (match_operand:SI 2 "const248_operand" "n"))
5148                             (match_operand:SI 3 "register_operand" "r"))
5149                    (match_operand:SI 4 "immediate_operand" "i"))))]
5150   "TARGET_64BIT"
5151   "#"
5152   "&& reload_completed"
5153   [(set (match_dup 0)
5154         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5155                                                               (match_dup 2))
5156                                                      (match_dup 3))
5157                                             (match_dup 4)) 0)))]
5158 {
5159   operands[1] = gen_lowpart (Pmode, operands[1]);
5160   operands[3] = gen_lowpart (Pmode, operands[3]);
5161   operands[4] = gen_lowpart (Pmode, operands[4]);
5162 }
5163   [(set_attr "type" "lea")
5164    (set_attr "mode" "SI")])
5165
5166 (define_insn "*adddi_1_rex64"
5167   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5168         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5169                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5170    (clobber (reg:CC FLAGS_REG))]
5171   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5172 {
5173   switch (get_attr_type (insn))
5174     {
5175     case TYPE_LEA:
5176       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5177       return "lea{q}\t{%a2, %0|%0, %a2}";
5178
5179     case TYPE_INCDEC:
5180       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5181       if (operands[2] == const1_rtx)
5182         return "inc{q}\t%0";
5183       else
5184         {
5185           gcc_assert (operands[2] == constm1_rtx);
5186           return "dec{q}\t%0";
5187         }
5188
5189     default:
5190       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5191
5192       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5193          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5194       if (GET_CODE (operands[2]) == CONST_INT
5195           /* Avoid overflows.  */
5196           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5197           && (INTVAL (operands[2]) == 128
5198               || (INTVAL (operands[2]) < 0
5199                   && INTVAL (operands[2]) != -128)))
5200         {
5201           operands[2] = GEN_INT (-INTVAL (operands[2]));
5202           return "sub{q}\t{%2, %0|%0, %2}";
5203         }
5204       return "add{q}\t{%2, %0|%0, %2}";
5205     }
5206 }
5207   [(set (attr "type")
5208      (cond [(eq_attr "alternative" "2")
5209               (const_string "lea")
5210             ; Current assemblers are broken and do not allow @GOTOFF in
5211             ; ought but a memory context.
5212             (match_operand:DI 2 "pic_symbolic_operand" "")
5213               (const_string "lea")
5214             (match_operand:DI 2 "incdec_operand" "")
5215               (const_string "incdec")
5216            ]
5217            (const_string "alu")))
5218    (set_attr "mode" "DI")])
5219
5220 ;; Convert lea to the lea pattern to avoid flags dependency.
5221 (define_split
5222   [(set (match_operand:DI 0 "register_operand" "")
5223         (plus:DI (match_operand:DI 1 "register_operand" "")
5224                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5225    (clobber (reg:CC FLAGS_REG))]
5226   "TARGET_64BIT && reload_completed
5227    && true_regnum (operands[0]) != true_regnum (operands[1])"
5228   [(set (match_dup 0)
5229         (plus:DI (match_dup 1)
5230                  (match_dup 2)))]
5231   "")
5232
5233 (define_insn "*adddi_2_rex64"
5234   [(set (reg FLAGS_REG)
5235         (compare
5236           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5237                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5238           (const_int 0)))
5239    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5240         (plus:DI (match_dup 1) (match_dup 2)))]
5241   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5242    && ix86_binary_operator_ok (PLUS, DImode, operands)
5243    /* Current assemblers are broken and do not allow @GOTOFF in
5244       ought but a memory context.  */
5245    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5246 {
5247   switch (get_attr_type (insn))
5248     {
5249     case TYPE_INCDEC:
5250       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5251       if (operands[2] == const1_rtx)
5252         return "inc{q}\t%0";
5253       else
5254         {
5255           gcc_assert (operands[2] == constm1_rtx);
5256           return "dec{q}\t%0";
5257         }
5258
5259     default:
5260       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5261       /* ???? We ought to handle there the 32bit case too
5262          - do we need new constraint?  */
5263       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5264          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5265       if (GET_CODE (operands[2]) == CONST_INT
5266           /* Avoid overflows.  */
5267           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5268           && (INTVAL (operands[2]) == 128
5269               || (INTVAL (operands[2]) < 0
5270                   && INTVAL (operands[2]) != -128)))
5271         {
5272           operands[2] = GEN_INT (-INTVAL (operands[2]));
5273           return "sub{q}\t{%2, %0|%0, %2}";
5274         }
5275       return "add{q}\t{%2, %0|%0, %2}";
5276     }
5277 }
5278   [(set (attr "type")
5279      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5280         (const_string "incdec")
5281         (const_string "alu")))
5282    (set_attr "mode" "DI")])
5283
5284 (define_insn "*adddi_3_rex64"
5285   [(set (reg FLAGS_REG)
5286         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5287                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5288    (clobber (match_scratch:DI 0 "=r"))]
5289   "TARGET_64BIT
5290    && ix86_match_ccmode (insn, CCZmode)
5291    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5292    /* Current assemblers are broken and do not allow @GOTOFF in
5293       ought but a memory context.  */
5294    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5295 {
5296   switch (get_attr_type (insn))
5297     {
5298     case TYPE_INCDEC:
5299       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5300       if (operands[2] == const1_rtx)
5301         return "inc{q}\t%0";
5302       else
5303         {
5304           gcc_assert (operands[2] == constm1_rtx);
5305           return "dec{q}\t%0";
5306         }
5307
5308     default:
5309       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5310       /* ???? We ought to handle there the 32bit case too
5311          - do we need new constraint?  */
5312       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5313          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5314       if (GET_CODE (operands[2]) == CONST_INT
5315           /* Avoid overflows.  */
5316           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5317           && (INTVAL (operands[2]) == 128
5318               || (INTVAL (operands[2]) < 0
5319                   && INTVAL (operands[2]) != -128)))
5320         {
5321           operands[2] = GEN_INT (-INTVAL (operands[2]));
5322           return "sub{q}\t{%2, %0|%0, %2}";
5323         }
5324       return "add{q}\t{%2, %0|%0, %2}";
5325     }
5326 }
5327   [(set (attr "type")
5328      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5329         (const_string "incdec")
5330         (const_string "alu")))
5331    (set_attr "mode" "DI")])
5332
5333 ; For comparisons against 1, -1 and 128, we may generate better code
5334 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5335 ; is matched then.  We can't accept general immediate, because for
5336 ; case of overflows,  the result is messed up.
5337 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5338 ; when negated.
5339 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5340 ; only for comparisons not depending on it.
5341 (define_insn "*adddi_4_rex64"
5342   [(set (reg FLAGS_REG)
5343         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5344                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5345    (clobber (match_scratch:DI 0 "=rm"))]
5346   "TARGET_64BIT
5347    &&  ix86_match_ccmode (insn, CCGCmode)"
5348 {
5349   switch (get_attr_type (insn))
5350     {
5351     case TYPE_INCDEC:
5352       if (operands[2] == constm1_rtx)
5353         return "inc{q}\t%0";
5354       else
5355         {
5356           gcc_assert (operands[2] == const1_rtx);
5357           return "dec{q}\t%0";
5358         }
5359
5360     default:
5361       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5362       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5363          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5364       if ((INTVAL (operands[2]) == -128
5365            || (INTVAL (operands[2]) > 0
5366                && INTVAL (operands[2]) != 128))
5367           /* Avoid overflows.  */
5368           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5369         return "sub{q}\t{%2, %0|%0, %2}";
5370       operands[2] = GEN_INT (-INTVAL (operands[2]));
5371       return "add{q}\t{%2, %0|%0, %2}";
5372     }
5373 }
5374   [(set (attr "type")
5375      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5376         (const_string "incdec")
5377         (const_string "alu")))
5378    (set_attr "mode" "DI")])
5379
5380 (define_insn "*adddi_5_rex64"
5381   [(set (reg FLAGS_REG)
5382         (compare
5383           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5384                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5385           (const_int 0)))
5386    (clobber (match_scratch:DI 0 "=r"))]
5387   "TARGET_64BIT
5388    && ix86_match_ccmode (insn, CCGOCmode)
5389    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5390    /* Current assemblers are broken and do not allow @GOTOFF in
5391       ought but a memory context.  */
5392    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5393 {
5394   switch (get_attr_type (insn))
5395     {
5396     case TYPE_INCDEC:
5397       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5398       if (operands[2] == const1_rtx)
5399         return "inc{q}\t%0";
5400       else
5401         {
5402           gcc_assert (operands[2] == constm1_rtx);
5403           return "dec{q}\t%0";
5404         }
5405
5406     default:
5407       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5408       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5409          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5410       if (GET_CODE (operands[2]) == CONST_INT
5411           /* Avoid overflows.  */
5412           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5413           && (INTVAL (operands[2]) == 128
5414               || (INTVAL (operands[2]) < 0
5415                   && INTVAL (operands[2]) != -128)))
5416         {
5417           operands[2] = GEN_INT (-INTVAL (operands[2]));
5418           return "sub{q}\t{%2, %0|%0, %2}";
5419         }
5420       return "add{q}\t{%2, %0|%0, %2}";
5421     }
5422 }
5423   [(set (attr "type")
5424      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5425         (const_string "incdec")
5426         (const_string "alu")))
5427    (set_attr "mode" "DI")])
5428
5429
5430 (define_insn "*addsi_1"
5431   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5432         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5433                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5434    (clobber (reg:CC FLAGS_REG))]
5435   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5436 {
5437   switch (get_attr_type (insn))
5438     {
5439     case TYPE_LEA:
5440       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5441       return "lea{l}\t{%a2, %0|%0, %a2}";
5442
5443     case TYPE_INCDEC:
5444       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5445       if (operands[2] == const1_rtx)
5446         return "inc{l}\t%0";
5447       else
5448         {
5449           gcc_assert (operands[2] == constm1_rtx);
5450           return "dec{l}\t%0";
5451         }
5452
5453     default:
5454       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5455
5456       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5457          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5458       if (GET_CODE (operands[2]) == CONST_INT
5459           && (INTVAL (operands[2]) == 128
5460               || (INTVAL (operands[2]) < 0
5461                   && INTVAL (operands[2]) != -128)))
5462         {
5463           operands[2] = GEN_INT (-INTVAL (operands[2]));
5464           return "sub{l}\t{%2, %0|%0, %2}";
5465         }
5466       return "add{l}\t{%2, %0|%0, %2}";
5467     }
5468 }
5469   [(set (attr "type")
5470      (cond [(eq_attr "alternative" "2")
5471               (const_string "lea")
5472             ; Current assemblers are broken and do not allow @GOTOFF in
5473             ; ought but a memory context.
5474             (match_operand:SI 2 "pic_symbolic_operand" "")
5475               (const_string "lea")
5476             (match_operand:SI 2 "incdec_operand" "")
5477               (const_string "incdec")
5478            ]
5479            (const_string "alu")))
5480    (set_attr "mode" "SI")])
5481
5482 ;; Convert lea to the lea pattern to avoid flags dependency.
5483 (define_split
5484   [(set (match_operand 0 "register_operand" "")
5485         (plus (match_operand 1 "register_operand" "")
5486               (match_operand 2 "nonmemory_operand" "")))
5487    (clobber (reg:CC FLAGS_REG))]
5488   "reload_completed
5489    && true_regnum (operands[0]) != true_regnum (operands[1])"
5490   [(const_int 0)]
5491 {
5492   rtx pat;
5493   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5494      may confuse gen_lowpart.  */
5495   if (GET_MODE (operands[0]) != Pmode)
5496     {
5497       operands[1] = gen_lowpart (Pmode, operands[1]);
5498       operands[2] = gen_lowpart (Pmode, operands[2]);
5499     }
5500   operands[0] = gen_lowpart (SImode, operands[0]);
5501   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5502   if (Pmode != SImode)
5503     pat = gen_rtx_SUBREG (SImode, pat, 0);
5504   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5505   DONE;
5506 })
5507
5508 ;; It may seem that nonimmediate operand is proper one for operand 1.
5509 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5510 ;; we take care in ix86_binary_operator_ok to not allow two memory
5511 ;; operands so proper swapping will be done in reload.  This allow
5512 ;; patterns constructed from addsi_1 to match.
5513 (define_insn "addsi_1_zext"
5514   [(set (match_operand:DI 0 "register_operand" "=r,r")
5515         (zero_extend:DI
5516           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5517                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5518    (clobber (reg:CC FLAGS_REG))]
5519   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5520 {
5521   switch (get_attr_type (insn))
5522     {
5523     case TYPE_LEA:
5524       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5525       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5526
5527     case TYPE_INCDEC:
5528       if (operands[2] == const1_rtx)
5529         return "inc{l}\t%k0";
5530       else
5531         {
5532           gcc_assert (operands[2] == constm1_rtx);
5533           return "dec{l}\t%k0";
5534         }
5535
5536     default:
5537       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5538          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5539       if (GET_CODE (operands[2]) == CONST_INT
5540           && (INTVAL (operands[2]) == 128
5541               || (INTVAL (operands[2]) < 0
5542                   && INTVAL (operands[2]) != -128)))
5543         {
5544           operands[2] = GEN_INT (-INTVAL (operands[2]));
5545           return "sub{l}\t{%2, %k0|%k0, %2}";
5546         }
5547       return "add{l}\t{%2, %k0|%k0, %2}";
5548     }
5549 }
5550   [(set (attr "type")
5551      (cond [(eq_attr "alternative" "1")
5552               (const_string "lea")
5553             ; Current assemblers are broken and do not allow @GOTOFF in
5554             ; ought but a memory context.
5555             (match_operand:SI 2 "pic_symbolic_operand" "")
5556               (const_string "lea")
5557             (match_operand:SI 2 "incdec_operand" "")
5558               (const_string "incdec")
5559            ]
5560            (const_string "alu")))
5561    (set_attr "mode" "SI")])
5562
5563 ;; Convert lea to the lea pattern to avoid flags dependency.
5564 (define_split
5565   [(set (match_operand:DI 0 "register_operand" "")
5566         (zero_extend:DI
5567           (plus:SI (match_operand:SI 1 "register_operand" "")
5568                    (match_operand:SI 2 "nonmemory_operand" ""))))
5569    (clobber (reg:CC FLAGS_REG))]
5570   "TARGET_64BIT && reload_completed
5571    && true_regnum (operands[0]) != true_regnum (operands[1])"
5572   [(set (match_dup 0)
5573         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5574 {
5575   operands[1] = gen_lowpart (Pmode, operands[1]);
5576   operands[2] = gen_lowpart (Pmode, operands[2]);
5577 })
5578
5579 (define_insn "*addsi_2"
5580   [(set (reg FLAGS_REG)
5581         (compare
5582           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5583                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5584           (const_int 0)))
5585    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5586         (plus:SI (match_dup 1) (match_dup 2)))]
5587   "ix86_match_ccmode (insn, CCGOCmode)
5588    && ix86_binary_operator_ok (PLUS, SImode, operands)
5589    /* Current assemblers are broken and do not allow @GOTOFF in
5590       ought but a memory context.  */
5591    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5592 {
5593   switch (get_attr_type (insn))
5594     {
5595     case TYPE_INCDEC:
5596       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5597       if (operands[2] == const1_rtx)
5598         return "inc{l}\t%0";
5599       else
5600         {
5601           gcc_assert (operands[2] == constm1_rtx);
5602           return "dec{l}\t%0";
5603         }
5604
5605     default:
5606       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5607       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5608          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5609       if (GET_CODE (operands[2]) == CONST_INT
5610           && (INTVAL (operands[2]) == 128
5611               || (INTVAL (operands[2]) < 0
5612                   && INTVAL (operands[2]) != -128)))
5613         {
5614           operands[2] = GEN_INT (-INTVAL (operands[2]));
5615           return "sub{l}\t{%2, %0|%0, %2}";
5616         }
5617       return "add{l}\t{%2, %0|%0, %2}";
5618     }
5619 }
5620   [(set (attr "type")
5621      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5622         (const_string "incdec")
5623         (const_string "alu")))
5624    (set_attr "mode" "SI")])
5625
5626 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5627 (define_insn "*addsi_2_zext"
5628   [(set (reg FLAGS_REG)
5629         (compare
5630           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5631                    (match_operand:SI 2 "general_operand" "rmni"))
5632           (const_int 0)))
5633    (set (match_operand:DI 0 "register_operand" "=r")
5634         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5635   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5636    && ix86_binary_operator_ok (PLUS, SImode, operands)
5637    /* Current assemblers are broken and do not allow @GOTOFF in
5638       ought but a memory context.  */
5639    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5640 {
5641   switch (get_attr_type (insn))
5642     {
5643     case TYPE_INCDEC:
5644       if (operands[2] == const1_rtx)
5645         return "inc{l}\t%k0";
5646       else
5647         {
5648           gcc_assert (operands[2] == constm1_rtx);
5649           return "dec{l}\t%k0";
5650         }
5651
5652     default:
5653       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5654          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5655       if (GET_CODE (operands[2]) == CONST_INT
5656           && (INTVAL (operands[2]) == 128
5657               || (INTVAL (operands[2]) < 0
5658                   && INTVAL (operands[2]) != -128)))
5659         {
5660           operands[2] = GEN_INT (-INTVAL (operands[2]));
5661           return "sub{l}\t{%2, %k0|%k0, %2}";
5662         }
5663       return "add{l}\t{%2, %k0|%k0, %2}";
5664     }
5665 }
5666   [(set (attr "type")
5667      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5668         (const_string "incdec")
5669         (const_string "alu")))
5670    (set_attr "mode" "SI")])
5671
5672 (define_insn "*addsi_3"
5673   [(set (reg FLAGS_REG)
5674         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5675                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5676    (clobber (match_scratch:SI 0 "=r"))]
5677   "ix86_match_ccmode (insn, CCZmode)
5678    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5679    /* Current assemblers are broken and do not allow @GOTOFF in
5680       ought but a memory context.  */
5681    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5682 {
5683   switch (get_attr_type (insn))
5684     {
5685     case TYPE_INCDEC:
5686       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5687       if (operands[2] == const1_rtx)
5688         return "inc{l}\t%0";
5689       else
5690         {
5691           gcc_assert (operands[2] == constm1_rtx);
5692           return "dec{l}\t%0";
5693         }
5694
5695     default:
5696       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5697       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5698          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5699       if (GET_CODE (operands[2]) == CONST_INT
5700           && (INTVAL (operands[2]) == 128
5701               || (INTVAL (operands[2]) < 0
5702                   && INTVAL (operands[2]) != -128)))
5703         {
5704           operands[2] = GEN_INT (-INTVAL (operands[2]));
5705           return "sub{l}\t{%2, %0|%0, %2}";
5706         }
5707       return "add{l}\t{%2, %0|%0, %2}";
5708     }
5709 }
5710   [(set (attr "type")
5711      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5712         (const_string "incdec")
5713         (const_string "alu")))
5714    (set_attr "mode" "SI")])
5715
5716 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5717 (define_insn "*addsi_3_zext"
5718   [(set (reg FLAGS_REG)
5719         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5720                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5721    (set (match_operand:DI 0 "register_operand" "=r")
5722         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5723   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5724    && ix86_binary_operator_ok (PLUS, SImode, operands)
5725    /* Current assemblers are broken and do not allow @GOTOFF in
5726       ought but a memory context.  */
5727    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5728 {
5729   switch (get_attr_type (insn))
5730     {
5731     case TYPE_INCDEC:
5732       if (operands[2] == const1_rtx)
5733         return "inc{l}\t%k0";
5734       else
5735         {
5736           gcc_assert (operands[2] == constm1_rtx);
5737           return "dec{l}\t%k0";
5738         }
5739
5740     default:
5741       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5742          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5743       if (GET_CODE (operands[2]) == CONST_INT
5744           && (INTVAL (operands[2]) == 128
5745               || (INTVAL (operands[2]) < 0
5746                   && INTVAL (operands[2]) != -128)))
5747         {
5748           operands[2] = GEN_INT (-INTVAL (operands[2]));
5749           return "sub{l}\t{%2, %k0|%k0, %2}";
5750         }
5751       return "add{l}\t{%2, %k0|%k0, %2}";
5752     }
5753 }
5754   [(set (attr "type")
5755      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5756         (const_string "incdec")
5757         (const_string "alu")))
5758    (set_attr "mode" "SI")])
5759
5760 ; For comparisons against 1, -1 and 128, we may generate better code
5761 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5762 ; is matched then.  We can't accept general immediate, because for
5763 ; case of overflows,  the result is messed up.
5764 ; This pattern also don't hold of 0x80000000, since the value overflows
5765 ; when negated.
5766 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5767 ; only for comparisons not depending on it.
5768 (define_insn "*addsi_4"
5769   [(set (reg FLAGS_REG)
5770         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5771                  (match_operand:SI 2 "const_int_operand" "n")))
5772    (clobber (match_scratch:SI 0 "=rm"))]
5773   "ix86_match_ccmode (insn, CCGCmode)
5774    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5775 {
5776   switch (get_attr_type (insn))
5777     {
5778     case TYPE_INCDEC:
5779       if (operands[2] == constm1_rtx)
5780         return "inc{l}\t%0";
5781       else
5782         {
5783           gcc_assert (operands[2] == const1_rtx);
5784           return "dec{l}\t%0";
5785         }
5786
5787     default:
5788       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5789       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5790          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5791       if ((INTVAL (operands[2]) == -128
5792            || (INTVAL (operands[2]) > 0
5793                && INTVAL (operands[2]) != 128)))
5794         return "sub{l}\t{%2, %0|%0, %2}";
5795       operands[2] = GEN_INT (-INTVAL (operands[2]));
5796       return "add{l}\t{%2, %0|%0, %2}";
5797     }
5798 }
5799   [(set (attr "type")
5800      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5801         (const_string "incdec")
5802         (const_string "alu")))
5803    (set_attr "mode" "SI")])
5804
5805 (define_insn "*addsi_5"
5806   [(set (reg FLAGS_REG)
5807         (compare
5808           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5809                    (match_operand:SI 2 "general_operand" "rmni"))
5810           (const_int 0)))
5811    (clobber (match_scratch:SI 0 "=r"))]
5812   "ix86_match_ccmode (insn, CCGOCmode)
5813    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5814    /* Current assemblers are broken and do not allow @GOTOFF in
5815       ought but a memory context.  */
5816    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5817 {
5818   switch (get_attr_type (insn))
5819     {
5820     case TYPE_INCDEC:
5821       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5822       if (operands[2] == const1_rtx)
5823         return "inc{l}\t%0";
5824       else
5825         {
5826           gcc_assert (operands[2] == constm1_rtx);
5827           return "dec{l}\t%0";
5828         }
5829
5830     default:
5831       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5832       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5833          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5834       if (GET_CODE (operands[2]) == CONST_INT
5835           && (INTVAL (operands[2]) == 128
5836               || (INTVAL (operands[2]) < 0
5837                   && INTVAL (operands[2]) != -128)))
5838         {
5839           operands[2] = GEN_INT (-INTVAL (operands[2]));
5840           return "sub{l}\t{%2, %0|%0, %2}";
5841         }
5842       return "add{l}\t{%2, %0|%0, %2}";
5843     }
5844 }
5845   [(set (attr "type")
5846      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5847         (const_string "incdec")
5848         (const_string "alu")))
5849    (set_attr "mode" "SI")])
5850
5851 (define_expand "addhi3"
5852   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5853                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5854                             (match_operand:HI 2 "general_operand" "")))
5855               (clobber (reg:CC FLAGS_REG))])]
5856   "TARGET_HIMODE_MATH"
5857   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5858
5859 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5860 ;; type optimizations enabled by define-splits.  This is not important
5861 ;; for PII, and in fact harmful because of partial register stalls.
5862
5863 (define_insn "*addhi_1_lea"
5864   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5865         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5866                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5867    (clobber (reg:CC FLAGS_REG))]
5868   "!TARGET_PARTIAL_REG_STALL
5869    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5870 {
5871   switch (get_attr_type (insn))
5872     {
5873     case TYPE_LEA:
5874       return "#";
5875     case TYPE_INCDEC:
5876       if (operands[2] == const1_rtx)
5877         return "inc{w}\t%0";
5878       else
5879         {
5880           gcc_assert (operands[2] == constm1_rtx);
5881           return "dec{w}\t%0";
5882         }
5883
5884     default:
5885       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5886          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5887       if (GET_CODE (operands[2]) == CONST_INT
5888           && (INTVAL (operands[2]) == 128
5889               || (INTVAL (operands[2]) < 0
5890                   && INTVAL (operands[2]) != -128)))
5891         {
5892           operands[2] = GEN_INT (-INTVAL (operands[2]));
5893           return "sub{w}\t{%2, %0|%0, %2}";
5894         }
5895       return "add{w}\t{%2, %0|%0, %2}";
5896     }
5897 }
5898   [(set (attr "type")
5899      (if_then_else (eq_attr "alternative" "2")
5900         (const_string "lea")
5901         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5902            (const_string "incdec")
5903            (const_string "alu"))))
5904    (set_attr "mode" "HI,HI,SI")])
5905
5906 (define_insn "*addhi_1"
5907   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5908         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5909                  (match_operand:HI 2 "general_operand" "ri,rm")))
5910    (clobber (reg:CC FLAGS_REG))]
5911   "TARGET_PARTIAL_REG_STALL
5912    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5913 {
5914   switch (get_attr_type (insn))
5915     {
5916     case TYPE_INCDEC:
5917       if (operands[2] == const1_rtx)
5918         return "inc{w}\t%0";
5919       else
5920         {
5921           gcc_assert (operands[2] == constm1_rtx);
5922           return "dec{w}\t%0";
5923         }
5924
5925     default:
5926       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5927          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5928       if (GET_CODE (operands[2]) == CONST_INT
5929           && (INTVAL (operands[2]) == 128
5930               || (INTVAL (operands[2]) < 0
5931                   && INTVAL (operands[2]) != -128)))
5932         {
5933           operands[2] = GEN_INT (-INTVAL (operands[2]));
5934           return "sub{w}\t{%2, %0|%0, %2}";
5935         }
5936       return "add{w}\t{%2, %0|%0, %2}";
5937     }
5938 }
5939   [(set (attr "type")
5940      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5941         (const_string "incdec")
5942         (const_string "alu")))
5943    (set_attr "mode" "HI")])
5944
5945 (define_insn "*addhi_2"
5946   [(set (reg FLAGS_REG)
5947         (compare
5948           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5949                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5950           (const_int 0)))
5951    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5952         (plus:HI (match_dup 1) (match_dup 2)))]
5953   "ix86_match_ccmode (insn, CCGOCmode)
5954    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5955 {
5956   switch (get_attr_type (insn))
5957     {
5958     case TYPE_INCDEC:
5959       if (operands[2] == const1_rtx)
5960         return "inc{w}\t%0";
5961       else
5962         {
5963           gcc_assert (operands[2] == constm1_rtx);
5964           return "dec{w}\t%0";
5965         }
5966
5967     default:
5968       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5969          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5970       if (GET_CODE (operands[2]) == CONST_INT
5971           && (INTVAL (operands[2]) == 128
5972               || (INTVAL (operands[2]) < 0
5973                   && INTVAL (operands[2]) != -128)))
5974         {
5975           operands[2] = GEN_INT (-INTVAL (operands[2]));
5976           return "sub{w}\t{%2, %0|%0, %2}";
5977         }
5978       return "add{w}\t{%2, %0|%0, %2}";
5979     }
5980 }
5981   [(set (attr "type")
5982      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5983         (const_string "incdec")
5984         (const_string "alu")))
5985    (set_attr "mode" "HI")])
5986
5987 (define_insn "*addhi_3"
5988   [(set (reg FLAGS_REG)
5989         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5990                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
5991    (clobber (match_scratch:HI 0 "=r"))]
5992   "ix86_match_ccmode (insn, CCZmode)
5993    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5994 {
5995   switch (get_attr_type (insn))
5996     {
5997     case TYPE_INCDEC:
5998       if (operands[2] == const1_rtx)
5999         return "inc{w}\t%0";
6000       else
6001         {
6002           gcc_assert (operands[2] == constm1_rtx);
6003           return "dec{w}\t%0";
6004         }
6005
6006     default:
6007       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6008          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6009       if (GET_CODE (operands[2]) == CONST_INT
6010           && (INTVAL (operands[2]) == 128
6011               || (INTVAL (operands[2]) < 0
6012                   && INTVAL (operands[2]) != -128)))
6013         {
6014           operands[2] = GEN_INT (-INTVAL (operands[2]));
6015           return "sub{w}\t{%2, %0|%0, %2}";
6016         }
6017       return "add{w}\t{%2, %0|%0, %2}";
6018     }
6019 }
6020   [(set (attr "type")
6021      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6022         (const_string "incdec")
6023         (const_string "alu")))
6024    (set_attr "mode" "HI")])
6025
6026 ; See comments above addsi_4 for details.
6027 (define_insn "*addhi_4"
6028   [(set (reg FLAGS_REG)
6029         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6030                  (match_operand:HI 2 "const_int_operand" "n")))
6031    (clobber (match_scratch:HI 0 "=rm"))]
6032   "ix86_match_ccmode (insn, CCGCmode)
6033    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6034 {
6035   switch (get_attr_type (insn))
6036     {
6037     case TYPE_INCDEC:
6038       if (operands[2] == constm1_rtx)
6039         return "inc{w}\t%0";
6040       else
6041         {
6042           gcc_assert (operands[2] == const1_rtx);
6043           return "dec{w}\t%0";
6044         }
6045
6046     default:
6047       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6048       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6049          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6050       if ((INTVAL (operands[2]) == -128
6051            || (INTVAL (operands[2]) > 0
6052                && INTVAL (operands[2]) != 128)))
6053         return "sub{w}\t{%2, %0|%0, %2}";
6054       operands[2] = GEN_INT (-INTVAL (operands[2]));
6055       return "add{w}\t{%2, %0|%0, %2}";
6056     }
6057 }
6058   [(set (attr "type")
6059      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6060         (const_string "incdec")
6061         (const_string "alu")))
6062    (set_attr "mode" "SI")])
6063
6064
6065 (define_insn "*addhi_5"
6066   [(set (reg FLAGS_REG)
6067         (compare
6068           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6069                    (match_operand:HI 2 "general_operand" "rmni"))
6070           (const_int 0)))
6071    (clobber (match_scratch:HI 0 "=r"))]
6072   "ix86_match_ccmode (insn, CCGOCmode)
6073    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6074 {
6075   switch (get_attr_type (insn))
6076     {
6077     case TYPE_INCDEC:
6078       if (operands[2] == const1_rtx)
6079         return "inc{w}\t%0";
6080       else
6081         {
6082           gcc_assert (operands[2] == constm1_rtx);
6083           return "dec{w}\t%0";
6084         }
6085
6086     default:
6087       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6088          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6089       if (GET_CODE (operands[2]) == CONST_INT
6090           && (INTVAL (operands[2]) == 128
6091               || (INTVAL (operands[2]) < 0
6092                   && INTVAL (operands[2]) != -128)))
6093         {
6094           operands[2] = GEN_INT (-INTVAL (operands[2]));
6095           return "sub{w}\t{%2, %0|%0, %2}";
6096         }
6097       return "add{w}\t{%2, %0|%0, %2}";
6098     }
6099 }
6100   [(set (attr "type")
6101      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6102         (const_string "incdec")
6103         (const_string "alu")))
6104    (set_attr "mode" "HI")])
6105
6106 (define_expand "addqi3"
6107   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6108                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6109                             (match_operand:QI 2 "general_operand" "")))
6110               (clobber (reg:CC FLAGS_REG))])]
6111   "TARGET_QIMODE_MATH"
6112   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6113
6114 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6115 (define_insn "*addqi_1_lea"
6116   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6117         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6118                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6119    (clobber (reg:CC FLAGS_REG))]
6120   "!TARGET_PARTIAL_REG_STALL
6121    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6122 {
6123   int widen = (which_alternative == 2);
6124   switch (get_attr_type (insn))
6125     {
6126     case TYPE_LEA:
6127       return "#";
6128     case TYPE_INCDEC:
6129       if (operands[2] == const1_rtx)
6130         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6131       else
6132         {
6133           gcc_assert (operands[2] == constm1_rtx);
6134           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6135         }
6136
6137     default:
6138       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6139          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6140       if (GET_CODE (operands[2]) == CONST_INT
6141           && (INTVAL (operands[2]) == 128
6142               || (INTVAL (operands[2]) < 0
6143                   && INTVAL (operands[2]) != -128)))
6144         {
6145           operands[2] = GEN_INT (-INTVAL (operands[2]));
6146           if (widen)
6147             return "sub{l}\t{%2, %k0|%k0, %2}";
6148           else
6149             return "sub{b}\t{%2, %0|%0, %2}";
6150         }
6151       if (widen)
6152         return "add{l}\t{%k2, %k0|%k0, %k2}";
6153       else
6154         return "add{b}\t{%2, %0|%0, %2}";
6155     }
6156 }
6157   [(set (attr "type")
6158      (if_then_else (eq_attr "alternative" "3")
6159         (const_string "lea")
6160         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6161            (const_string "incdec")
6162            (const_string "alu"))))
6163    (set_attr "mode" "QI,QI,SI,SI")])
6164
6165 (define_insn "*addqi_1"
6166   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6167         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6168                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6169    (clobber (reg:CC FLAGS_REG))]
6170   "TARGET_PARTIAL_REG_STALL
6171    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6172 {
6173   int widen = (which_alternative == 2);
6174   switch (get_attr_type (insn))
6175     {
6176     case TYPE_INCDEC:
6177       if (operands[2] == const1_rtx)
6178         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6179       else
6180         {
6181           gcc_assert (operands[2] == constm1_rtx);
6182           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6183         }
6184
6185     default:
6186       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6187          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6188       if (GET_CODE (operands[2]) == CONST_INT
6189           && (INTVAL (operands[2]) == 128
6190               || (INTVAL (operands[2]) < 0
6191                   && INTVAL (operands[2]) != -128)))
6192         {
6193           operands[2] = GEN_INT (-INTVAL (operands[2]));
6194           if (widen)
6195             return "sub{l}\t{%2, %k0|%k0, %2}";
6196           else
6197             return "sub{b}\t{%2, %0|%0, %2}";
6198         }
6199       if (widen)
6200         return "add{l}\t{%k2, %k0|%k0, %k2}";
6201       else
6202         return "add{b}\t{%2, %0|%0, %2}";
6203     }
6204 }
6205   [(set (attr "type")
6206      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6207         (const_string "incdec")
6208         (const_string "alu")))
6209    (set_attr "mode" "QI,QI,SI")])
6210
6211 (define_insn "*addqi_1_slp"
6212   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6213         (plus:QI (match_dup 0)
6214                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6215    (clobber (reg:CC FLAGS_REG))]
6216   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6217    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6218 {
6219   switch (get_attr_type (insn))
6220     {
6221     case TYPE_INCDEC:
6222       if (operands[1] == const1_rtx)
6223         return "inc{b}\t%0";
6224       else
6225         {
6226           gcc_assert (operands[1] == constm1_rtx);
6227           return "dec{b}\t%0";
6228         }
6229
6230     default:
6231       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6232       if (GET_CODE (operands[1]) == CONST_INT
6233           && INTVAL (operands[1]) < 0)
6234         {
6235           operands[1] = GEN_INT (-INTVAL (operands[1]));
6236           return "sub{b}\t{%1, %0|%0, %1}";
6237         }
6238       return "add{b}\t{%1, %0|%0, %1}";
6239     }
6240 }
6241   [(set (attr "type")
6242      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6243         (const_string "incdec")
6244         (const_string "alu1")))
6245    (set (attr "memory")
6246      (if_then_else (match_operand 1 "memory_operand" "")
6247         (const_string "load")
6248         (const_string "none")))
6249    (set_attr "mode" "QI")])
6250
6251 (define_insn "*addqi_2"
6252   [(set (reg FLAGS_REG)
6253         (compare
6254           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6255                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6256           (const_int 0)))
6257    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6258         (plus:QI (match_dup 1) (match_dup 2)))]
6259   "ix86_match_ccmode (insn, CCGOCmode)
6260    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6261 {
6262   switch (get_attr_type (insn))
6263     {
6264     case TYPE_INCDEC:
6265       if (operands[2] == const1_rtx)
6266         return "inc{b}\t%0";
6267       else
6268         {
6269           gcc_assert (operands[2] == constm1_rtx
6270                       || (GET_CODE (operands[2]) == CONST_INT
6271                           && INTVAL (operands[2]) == 255));
6272           return "dec{b}\t%0";
6273         }
6274
6275     default:
6276       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6277       if (GET_CODE (operands[2]) == CONST_INT
6278           && INTVAL (operands[2]) < 0)
6279         {
6280           operands[2] = GEN_INT (-INTVAL (operands[2]));
6281           return "sub{b}\t{%2, %0|%0, %2}";
6282         }
6283       return "add{b}\t{%2, %0|%0, %2}";
6284     }
6285 }
6286   [(set (attr "type")
6287      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6288         (const_string "incdec")
6289         (const_string "alu")))
6290    (set_attr "mode" "QI")])
6291
6292 (define_insn "*addqi_3"
6293   [(set (reg FLAGS_REG)
6294         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6295                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6296    (clobber (match_scratch:QI 0 "=q"))]
6297   "ix86_match_ccmode (insn, CCZmode)
6298    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6299 {
6300   switch (get_attr_type (insn))
6301     {
6302     case TYPE_INCDEC:
6303       if (operands[2] == const1_rtx)
6304         return "inc{b}\t%0";
6305       else
6306         {
6307           gcc_assert (operands[2] == constm1_rtx
6308                       || (GET_CODE (operands[2]) == CONST_INT
6309                           && INTVAL (operands[2]) == 255));
6310           return "dec{b}\t%0";
6311         }
6312
6313     default:
6314       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6315       if (GET_CODE (operands[2]) == CONST_INT
6316           && INTVAL (operands[2]) < 0)
6317         {
6318           operands[2] = GEN_INT (-INTVAL (operands[2]));
6319           return "sub{b}\t{%2, %0|%0, %2}";
6320         }
6321       return "add{b}\t{%2, %0|%0, %2}";
6322     }
6323 }
6324   [(set (attr "type")
6325      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6326         (const_string "incdec")
6327         (const_string "alu")))
6328    (set_attr "mode" "QI")])
6329
6330 ; See comments above addsi_4 for details.
6331 (define_insn "*addqi_4"
6332   [(set (reg FLAGS_REG)
6333         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6334                  (match_operand:QI 2 "const_int_operand" "n")))
6335    (clobber (match_scratch:QI 0 "=qm"))]
6336   "ix86_match_ccmode (insn, CCGCmode)
6337    && (INTVAL (operands[2]) & 0xff) != 0x80"
6338 {
6339   switch (get_attr_type (insn))
6340     {
6341     case TYPE_INCDEC:
6342       if (operands[2] == constm1_rtx
6343           || (GET_CODE (operands[2]) == CONST_INT
6344               && INTVAL (operands[2]) == 255))
6345         return "inc{b}\t%0";
6346       else
6347         {
6348           gcc_assert (operands[2] == const1_rtx);
6349           return "dec{b}\t%0";
6350         }
6351
6352     default:
6353       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6354       if (INTVAL (operands[2]) < 0)
6355         {
6356           operands[2] = GEN_INT (-INTVAL (operands[2]));
6357           return "add{b}\t{%2, %0|%0, %2}";
6358         }
6359       return "sub{b}\t{%2, %0|%0, %2}";
6360     }
6361 }
6362   [(set (attr "type")
6363      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6364         (const_string "incdec")
6365         (const_string "alu")))
6366    (set_attr "mode" "QI")])
6367
6368
6369 (define_insn "*addqi_5"
6370   [(set (reg FLAGS_REG)
6371         (compare
6372           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6373                    (match_operand:QI 2 "general_operand" "qmni"))
6374           (const_int 0)))
6375    (clobber (match_scratch:QI 0 "=q"))]
6376   "ix86_match_ccmode (insn, CCGOCmode)
6377    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6378 {
6379   switch (get_attr_type (insn))
6380     {
6381     case TYPE_INCDEC:
6382       if (operands[2] == const1_rtx)
6383         return "inc{b}\t%0";
6384       else
6385         {
6386           gcc_assert (operands[2] == constm1_rtx
6387                       || (GET_CODE (operands[2]) == CONST_INT
6388                           && INTVAL (operands[2]) == 255));
6389           return "dec{b}\t%0";
6390         }
6391
6392     default:
6393       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6394       if (GET_CODE (operands[2]) == CONST_INT
6395           && INTVAL (operands[2]) < 0)
6396         {
6397           operands[2] = GEN_INT (-INTVAL (operands[2]));
6398           return "sub{b}\t{%2, %0|%0, %2}";
6399         }
6400       return "add{b}\t{%2, %0|%0, %2}";
6401     }
6402 }
6403   [(set (attr "type")
6404      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6405         (const_string "incdec")
6406         (const_string "alu")))
6407    (set_attr "mode" "QI")])
6408
6409
6410 (define_insn "addqi_ext_1"
6411   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6412                          (const_int 8)
6413                          (const_int 8))
6414         (plus:SI
6415           (zero_extract:SI
6416             (match_operand 1 "ext_register_operand" "0")
6417             (const_int 8)
6418             (const_int 8))
6419           (match_operand:QI 2 "general_operand" "Qmn")))
6420    (clobber (reg:CC FLAGS_REG))]
6421   "!TARGET_64BIT"
6422 {
6423   switch (get_attr_type (insn))
6424     {
6425     case TYPE_INCDEC:
6426       if (operands[2] == const1_rtx)
6427         return "inc{b}\t%h0";
6428       else
6429         {
6430           gcc_assert (operands[2] == constm1_rtx
6431                       || (GET_CODE (operands[2]) == CONST_INT
6432                           && INTVAL (operands[2]) == 255));
6433           return "dec{b}\t%h0";
6434         }
6435
6436     default:
6437       return "add{b}\t{%2, %h0|%h0, %2}";
6438     }
6439 }
6440   [(set (attr "type")
6441      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6442         (const_string "incdec")
6443         (const_string "alu")))
6444    (set_attr "mode" "QI")])
6445
6446 (define_insn "*addqi_ext_1_rex64"
6447   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6448                          (const_int 8)
6449                          (const_int 8))
6450         (plus:SI
6451           (zero_extract:SI
6452             (match_operand 1 "ext_register_operand" "0")
6453             (const_int 8)
6454             (const_int 8))
6455           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6456    (clobber (reg:CC FLAGS_REG))]
6457   "TARGET_64BIT"
6458 {
6459   switch (get_attr_type (insn))
6460     {
6461     case TYPE_INCDEC:
6462       if (operands[2] == const1_rtx)
6463         return "inc{b}\t%h0";
6464       else
6465         {
6466           gcc_assert (operands[2] == constm1_rtx
6467                       || (GET_CODE (operands[2]) == CONST_INT
6468                           && INTVAL (operands[2]) == 255));
6469           return "dec{b}\t%h0";
6470         }
6471
6472     default:
6473       return "add{b}\t{%2, %h0|%h0, %2}";
6474     }
6475 }
6476   [(set (attr "type")
6477      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6478         (const_string "incdec")
6479         (const_string "alu")))
6480    (set_attr "mode" "QI")])
6481
6482 (define_insn "*addqi_ext_2"
6483   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6484                          (const_int 8)
6485                          (const_int 8))
6486         (plus:SI
6487           (zero_extract:SI
6488             (match_operand 1 "ext_register_operand" "%0")
6489             (const_int 8)
6490             (const_int 8))
6491           (zero_extract:SI
6492             (match_operand 2 "ext_register_operand" "Q")
6493             (const_int 8)
6494             (const_int 8))))
6495    (clobber (reg:CC FLAGS_REG))]
6496   ""
6497   "add{b}\t{%h2, %h0|%h0, %h2}"
6498   [(set_attr "type" "alu")
6499    (set_attr "mode" "QI")])
6500
6501 ;; The patterns that match these are at the end of this file.
6502
6503 (define_expand "addxf3"
6504   [(set (match_operand:XF 0 "register_operand" "")
6505         (plus:XF (match_operand:XF 1 "register_operand" "")
6506                  (match_operand:XF 2 "register_operand" "")))]
6507   "TARGET_80387"
6508   "")
6509
6510 (define_expand "adddf3"
6511   [(set (match_operand:DF 0 "register_operand" "")
6512         (plus:DF (match_operand:DF 1 "register_operand" "")
6513                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6514   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6515   "")
6516
6517 (define_expand "addsf3"
6518   [(set (match_operand:SF 0 "register_operand" "")
6519         (plus:SF (match_operand:SF 1 "register_operand" "")
6520                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6521   "TARGET_80387 || TARGET_SSE_MATH"
6522   "")
6523 \f
6524 ;; Subtract instructions
6525
6526 ;; %%% splits for subditi3
6527
6528 (define_expand "subti3"
6529   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6530                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6531                              (match_operand:TI 2 "x86_64_general_operand" "")))
6532               (clobber (reg:CC FLAGS_REG))])]
6533   "TARGET_64BIT"
6534   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6535
6536 (define_insn "*subti3_1"
6537   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6538         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6539                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6540    (clobber (reg:CC FLAGS_REG))]
6541   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6542   "#")
6543
6544 (define_split
6545   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6546         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6547                   (match_operand:TI 2 "general_operand" "")))
6548    (clobber (reg:CC FLAGS_REG))]
6549   "TARGET_64BIT && reload_completed"
6550   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6551               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6552    (parallel [(set (match_dup 3)
6553                    (minus:DI (match_dup 4)
6554                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6555                                       (match_dup 5))))
6556               (clobber (reg:CC FLAGS_REG))])]
6557   "split_ti (operands+0, 1, operands+0, operands+3);
6558    split_ti (operands+1, 1, operands+1, operands+4);
6559    split_ti (operands+2, 1, operands+2, operands+5);")
6560
6561 ;; %%% splits for subsidi3
6562
6563 (define_expand "subdi3"
6564   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6565                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6566                              (match_operand:DI 2 "x86_64_general_operand" "")))
6567               (clobber (reg:CC FLAGS_REG))])]
6568   ""
6569   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6570
6571 (define_insn "*subdi3_1"
6572   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6573         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6574                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6575    (clobber (reg:CC FLAGS_REG))]
6576   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6577   "#")
6578
6579 (define_split
6580   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6581         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6582                   (match_operand:DI 2 "general_operand" "")))
6583    (clobber (reg:CC FLAGS_REG))]
6584   "!TARGET_64BIT && reload_completed"
6585   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6586               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6587    (parallel [(set (match_dup 3)
6588                    (minus:SI (match_dup 4)
6589                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6590                                       (match_dup 5))))
6591               (clobber (reg:CC FLAGS_REG))])]
6592   "split_di (operands+0, 1, operands+0, operands+3);
6593    split_di (operands+1, 1, operands+1, operands+4);
6594    split_di (operands+2, 1, operands+2, operands+5);")
6595
6596 (define_insn "subdi3_carry_rex64"
6597   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6598           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6599             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6600                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6601    (clobber (reg:CC FLAGS_REG))]
6602   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6603   "sbb{q}\t{%2, %0|%0, %2}"
6604   [(set_attr "type" "alu")
6605    (set_attr "pent_pair" "pu")
6606    (set_attr "mode" "DI")])
6607
6608 (define_insn "*subdi_1_rex64"
6609   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6610         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6611                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6612    (clobber (reg:CC FLAGS_REG))]
6613   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6614   "sub{q}\t{%2, %0|%0, %2}"
6615   [(set_attr "type" "alu")
6616    (set_attr "mode" "DI")])
6617
6618 (define_insn "*subdi_2_rex64"
6619   [(set (reg FLAGS_REG)
6620         (compare
6621           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6622                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6623           (const_int 0)))
6624    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6625         (minus:DI (match_dup 1) (match_dup 2)))]
6626   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6627    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6628   "sub{q}\t{%2, %0|%0, %2}"
6629   [(set_attr "type" "alu")
6630    (set_attr "mode" "DI")])
6631
6632 (define_insn "*subdi_3_rex63"
6633   [(set (reg FLAGS_REG)
6634         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6635                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6636    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6637         (minus:DI (match_dup 1) (match_dup 2)))]
6638   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6639    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6640   "sub{q}\t{%2, %0|%0, %2}"
6641   [(set_attr "type" "alu")
6642    (set_attr "mode" "DI")])
6643
6644 (define_insn "subqi3_carry"
6645   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6646           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6647             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6648                (match_operand:QI 2 "general_operand" "qi,qm"))))
6649    (clobber (reg:CC FLAGS_REG))]
6650   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6651   "sbb{b}\t{%2, %0|%0, %2}"
6652   [(set_attr "type" "alu")
6653    (set_attr "pent_pair" "pu")
6654    (set_attr "mode" "QI")])
6655
6656 (define_insn "subhi3_carry"
6657   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6658           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6659             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6660                (match_operand:HI 2 "general_operand" "ri,rm"))))
6661    (clobber (reg:CC FLAGS_REG))]
6662   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6663   "sbb{w}\t{%2, %0|%0, %2}"
6664   [(set_attr "type" "alu")
6665    (set_attr "pent_pair" "pu")
6666    (set_attr "mode" "HI")])
6667
6668 (define_insn "subsi3_carry"
6669   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6670           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6671             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6672                (match_operand:SI 2 "general_operand" "ri,rm"))))
6673    (clobber (reg:CC FLAGS_REG))]
6674   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6675   "sbb{l}\t{%2, %0|%0, %2}"
6676   [(set_attr "type" "alu")
6677    (set_attr "pent_pair" "pu")
6678    (set_attr "mode" "SI")])
6679
6680 (define_insn "subsi3_carry_zext"
6681   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6682           (zero_extend:DI
6683             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6684               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6685                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6686    (clobber (reg:CC FLAGS_REG))]
6687   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6688   "sbb{l}\t{%2, %k0|%k0, %2}"
6689   [(set_attr "type" "alu")
6690    (set_attr "pent_pair" "pu")
6691    (set_attr "mode" "SI")])
6692
6693 (define_expand "subsi3"
6694   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6695                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6696                              (match_operand:SI 2 "general_operand" "")))
6697               (clobber (reg:CC FLAGS_REG))])]
6698   ""
6699   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6700
6701 (define_insn "*subsi_1"
6702   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6703         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6704                   (match_operand:SI 2 "general_operand" "ri,rm")))
6705    (clobber (reg:CC FLAGS_REG))]
6706   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6707   "sub{l}\t{%2, %0|%0, %2}"
6708   [(set_attr "type" "alu")
6709    (set_attr "mode" "SI")])
6710
6711 (define_insn "*subsi_1_zext"
6712   [(set (match_operand:DI 0 "register_operand" "=r")
6713         (zero_extend:DI
6714           (minus:SI (match_operand:SI 1 "register_operand" "0")
6715                     (match_operand:SI 2 "general_operand" "rim"))))
6716    (clobber (reg:CC FLAGS_REG))]
6717   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6718   "sub{l}\t{%2, %k0|%k0, %2}"
6719   [(set_attr "type" "alu")
6720    (set_attr "mode" "SI")])
6721
6722 (define_insn "*subsi_2"
6723   [(set (reg FLAGS_REG)
6724         (compare
6725           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6726                     (match_operand:SI 2 "general_operand" "ri,rm"))
6727           (const_int 0)))
6728    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6729         (minus:SI (match_dup 1) (match_dup 2)))]
6730   "ix86_match_ccmode (insn, CCGOCmode)
6731    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6732   "sub{l}\t{%2, %0|%0, %2}"
6733   [(set_attr "type" "alu")
6734    (set_attr "mode" "SI")])
6735
6736 (define_insn "*subsi_2_zext"
6737   [(set (reg FLAGS_REG)
6738         (compare
6739           (minus:SI (match_operand:SI 1 "register_operand" "0")
6740                     (match_operand:SI 2 "general_operand" "rim"))
6741           (const_int 0)))
6742    (set (match_operand:DI 0 "register_operand" "=r")
6743         (zero_extend:DI
6744           (minus:SI (match_dup 1)
6745                     (match_dup 2))))]
6746   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6747    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6748   "sub{l}\t{%2, %k0|%k0, %2}"
6749   [(set_attr "type" "alu")
6750    (set_attr "mode" "SI")])
6751
6752 (define_insn "*subsi_3"
6753   [(set (reg FLAGS_REG)
6754         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6755                  (match_operand:SI 2 "general_operand" "ri,rm")))
6756    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6757         (minus:SI (match_dup 1) (match_dup 2)))]
6758   "ix86_match_ccmode (insn, CCmode)
6759    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6760   "sub{l}\t{%2, %0|%0, %2}"
6761   [(set_attr "type" "alu")
6762    (set_attr "mode" "SI")])
6763
6764 (define_insn "*subsi_3_zext"
6765   [(set (reg FLAGS_REG)
6766         (compare (match_operand:SI 1 "register_operand" "0")
6767                  (match_operand:SI 2 "general_operand" "rim")))
6768    (set (match_operand:DI 0 "register_operand" "=r")
6769         (zero_extend:DI
6770           (minus:SI (match_dup 1)
6771                     (match_dup 2))))]
6772   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6773    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6774   "sub{l}\t{%2, %1|%1, %2}"
6775   [(set_attr "type" "alu")
6776    (set_attr "mode" "DI")])
6777
6778 (define_expand "subhi3"
6779   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6780                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6781                              (match_operand:HI 2 "general_operand" "")))
6782               (clobber (reg:CC FLAGS_REG))])]
6783   "TARGET_HIMODE_MATH"
6784   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6785
6786 (define_insn "*subhi_1"
6787   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6788         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6789                   (match_operand:HI 2 "general_operand" "ri,rm")))
6790    (clobber (reg:CC FLAGS_REG))]
6791   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6792   "sub{w}\t{%2, %0|%0, %2}"
6793   [(set_attr "type" "alu")
6794    (set_attr "mode" "HI")])
6795
6796 (define_insn "*subhi_2"
6797   [(set (reg FLAGS_REG)
6798         (compare
6799           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6800                     (match_operand:HI 2 "general_operand" "ri,rm"))
6801           (const_int 0)))
6802    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6803         (minus:HI (match_dup 1) (match_dup 2)))]
6804   "ix86_match_ccmode (insn, CCGOCmode)
6805    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6806   "sub{w}\t{%2, %0|%0, %2}"
6807   [(set_attr "type" "alu")
6808    (set_attr "mode" "HI")])
6809
6810 (define_insn "*subhi_3"
6811   [(set (reg FLAGS_REG)
6812         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6813                  (match_operand:HI 2 "general_operand" "ri,rm")))
6814    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6815         (minus:HI (match_dup 1) (match_dup 2)))]
6816   "ix86_match_ccmode (insn, CCmode)
6817    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6818   "sub{w}\t{%2, %0|%0, %2}"
6819   [(set_attr "type" "alu")
6820    (set_attr "mode" "HI")])
6821
6822 (define_expand "subqi3"
6823   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6824                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6825                              (match_operand:QI 2 "general_operand" "")))
6826               (clobber (reg:CC FLAGS_REG))])]
6827   "TARGET_QIMODE_MATH"
6828   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6829
6830 (define_insn "*subqi_1"
6831   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6832         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6833                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6834    (clobber (reg:CC FLAGS_REG))]
6835   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6836   "sub{b}\t{%2, %0|%0, %2}"
6837   [(set_attr "type" "alu")
6838    (set_attr "mode" "QI")])
6839
6840 (define_insn "*subqi_1_slp"
6841   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6842         (minus:QI (match_dup 0)
6843                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6844    (clobber (reg:CC FLAGS_REG))]
6845   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6846    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6847   "sub{b}\t{%1, %0|%0, %1}"
6848   [(set_attr "type" "alu1")
6849    (set_attr "mode" "QI")])
6850
6851 (define_insn "*subqi_2"
6852   [(set (reg FLAGS_REG)
6853         (compare
6854           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6855                     (match_operand:QI 2 "general_operand" "qi,qm"))
6856           (const_int 0)))
6857    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6858         (minus:HI (match_dup 1) (match_dup 2)))]
6859   "ix86_match_ccmode (insn, CCGOCmode)
6860    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6861   "sub{b}\t{%2, %0|%0, %2}"
6862   [(set_attr "type" "alu")
6863    (set_attr "mode" "QI")])
6864
6865 (define_insn "*subqi_3"
6866   [(set (reg FLAGS_REG)
6867         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6868                  (match_operand:QI 2 "general_operand" "qi,qm")))
6869    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6870         (minus:HI (match_dup 1) (match_dup 2)))]
6871   "ix86_match_ccmode (insn, CCmode)
6872    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6873   "sub{b}\t{%2, %0|%0, %2}"
6874   [(set_attr "type" "alu")
6875    (set_attr "mode" "QI")])
6876
6877 ;; The patterns that match these are at the end of this file.
6878
6879 (define_expand "subxf3"
6880   [(set (match_operand:XF 0 "register_operand" "")
6881         (minus:XF (match_operand:XF 1 "register_operand" "")
6882                   (match_operand:XF 2 "register_operand" "")))]
6883   "TARGET_80387"
6884   "")
6885
6886 (define_expand "subdf3"
6887   [(set (match_operand:DF 0 "register_operand" "")
6888         (minus:DF (match_operand:DF 1 "register_operand" "")
6889                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6890   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6891   "")
6892
6893 (define_expand "subsf3"
6894   [(set (match_operand:SF 0 "register_operand" "")
6895         (minus:SF (match_operand:SF 1 "register_operand" "")
6896                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6897   "TARGET_80387 || TARGET_SSE_MATH"
6898   "")
6899 \f
6900 ;; Multiply instructions
6901
6902 (define_expand "muldi3"
6903   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6904                    (mult:DI (match_operand:DI 1 "register_operand" "")
6905                             (match_operand:DI 2 "x86_64_general_operand" "")))
6906               (clobber (reg:CC FLAGS_REG))])]
6907   "TARGET_64BIT"
6908   "")
6909
6910 (define_insn "*muldi3_1_rex64"
6911   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6912         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6913                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6914    (clobber (reg:CC FLAGS_REG))]
6915   "TARGET_64BIT
6916    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6917   "@
6918    imul{q}\t{%2, %1, %0|%0, %1, %2}
6919    imul{q}\t{%2, %1, %0|%0, %1, %2}
6920    imul{q}\t{%2, %0|%0, %2}"
6921   [(set_attr "type" "imul")
6922    (set_attr "prefix_0f" "0,0,1")
6923    (set (attr "athlon_decode")
6924         (cond [(eq_attr "cpu" "athlon")
6925                   (const_string "vector")
6926                (eq_attr "alternative" "1")
6927                   (const_string "vector")
6928                (and (eq_attr "alternative" "2")
6929                     (match_operand 1 "memory_operand" ""))
6930                   (const_string "vector")]
6931               (const_string "direct")))
6932    (set_attr "mode" "DI")])
6933
6934 (define_expand "mulsi3"
6935   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6936                    (mult:SI (match_operand:SI 1 "register_operand" "")
6937                             (match_operand:SI 2 "general_operand" "")))
6938               (clobber (reg:CC FLAGS_REG))])]
6939   ""
6940   "")
6941
6942 (define_insn "*mulsi3_1"
6943   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6944         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6945                  (match_operand:SI 2 "general_operand" "K,i,mr")))
6946    (clobber (reg:CC FLAGS_REG))]
6947   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6948   "@
6949    imul{l}\t{%2, %1, %0|%0, %1, %2}
6950    imul{l}\t{%2, %1, %0|%0, %1, %2}
6951    imul{l}\t{%2, %0|%0, %2}"
6952   [(set_attr "type" "imul")
6953    (set_attr "prefix_0f" "0,0,1")
6954    (set (attr "athlon_decode")
6955         (cond [(eq_attr "cpu" "athlon")
6956                   (const_string "vector")
6957                (eq_attr "alternative" "1")
6958                   (const_string "vector")
6959                (and (eq_attr "alternative" "2")
6960                     (match_operand 1 "memory_operand" ""))
6961                   (const_string "vector")]
6962               (const_string "direct")))
6963    (set_attr "mode" "SI")])
6964
6965 (define_insn "*mulsi3_1_zext"
6966   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6967         (zero_extend:DI
6968           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6969                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
6970    (clobber (reg:CC FLAGS_REG))]
6971   "TARGET_64BIT
6972    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6973   "@
6974    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6975    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6976    imul{l}\t{%2, %k0|%k0, %2}"
6977   [(set_attr "type" "imul")
6978    (set_attr "prefix_0f" "0,0,1")
6979    (set (attr "athlon_decode")
6980         (cond [(eq_attr "cpu" "athlon")
6981                   (const_string "vector")
6982                (eq_attr "alternative" "1")
6983                   (const_string "vector")
6984                (and (eq_attr "alternative" "2")
6985                     (match_operand 1 "memory_operand" ""))
6986                   (const_string "vector")]
6987               (const_string "direct")))
6988    (set_attr "mode" "SI")])
6989
6990 (define_expand "mulhi3"
6991   [(parallel [(set (match_operand:HI 0 "register_operand" "")
6992                    (mult:HI (match_operand:HI 1 "register_operand" "")
6993                             (match_operand:HI 2 "general_operand" "")))
6994               (clobber (reg:CC FLAGS_REG))])]
6995   "TARGET_HIMODE_MATH"
6996   "")
6997
6998 (define_insn "*mulhi3_1"
6999   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7000         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7001                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7002    (clobber (reg:CC FLAGS_REG))]
7003   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7004   "@
7005    imul{w}\t{%2, %1, %0|%0, %1, %2}
7006    imul{w}\t{%2, %1, %0|%0, %1, %2}
7007    imul{w}\t{%2, %0|%0, %2}"
7008   [(set_attr "type" "imul")
7009    (set_attr "prefix_0f" "0,0,1")
7010    (set (attr "athlon_decode")
7011         (cond [(eq_attr "cpu" "athlon")
7012                   (const_string "vector")
7013                (eq_attr "alternative" "1,2")
7014                   (const_string "vector")]
7015               (const_string "direct")))
7016    (set_attr "mode" "HI")])
7017
7018 (define_expand "mulqi3"
7019   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7020                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7021                             (match_operand:QI 2 "register_operand" "")))
7022               (clobber (reg:CC FLAGS_REG))])]
7023   "TARGET_QIMODE_MATH"
7024   "")
7025
7026 (define_insn "*mulqi3_1"
7027   [(set (match_operand:QI 0 "register_operand" "=a")
7028         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7029                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7030    (clobber (reg:CC FLAGS_REG))]
7031   "TARGET_QIMODE_MATH
7032    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7033   "mul{b}\t%2"
7034   [(set_attr "type" "imul")
7035    (set_attr "length_immediate" "0")
7036    (set (attr "athlon_decode")
7037      (if_then_else (eq_attr "cpu" "athlon")
7038         (const_string "vector")
7039         (const_string "direct")))
7040    (set_attr "mode" "QI")])
7041
7042 (define_expand "umulqihi3"
7043   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7044                    (mult:HI (zero_extend:HI
7045                               (match_operand:QI 1 "nonimmediate_operand" ""))
7046                             (zero_extend:HI
7047                               (match_operand:QI 2 "register_operand" ""))))
7048               (clobber (reg:CC FLAGS_REG))])]
7049   "TARGET_QIMODE_MATH"
7050   "")
7051
7052 (define_insn "*umulqihi3_1"
7053   [(set (match_operand:HI 0 "register_operand" "=a")
7054         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7055                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7056    (clobber (reg:CC FLAGS_REG))]
7057   "TARGET_QIMODE_MATH
7058    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7059   "mul{b}\t%2"
7060   [(set_attr "type" "imul")
7061    (set_attr "length_immediate" "0")
7062    (set (attr "athlon_decode")
7063      (if_then_else (eq_attr "cpu" "athlon")
7064         (const_string "vector")
7065         (const_string "direct")))
7066    (set_attr "mode" "QI")])
7067
7068 (define_expand "mulqihi3"
7069   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7070                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7071                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7072               (clobber (reg:CC FLAGS_REG))])]
7073   "TARGET_QIMODE_MATH"
7074   "")
7075
7076 (define_insn "*mulqihi3_insn"
7077   [(set (match_operand:HI 0 "register_operand" "=a")
7078         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7079                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7080    (clobber (reg:CC FLAGS_REG))]
7081   "TARGET_QIMODE_MATH
7082    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7083   "imul{b}\t%2"
7084   [(set_attr "type" "imul")
7085    (set_attr "length_immediate" "0")
7086    (set (attr "athlon_decode")
7087      (if_then_else (eq_attr "cpu" "athlon")
7088         (const_string "vector")
7089         (const_string "direct")))
7090    (set_attr "mode" "QI")])
7091
7092 (define_expand "umulditi3"
7093   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7094                    (mult:TI (zero_extend:TI
7095                               (match_operand:DI 1 "nonimmediate_operand" ""))
7096                             (zero_extend:TI
7097                               (match_operand:DI 2 "register_operand" ""))))
7098               (clobber (reg:CC FLAGS_REG))])]
7099   "TARGET_64BIT"
7100   "")
7101
7102 (define_insn "*umulditi3_insn"
7103   [(set (match_operand:TI 0 "register_operand" "=A")
7104         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7105                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7106    (clobber (reg:CC FLAGS_REG))]
7107   "TARGET_64BIT
7108    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7109   "mul{q}\t%2"
7110   [(set_attr "type" "imul")
7111    (set_attr "length_immediate" "0")
7112    (set (attr "athlon_decode")
7113      (if_then_else (eq_attr "cpu" "athlon")
7114         (const_string "vector")
7115         (const_string "double")))
7116    (set_attr "mode" "DI")])
7117
7118 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7119 (define_expand "umulsidi3"
7120   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7121                    (mult:DI (zero_extend:DI
7122                               (match_operand:SI 1 "nonimmediate_operand" ""))
7123                             (zero_extend:DI
7124                               (match_operand:SI 2 "register_operand" ""))))
7125               (clobber (reg:CC FLAGS_REG))])]
7126   "!TARGET_64BIT"
7127   "")
7128
7129 (define_insn "*umulsidi3_insn"
7130   [(set (match_operand:DI 0 "register_operand" "=A")
7131         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7132                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7133    (clobber (reg:CC FLAGS_REG))]
7134   "!TARGET_64BIT
7135    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7136   "mul{l}\t%2"
7137   [(set_attr "type" "imul")
7138    (set_attr "length_immediate" "0")
7139    (set (attr "athlon_decode")
7140      (if_then_else (eq_attr "cpu" "athlon")
7141         (const_string "vector")
7142         (const_string "double")))
7143    (set_attr "mode" "SI")])
7144
7145 (define_expand "mulditi3"
7146   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7147                    (mult:TI (sign_extend:TI
7148                               (match_operand:DI 1 "nonimmediate_operand" ""))
7149                             (sign_extend:TI
7150                               (match_operand:DI 2 "register_operand" ""))))
7151               (clobber (reg:CC FLAGS_REG))])]
7152   "TARGET_64BIT"
7153   "")
7154
7155 (define_insn "*mulditi3_insn"
7156   [(set (match_operand:TI 0 "register_operand" "=A")
7157         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7158                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7159    (clobber (reg:CC FLAGS_REG))]
7160   "TARGET_64BIT
7161    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7162   "imul{q}\t%2"
7163   [(set_attr "type" "imul")
7164    (set_attr "length_immediate" "0")
7165    (set (attr "athlon_decode")
7166      (if_then_else (eq_attr "cpu" "athlon")
7167         (const_string "vector")
7168         (const_string "double")))
7169    (set_attr "mode" "DI")])
7170
7171 (define_expand "mulsidi3"
7172   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7173                    (mult:DI (sign_extend:DI
7174                               (match_operand:SI 1 "nonimmediate_operand" ""))
7175                             (sign_extend:DI
7176                               (match_operand:SI 2 "register_operand" ""))))
7177               (clobber (reg:CC FLAGS_REG))])]
7178   "!TARGET_64BIT"
7179   "")
7180
7181 (define_insn "*mulsidi3_insn"
7182   [(set (match_operand:DI 0 "register_operand" "=A")
7183         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7184                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7185    (clobber (reg:CC FLAGS_REG))]
7186   "!TARGET_64BIT
7187    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7188   "imul{l}\t%2"
7189   [(set_attr "type" "imul")
7190    (set_attr "length_immediate" "0")
7191    (set (attr "athlon_decode")
7192      (if_then_else (eq_attr "cpu" "athlon")
7193         (const_string "vector")
7194         (const_string "double")))
7195    (set_attr "mode" "SI")])
7196
7197 (define_expand "umuldi3_highpart"
7198   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7199                    (truncate:DI
7200                      (lshiftrt:TI
7201                        (mult:TI (zero_extend:TI
7202                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7203                                 (zero_extend:TI
7204                                   (match_operand:DI 2 "register_operand" "")))
7205                        (const_int 64))))
7206               (clobber (match_scratch:DI 3 ""))
7207               (clobber (reg:CC FLAGS_REG))])]
7208   "TARGET_64BIT"
7209   "")
7210
7211 (define_insn "*umuldi3_highpart_rex64"
7212   [(set (match_operand:DI 0 "register_operand" "=d")
7213         (truncate:DI
7214           (lshiftrt:TI
7215             (mult:TI (zero_extend:TI
7216                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7217                      (zero_extend:TI
7218                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7219             (const_int 64))))
7220    (clobber (match_scratch:DI 3 "=1"))
7221    (clobber (reg:CC FLAGS_REG))]
7222   "TARGET_64BIT
7223    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7224   "mul{q}\t%2"
7225   [(set_attr "type" "imul")
7226    (set_attr "length_immediate" "0")
7227    (set (attr "athlon_decode")
7228      (if_then_else (eq_attr "cpu" "athlon")
7229         (const_string "vector")
7230         (const_string "double")))
7231    (set_attr "mode" "DI")])
7232
7233 (define_expand "umulsi3_highpart"
7234   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7235                    (truncate:SI
7236                      (lshiftrt:DI
7237                        (mult:DI (zero_extend:DI
7238                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7239                                 (zero_extend:DI
7240                                   (match_operand:SI 2 "register_operand" "")))
7241                        (const_int 32))))
7242               (clobber (match_scratch:SI 3 ""))
7243               (clobber (reg:CC FLAGS_REG))])]
7244   ""
7245   "")
7246
7247 (define_insn "*umulsi3_highpart_insn"
7248   [(set (match_operand:SI 0 "register_operand" "=d")
7249         (truncate:SI
7250           (lshiftrt:DI
7251             (mult:DI (zero_extend:DI
7252                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7253                      (zero_extend:DI
7254                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7255             (const_int 32))))
7256    (clobber (match_scratch:SI 3 "=1"))
7257    (clobber (reg:CC FLAGS_REG))]
7258   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7259   "mul{l}\t%2"
7260   [(set_attr "type" "imul")
7261    (set_attr "length_immediate" "0")
7262    (set (attr "athlon_decode")
7263      (if_then_else (eq_attr "cpu" "athlon")
7264         (const_string "vector")
7265         (const_string "double")))
7266    (set_attr "mode" "SI")])
7267
7268 (define_insn "*umulsi3_highpart_zext"
7269   [(set (match_operand:DI 0 "register_operand" "=d")
7270         (zero_extend:DI (truncate:SI
7271           (lshiftrt:DI
7272             (mult:DI (zero_extend:DI
7273                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7274                      (zero_extend:DI
7275                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7276             (const_int 32)))))
7277    (clobber (match_scratch:SI 3 "=1"))
7278    (clobber (reg:CC FLAGS_REG))]
7279   "TARGET_64BIT
7280    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7281   "mul{l}\t%2"
7282   [(set_attr "type" "imul")
7283    (set_attr "length_immediate" "0")
7284    (set (attr "athlon_decode")
7285      (if_then_else (eq_attr "cpu" "athlon")
7286         (const_string "vector")
7287         (const_string "double")))
7288    (set_attr "mode" "SI")])
7289
7290 (define_expand "smuldi3_highpart"
7291   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7292                    (truncate:DI
7293                      (lshiftrt:TI
7294                        (mult:TI (sign_extend:TI
7295                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7296                                 (sign_extend:TI
7297                                   (match_operand:DI 2 "register_operand" "")))
7298                        (const_int 64))))
7299               (clobber (match_scratch:DI 3 ""))
7300               (clobber (reg:CC FLAGS_REG))])]
7301   "TARGET_64BIT"
7302   "")
7303
7304 (define_insn "*smuldi3_highpart_rex64"
7305   [(set (match_operand:DI 0 "register_operand" "=d")
7306         (truncate:DI
7307           (lshiftrt:TI
7308             (mult:TI (sign_extend:TI
7309                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7310                      (sign_extend:TI
7311                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7312             (const_int 64))))
7313    (clobber (match_scratch:DI 3 "=1"))
7314    (clobber (reg:CC FLAGS_REG))]
7315   "TARGET_64BIT
7316    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7317   "imul{q}\t%2"
7318   [(set_attr "type" "imul")
7319    (set (attr "athlon_decode")
7320      (if_then_else (eq_attr "cpu" "athlon")
7321         (const_string "vector")
7322         (const_string "double")))
7323    (set_attr "mode" "DI")])
7324
7325 (define_expand "smulsi3_highpart"
7326   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7327                    (truncate:SI
7328                      (lshiftrt:DI
7329                        (mult:DI (sign_extend:DI
7330                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7331                                 (sign_extend:DI
7332                                   (match_operand:SI 2 "register_operand" "")))
7333                        (const_int 32))))
7334               (clobber (match_scratch:SI 3 ""))
7335               (clobber (reg:CC FLAGS_REG))])]
7336   ""
7337   "")
7338
7339 (define_insn "*smulsi3_highpart_insn"
7340   [(set (match_operand:SI 0 "register_operand" "=d")
7341         (truncate:SI
7342           (lshiftrt:DI
7343             (mult:DI (sign_extend:DI
7344                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7345                      (sign_extend:DI
7346                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7347             (const_int 32))))
7348    (clobber (match_scratch:SI 3 "=1"))
7349    (clobber (reg:CC FLAGS_REG))]
7350   "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7351   "imul{l}\t%2"
7352   [(set_attr "type" "imul")
7353    (set (attr "athlon_decode")
7354      (if_then_else (eq_attr "cpu" "athlon")
7355         (const_string "vector")
7356         (const_string "double")))
7357    (set_attr "mode" "SI")])
7358
7359 (define_insn "*smulsi3_highpart_zext"
7360   [(set (match_operand:DI 0 "register_operand" "=d")
7361         (zero_extend:DI (truncate:SI
7362           (lshiftrt:DI
7363             (mult:DI (sign_extend:DI
7364                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7365                      (sign_extend:DI
7366                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7367             (const_int 32)))))
7368    (clobber (match_scratch:SI 3 "=1"))
7369    (clobber (reg:CC FLAGS_REG))]
7370   "TARGET_64BIT
7371    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7372   "imul{l}\t%2"
7373   [(set_attr "type" "imul")
7374    (set (attr "athlon_decode")
7375      (if_then_else (eq_attr "cpu" "athlon")
7376         (const_string "vector")
7377         (const_string "double")))
7378    (set_attr "mode" "SI")])
7379
7380 ;; The patterns that match these are at the end of this file.
7381
7382 (define_expand "mulxf3"
7383   [(set (match_operand:XF 0 "register_operand" "")
7384         (mult:XF (match_operand:XF 1 "register_operand" "")
7385                  (match_operand:XF 2 "register_operand" "")))]
7386   "TARGET_80387"
7387   "")
7388
7389 (define_expand "muldf3"
7390   [(set (match_operand:DF 0 "register_operand" "")
7391         (mult:DF (match_operand:DF 1 "register_operand" "")
7392                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7393   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7394   "")
7395
7396 (define_expand "mulsf3"
7397   [(set (match_operand:SF 0 "register_operand" "")
7398         (mult:SF (match_operand:SF 1 "register_operand" "")
7399                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7400   "TARGET_80387 || TARGET_SSE_MATH"
7401   "")
7402 \f
7403 ;; Divide instructions
7404
7405 (define_insn "divqi3"
7406   [(set (match_operand:QI 0 "register_operand" "=a")
7407         (div:QI (match_operand:HI 1 "register_operand" "0")
7408                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7409    (clobber (reg:CC FLAGS_REG))]
7410   "TARGET_QIMODE_MATH"
7411   "idiv{b}\t%2"
7412   [(set_attr "type" "idiv")
7413    (set_attr "mode" "QI")])
7414
7415 (define_insn "udivqi3"
7416   [(set (match_operand:QI 0 "register_operand" "=a")
7417         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7418                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7419    (clobber (reg:CC FLAGS_REG))]
7420   "TARGET_QIMODE_MATH"
7421   "div{b}\t%2"
7422   [(set_attr "type" "idiv")
7423    (set_attr "mode" "QI")])
7424
7425 ;; The patterns that match these are at the end of this file.
7426
7427 (define_expand "divxf3"
7428   [(set (match_operand:XF 0 "register_operand" "")
7429         (div:XF (match_operand:XF 1 "register_operand" "")
7430                 (match_operand:XF 2 "register_operand" "")))]
7431   "TARGET_80387"
7432   "")
7433
7434 (define_expand "divdf3"
7435   [(set (match_operand:DF 0 "register_operand" "")
7436         (div:DF (match_operand:DF 1 "register_operand" "")
7437                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7438    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7439    "")
7440
7441 (define_expand "divsf3"
7442   [(set (match_operand:SF 0 "register_operand" "")
7443         (div:SF (match_operand:SF 1 "register_operand" "")
7444                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7445   "TARGET_80387 || TARGET_SSE_MATH"
7446   "")
7447 \f
7448 ;; Remainder instructions.
7449
7450 (define_expand "divmoddi4"
7451   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7452                    (div:DI (match_operand:DI 1 "register_operand" "")
7453                            (match_operand:DI 2 "nonimmediate_operand" "")))
7454               (set (match_operand:DI 3 "register_operand" "")
7455                    (mod:DI (match_dup 1) (match_dup 2)))
7456               (clobber (reg:CC FLAGS_REG))])]
7457   "TARGET_64BIT"
7458   "")
7459
7460 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7461 ;; Penalize eax case slightly because it results in worse scheduling
7462 ;; of code.
7463 (define_insn "*divmoddi4_nocltd_rex64"
7464   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7465         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7466                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7467    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7468         (mod:DI (match_dup 2) (match_dup 3)))
7469    (clobber (reg:CC FLAGS_REG))]
7470   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7471   "#"
7472   [(set_attr "type" "multi")])
7473
7474 (define_insn "*divmoddi4_cltd_rex64"
7475   [(set (match_operand:DI 0 "register_operand" "=a")
7476         (div:DI (match_operand:DI 2 "register_operand" "a")
7477                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7478    (set (match_operand:DI 1 "register_operand" "=&d")
7479         (mod:DI (match_dup 2) (match_dup 3)))
7480    (clobber (reg:CC FLAGS_REG))]
7481   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7482   "#"
7483   [(set_attr "type" "multi")])
7484
7485 (define_insn "*divmoddi_noext_rex64"
7486   [(set (match_operand:DI 0 "register_operand" "=a")
7487         (div:DI (match_operand:DI 1 "register_operand" "0")
7488                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7489    (set (match_operand:DI 3 "register_operand" "=d")
7490         (mod:DI (match_dup 1) (match_dup 2)))
7491    (use (match_operand:DI 4 "register_operand" "3"))
7492    (clobber (reg:CC FLAGS_REG))]
7493   "TARGET_64BIT"
7494   "idiv{q}\t%2"
7495   [(set_attr "type" "idiv")
7496    (set_attr "mode" "DI")])
7497
7498 (define_split
7499   [(set (match_operand:DI 0 "register_operand" "")
7500         (div:DI (match_operand:DI 1 "register_operand" "")
7501                 (match_operand:DI 2 "nonimmediate_operand" "")))
7502    (set (match_operand:DI 3 "register_operand" "")
7503         (mod:DI (match_dup 1) (match_dup 2)))
7504    (clobber (reg:CC FLAGS_REG))]
7505   "TARGET_64BIT && reload_completed"
7506   [(parallel [(set (match_dup 3)
7507                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7508               (clobber (reg:CC FLAGS_REG))])
7509    (parallel [(set (match_dup 0)
7510                    (div:DI (reg:DI 0) (match_dup 2)))
7511               (set (match_dup 3)
7512                    (mod:DI (reg:DI 0) (match_dup 2)))
7513               (use (match_dup 3))
7514               (clobber (reg:CC FLAGS_REG))])]
7515 {
7516   /* Avoid use of cltd in favor of a mov+shift.  */
7517   if (!TARGET_USE_CLTD && !optimize_size)
7518     {
7519       if (true_regnum (operands[1]))
7520         emit_move_insn (operands[0], operands[1]);
7521       else
7522         emit_move_insn (operands[3], operands[1]);
7523       operands[4] = operands[3];
7524     }
7525   else
7526     {
7527       gcc_assert (!true_regnum (operands[1]));
7528       operands[4] = operands[1];
7529     }
7530 })
7531
7532
7533 (define_expand "divmodsi4"
7534   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7535                    (div:SI (match_operand:SI 1 "register_operand" "")
7536                            (match_operand:SI 2 "nonimmediate_operand" "")))
7537               (set (match_operand:SI 3 "register_operand" "")
7538                    (mod:SI (match_dup 1) (match_dup 2)))
7539               (clobber (reg:CC FLAGS_REG))])]
7540   ""
7541   "")
7542
7543 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7544 ;; Penalize eax case slightly because it results in worse scheduling
7545 ;; of code.
7546 (define_insn "*divmodsi4_nocltd"
7547   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7548         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7549                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7550    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7551         (mod:SI (match_dup 2) (match_dup 3)))
7552    (clobber (reg:CC FLAGS_REG))]
7553   "!optimize_size && !TARGET_USE_CLTD"
7554   "#"
7555   [(set_attr "type" "multi")])
7556
7557 (define_insn "*divmodsi4_cltd"
7558   [(set (match_operand:SI 0 "register_operand" "=a")
7559         (div:SI (match_operand:SI 2 "register_operand" "a")
7560                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7561    (set (match_operand:SI 1 "register_operand" "=&d")
7562         (mod:SI (match_dup 2) (match_dup 3)))
7563    (clobber (reg:CC FLAGS_REG))]
7564   "optimize_size || TARGET_USE_CLTD"
7565   "#"
7566   [(set_attr "type" "multi")])
7567
7568 (define_insn "*divmodsi_noext"
7569   [(set (match_operand:SI 0 "register_operand" "=a")
7570         (div:SI (match_operand:SI 1 "register_operand" "0")
7571                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7572    (set (match_operand:SI 3 "register_operand" "=d")
7573         (mod:SI (match_dup 1) (match_dup 2)))
7574    (use (match_operand:SI 4 "register_operand" "3"))
7575    (clobber (reg:CC FLAGS_REG))]
7576   ""
7577   "idiv{l}\t%2"
7578   [(set_attr "type" "idiv")
7579    (set_attr "mode" "SI")])
7580
7581 (define_split
7582   [(set (match_operand:SI 0 "register_operand" "")
7583         (div:SI (match_operand:SI 1 "register_operand" "")
7584                 (match_operand:SI 2 "nonimmediate_operand" "")))
7585    (set (match_operand:SI 3 "register_operand" "")
7586         (mod:SI (match_dup 1) (match_dup 2)))
7587    (clobber (reg:CC FLAGS_REG))]
7588   "reload_completed"
7589   [(parallel [(set (match_dup 3)
7590                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7591               (clobber (reg:CC FLAGS_REG))])
7592    (parallel [(set (match_dup 0)
7593                    (div:SI (reg:SI 0) (match_dup 2)))
7594               (set (match_dup 3)
7595                    (mod:SI (reg:SI 0) (match_dup 2)))
7596               (use (match_dup 3))
7597               (clobber (reg:CC FLAGS_REG))])]
7598 {
7599   /* Avoid use of cltd in favor of a mov+shift.  */
7600   if (!TARGET_USE_CLTD && !optimize_size)
7601     {
7602       if (true_regnum (operands[1]))
7603         emit_move_insn (operands[0], operands[1]);
7604       else
7605         emit_move_insn (operands[3], operands[1]);
7606       operands[4] = operands[3];
7607     }
7608   else
7609     {
7610       gcc_assert (!true_regnum (operands[1]));
7611       operands[4] = operands[1];
7612     }
7613 })
7614 ;; %%% Split me.
7615 (define_insn "divmodhi4"
7616   [(set (match_operand:HI 0 "register_operand" "=a")
7617         (div:HI (match_operand:HI 1 "register_operand" "0")
7618                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7619    (set (match_operand:HI 3 "register_operand" "=&d")
7620         (mod:HI (match_dup 1) (match_dup 2)))
7621    (clobber (reg:CC FLAGS_REG))]
7622   "TARGET_HIMODE_MATH"
7623   "cwtd\;idiv{w}\t%2"
7624   [(set_attr "type" "multi")
7625    (set_attr "length_immediate" "0")
7626    (set_attr "mode" "SI")])
7627
7628 (define_insn "udivmoddi4"
7629   [(set (match_operand:DI 0 "register_operand" "=a")
7630         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7631                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7632    (set (match_operand:DI 3 "register_operand" "=&d")
7633         (umod:DI (match_dup 1) (match_dup 2)))
7634    (clobber (reg:CC FLAGS_REG))]
7635   "TARGET_64BIT"
7636   "xor{q}\t%3, %3\;div{q}\t%2"
7637   [(set_attr "type" "multi")
7638    (set_attr "length_immediate" "0")
7639    (set_attr "mode" "DI")])
7640
7641 (define_insn "*udivmoddi4_noext"
7642   [(set (match_operand:DI 0 "register_operand" "=a")
7643         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7644                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7645    (set (match_operand:DI 3 "register_operand" "=d")
7646         (umod:DI (match_dup 1) (match_dup 2)))
7647    (use (match_dup 3))
7648    (clobber (reg:CC FLAGS_REG))]
7649   "TARGET_64BIT"
7650   "div{q}\t%2"
7651   [(set_attr "type" "idiv")
7652    (set_attr "mode" "DI")])
7653
7654 (define_split
7655   [(set (match_operand:DI 0 "register_operand" "")
7656         (udiv:DI (match_operand:DI 1 "register_operand" "")
7657                  (match_operand:DI 2 "nonimmediate_operand" "")))
7658    (set (match_operand:DI 3 "register_operand" "")
7659         (umod:DI (match_dup 1) (match_dup 2)))
7660    (clobber (reg:CC FLAGS_REG))]
7661   "TARGET_64BIT && reload_completed"
7662   [(set (match_dup 3) (const_int 0))
7663    (parallel [(set (match_dup 0)
7664                    (udiv:DI (match_dup 1) (match_dup 2)))
7665               (set (match_dup 3)
7666                    (umod:DI (match_dup 1) (match_dup 2)))
7667               (use (match_dup 3))
7668               (clobber (reg:CC FLAGS_REG))])]
7669   "")
7670
7671 (define_insn "udivmodsi4"
7672   [(set (match_operand:SI 0 "register_operand" "=a")
7673         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7674                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7675    (set (match_operand:SI 3 "register_operand" "=&d")
7676         (umod:SI (match_dup 1) (match_dup 2)))
7677    (clobber (reg:CC FLAGS_REG))]
7678   ""
7679   "xor{l}\t%3, %3\;div{l}\t%2"
7680   [(set_attr "type" "multi")
7681    (set_attr "length_immediate" "0")
7682    (set_attr "mode" "SI")])
7683
7684 (define_insn "*udivmodsi4_noext"
7685   [(set (match_operand:SI 0 "register_operand" "=a")
7686         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7687                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7688    (set (match_operand:SI 3 "register_operand" "=d")
7689         (umod:SI (match_dup 1) (match_dup 2)))
7690    (use (match_dup 3))
7691    (clobber (reg:CC FLAGS_REG))]
7692   ""
7693   "div{l}\t%2"
7694   [(set_attr "type" "idiv")
7695    (set_attr "mode" "SI")])
7696
7697 (define_split
7698   [(set (match_operand:SI 0 "register_operand" "")
7699         (udiv:SI (match_operand:SI 1 "register_operand" "")
7700                  (match_operand:SI 2 "nonimmediate_operand" "")))
7701    (set (match_operand:SI 3 "register_operand" "")
7702         (umod:SI (match_dup 1) (match_dup 2)))
7703    (clobber (reg:CC FLAGS_REG))]
7704   "reload_completed"
7705   [(set (match_dup 3) (const_int 0))
7706    (parallel [(set (match_dup 0)
7707                    (udiv:SI (match_dup 1) (match_dup 2)))
7708               (set (match_dup 3)
7709                    (umod:SI (match_dup 1) (match_dup 2)))
7710               (use (match_dup 3))
7711               (clobber (reg:CC FLAGS_REG))])]
7712   "")
7713
7714 (define_expand "udivmodhi4"
7715   [(set (match_dup 4) (const_int 0))
7716    (parallel [(set (match_operand:HI 0 "register_operand" "")
7717                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7718                             (match_operand:HI 2 "nonimmediate_operand" "")))
7719               (set (match_operand:HI 3 "register_operand" "")
7720                    (umod:HI (match_dup 1) (match_dup 2)))
7721               (use (match_dup 4))
7722               (clobber (reg:CC FLAGS_REG))])]
7723   "TARGET_HIMODE_MATH"
7724   "operands[4] = gen_reg_rtx (HImode);")
7725
7726 (define_insn "*udivmodhi_noext"
7727   [(set (match_operand:HI 0 "register_operand" "=a")
7728         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7729                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7730    (set (match_operand:HI 3 "register_operand" "=d")
7731         (umod:HI (match_dup 1) (match_dup 2)))
7732    (use (match_operand:HI 4 "register_operand" "3"))
7733    (clobber (reg:CC FLAGS_REG))]
7734   ""
7735   "div{w}\t%2"
7736   [(set_attr "type" "idiv")
7737    (set_attr "mode" "HI")])
7738
7739 ;; We cannot use div/idiv for double division, because it causes
7740 ;; "division by zero" on the overflow and that's not what we expect
7741 ;; from truncate.  Because true (non truncating) double division is
7742 ;; never generated, we can't create this insn anyway.
7743 ;
7744 ;(define_insn ""
7745 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7746 ;       (truncate:SI
7747 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7748 ;                  (zero_extend:DI
7749 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7750 ;   (set (match_operand:SI 3 "register_operand" "=d")
7751 ;       (truncate:SI
7752 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7753 ;   (clobber (reg:CC FLAGS_REG))]
7754 ;  ""
7755 ;  "div{l}\t{%2, %0|%0, %2}"
7756 ;  [(set_attr "type" "idiv")])
7757 \f
7758 ;;- Logical AND instructions
7759
7760 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7761 ;; Note that this excludes ah.
7762
7763 (define_insn "*testdi_1_rex64"
7764   [(set (reg FLAGS_REG)
7765         (compare
7766           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7767                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7768           (const_int 0)))]
7769   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7770    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7771   "@
7772    test{l}\t{%k1, %k0|%k0, %k1}
7773    test{l}\t{%k1, %k0|%k0, %k1}
7774    test{q}\t{%1, %0|%0, %1}
7775    test{q}\t{%1, %0|%0, %1}
7776    test{q}\t{%1, %0|%0, %1}"
7777   [(set_attr "type" "test")
7778    (set_attr "modrm" "0,1,0,1,1")
7779    (set_attr "mode" "SI,SI,DI,DI,DI")
7780    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7781
7782 (define_insn "testsi_1"
7783   [(set (reg FLAGS_REG)
7784         (compare
7785           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7786                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7787           (const_int 0)))]
7788   "ix86_match_ccmode (insn, CCNOmode)
7789    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7790   "test{l}\t{%1, %0|%0, %1}"
7791   [(set_attr "type" "test")
7792    (set_attr "modrm" "0,1,1")
7793    (set_attr "mode" "SI")
7794    (set_attr "pent_pair" "uv,np,uv")])
7795
7796 (define_expand "testsi_ccno_1"
7797   [(set (reg:CCNO FLAGS_REG)
7798         (compare:CCNO
7799           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7800                   (match_operand:SI 1 "nonmemory_operand" ""))
7801           (const_int 0)))]
7802   ""
7803   "")
7804
7805 (define_insn "*testhi_1"
7806   [(set (reg FLAGS_REG)
7807         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7808                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7809                  (const_int 0)))]
7810   "ix86_match_ccmode (insn, CCNOmode)
7811    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7812   "test{w}\t{%1, %0|%0, %1}"
7813   [(set_attr "type" "test")
7814    (set_attr "modrm" "0,1,1")
7815    (set_attr "mode" "HI")
7816    (set_attr "pent_pair" "uv,np,uv")])
7817
7818 (define_expand "testqi_ccz_1"
7819   [(set (reg:CCZ FLAGS_REG)
7820         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7821                              (match_operand:QI 1 "nonmemory_operand" ""))
7822                  (const_int 0)))]
7823   ""
7824   "")
7825
7826 (define_insn "*testqi_1_maybe_si"
7827   [(set (reg FLAGS_REG)
7828         (compare
7829           (and:QI
7830             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7831             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7832           (const_int 0)))]
7833    "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7834     && ix86_match_ccmode (insn,
7835                          GET_CODE (operands[1]) == CONST_INT
7836                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7837 {
7838   if (which_alternative == 3)
7839     {
7840       if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7841         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7842       return "test{l}\t{%1, %k0|%k0, %1}";
7843     }
7844   return "test{b}\t{%1, %0|%0, %1}";
7845 }
7846   [(set_attr "type" "test")
7847    (set_attr "modrm" "0,1,1,1")
7848    (set_attr "mode" "QI,QI,QI,SI")
7849    (set_attr "pent_pair" "uv,np,uv,np")])
7850
7851 (define_insn "*testqi_1"
7852   [(set (reg FLAGS_REG)
7853         (compare
7854           (and:QI
7855             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7856             (match_operand:QI 1 "general_operand" "n,n,qn"))
7857           (const_int 0)))]
7858   "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7859    && ix86_match_ccmode (insn, CCNOmode)"
7860   "test{b}\t{%1, %0|%0, %1}"
7861   [(set_attr "type" "test")
7862    (set_attr "modrm" "0,1,1")
7863    (set_attr "mode" "QI")
7864    (set_attr "pent_pair" "uv,np,uv")])
7865
7866 (define_expand "testqi_ext_ccno_0"
7867   [(set (reg:CCNO FLAGS_REG)
7868         (compare:CCNO
7869           (and:SI
7870             (zero_extract:SI
7871               (match_operand 0 "ext_register_operand" "")
7872               (const_int 8)
7873               (const_int 8))
7874             (match_operand 1 "const_int_operand" ""))
7875           (const_int 0)))]
7876   ""
7877   "")
7878
7879 (define_insn "*testqi_ext_0"
7880   [(set (reg FLAGS_REG)
7881         (compare
7882           (and:SI
7883             (zero_extract:SI
7884               (match_operand 0 "ext_register_operand" "Q")
7885               (const_int 8)
7886               (const_int 8))
7887             (match_operand 1 "const_int_operand" "n"))
7888           (const_int 0)))]
7889   "ix86_match_ccmode (insn, CCNOmode)"
7890   "test{b}\t{%1, %h0|%h0, %1}"
7891   [(set_attr "type" "test")
7892    (set_attr "mode" "QI")
7893    (set_attr "length_immediate" "1")
7894    (set_attr "pent_pair" "np")])
7895
7896 (define_insn "*testqi_ext_1"
7897   [(set (reg FLAGS_REG)
7898         (compare
7899           (and:SI
7900             (zero_extract:SI
7901               (match_operand 0 "ext_register_operand" "Q")
7902               (const_int 8)
7903               (const_int 8))
7904             (zero_extend:SI
7905               (match_operand:QI 1 "general_operand" "Qm")))
7906           (const_int 0)))]
7907   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7908    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7909   "test{b}\t{%1, %h0|%h0, %1}"
7910   [(set_attr "type" "test")
7911    (set_attr "mode" "QI")])
7912
7913 (define_insn "*testqi_ext_1_rex64"
7914   [(set (reg FLAGS_REG)
7915         (compare
7916           (and:SI
7917             (zero_extract:SI
7918               (match_operand 0 "ext_register_operand" "Q")
7919               (const_int 8)
7920               (const_int 8))
7921             (zero_extend:SI
7922               (match_operand:QI 1 "register_operand" "Q")))
7923           (const_int 0)))]
7924   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7925   "test{b}\t{%1, %h0|%h0, %1}"
7926   [(set_attr "type" "test")
7927    (set_attr "mode" "QI")])
7928
7929 (define_insn "*testqi_ext_2"
7930   [(set (reg FLAGS_REG)
7931         (compare
7932           (and:SI
7933             (zero_extract:SI
7934               (match_operand 0 "ext_register_operand" "Q")
7935               (const_int 8)
7936               (const_int 8))
7937             (zero_extract:SI
7938               (match_operand 1 "ext_register_operand" "Q")
7939               (const_int 8)
7940               (const_int 8)))
7941           (const_int 0)))]
7942   "ix86_match_ccmode (insn, CCNOmode)"
7943   "test{b}\t{%h1, %h0|%h0, %h1}"
7944   [(set_attr "type" "test")
7945    (set_attr "mode" "QI")])
7946
7947 ;; Combine likes to form bit extractions for some tests.  Humor it.
7948 (define_insn "*testqi_ext_3"
7949   [(set (reg FLAGS_REG)
7950         (compare (zero_extract:SI
7951                    (match_operand 0 "nonimmediate_operand" "rm")
7952                    (match_operand:SI 1 "const_int_operand" "")
7953                    (match_operand:SI 2 "const_int_operand" ""))
7954                  (const_int 0)))]
7955   "ix86_match_ccmode (insn, CCNOmode)
7956    && INTVAL (operands[1]) > 0
7957    && INTVAL (operands[2]) >= 0
7958    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7959    && (GET_MODE (operands[0]) == SImode
7960        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7961        || GET_MODE (operands[0]) == HImode
7962        || GET_MODE (operands[0]) == QImode)"
7963   "#")
7964
7965 (define_insn "*testqi_ext_3_rex64"
7966   [(set (reg FLAGS_REG)
7967         (compare (zero_extract:DI
7968                    (match_operand 0 "nonimmediate_operand" "rm")
7969                    (match_operand:DI 1 "const_int_operand" "")
7970                    (match_operand:DI 2 "const_int_operand" ""))
7971                  (const_int 0)))]
7972   "TARGET_64BIT
7973    && ix86_match_ccmode (insn, CCNOmode)
7974    && INTVAL (operands[1]) > 0
7975    && INTVAL (operands[2]) >= 0
7976    /* Ensure that resulting mask is zero or sign extended operand.  */
7977    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7978        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7979            && INTVAL (operands[1]) > 32))
7980    && (GET_MODE (operands[0]) == SImode
7981        || GET_MODE (operands[0]) == DImode
7982        || GET_MODE (operands[0]) == HImode
7983        || GET_MODE (operands[0]) == QImode)"
7984   "#")
7985
7986 (define_split
7987   [(set (match_operand 0 "flags_reg_operand" "")
7988         (match_operator 1 "compare_operator"
7989           [(zero_extract
7990              (match_operand 2 "nonimmediate_operand" "")
7991              (match_operand 3 "const_int_operand" "")
7992              (match_operand 4 "const_int_operand" ""))
7993            (const_int 0)]))]
7994   "ix86_match_ccmode (insn, CCNOmode)"
7995   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7996 {
7997   rtx val = operands[2];
7998   HOST_WIDE_INT len = INTVAL (operands[3]);
7999   HOST_WIDE_INT pos = INTVAL (operands[4]);
8000   HOST_WIDE_INT mask;
8001   enum machine_mode mode, submode;
8002
8003   mode = GET_MODE (val);
8004   if (GET_CODE (val) == MEM)
8005     {
8006       /* ??? Combine likes to put non-volatile mem extractions in QImode
8007          no matter the size of the test.  So find a mode that works.  */
8008       if (! MEM_VOLATILE_P (val))
8009         {
8010           mode = smallest_mode_for_size (pos + len, MODE_INT);
8011           val = adjust_address (val, mode, 0);
8012         }
8013     }
8014   else if (GET_CODE (val) == SUBREG
8015            && (submode = GET_MODE (SUBREG_REG (val)),
8016                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8017            && pos + len <= GET_MODE_BITSIZE (submode))
8018     {
8019       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8020       mode = submode;
8021       val = SUBREG_REG (val);
8022     }
8023   else if (mode == HImode && pos + len <= 8)
8024     {
8025       /* Small HImode tests can be converted to QImode.  */
8026       mode = QImode;
8027       val = gen_lowpart (QImode, val);
8028     }
8029
8030   if (len == HOST_BITS_PER_WIDE_INT)
8031     mask = -1;
8032   else
8033     mask = ((HOST_WIDE_INT)1 << len) - 1;
8034   mask <<= pos;
8035
8036   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8037 })
8038
8039 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8040 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8041 ;; this is relatively important trick.
8042 ;; Do the conversion only post-reload to avoid limiting of the register class
8043 ;; to QI regs.
8044 (define_split
8045   [(set (match_operand 0 "flags_reg_operand" "")
8046         (match_operator 1 "compare_operator"
8047           [(and (match_operand 2 "register_operand" "")
8048                 (match_operand 3 "const_int_operand" ""))
8049            (const_int 0)]))]
8050    "reload_completed
8051     && QI_REG_P (operands[2])
8052     && GET_MODE (operands[2]) != QImode
8053     && ((ix86_match_ccmode (insn, CCZmode)
8054          && !(INTVAL (operands[3]) & ~(255 << 8)))
8055         || (ix86_match_ccmode (insn, CCNOmode)
8056             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8057   [(set (match_dup 0)
8058         (match_op_dup 1
8059           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8060                    (match_dup 3))
8061            (const_int 0)]))]
8062   "operands[2] = gen_lowpart (SImode, operands[2]);
8063    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8064
8065 (define_split
8066   [(set (match_operand 0 "flags_reg_operand" "")
8067         (match_operator 1 "compare_operator"
8068           [(and (match_operand 2 "nonimmediate_operand" "")
8069                 (match_operand 3 "const_int_operand" ""))
8070            (const_int 0)]))]
8071    "reload_completed
8072     && GET_MODE (operands[2]) != QImode
8073     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8074     && ((ix86_match_ccmode (insn, CCZmode)
8075          && !(INTVAL (operands[3]) & ~255))
8076         || (ix86_match_ccmode (insn, CCNOmode)
8077             && !(INTVAL (operands[3]) & ~127)))"
8078   [(set (match_dup 0)
8079         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8080                          (const_int 0)]))]
8081   "operands[2] = gen_lowpart (QImode, operands[2]);
8082    operands[3] = gen_lowpart (QImode, operands[3]);")
8083
8084
8085 ;; %%% This used to optimize known byte-wide and operations to memory,
8086 ;; and sometimes to QImode registers.  If this is considered useful,
8087 ;; it should be done with splitters.
8088
8089 (define_expand "anddi3"
8090   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8091         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8092                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8093    (clobber (reg:CC FLAGS_REG))]
8094   "TARGET_64BIT"
8095   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8096
8097 (define_insn "*anddi_1_rex64"
8098   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8099         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8100                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8101    (clobber (reg:CC FLAGS_REG))]
8102   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8103 {
8104   switch (get_attr_type (insn))
8105     {
8106     case TYPE_IMOVX:
8107       {
8108         enum machine_mode mode;
8109
8110         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8111         if (INTVAL (operands[2]) == 0xff)
8112           mode = QImode;
8113         else
8114           {
8115             gcc_assert (INTVAL (operands[2]) == 0xffff);
8116             mode = HImode;
8117           }
8118
8119         operands[1] = gen_lowpart (mode, operands[1]);
8120         if (mode == QImode)
8121           return "movz{bq|x}\t{%1,%0|%0, %1}";
8122         else
8123           return "movz{wq|x}\t{%1,%0|%0, %1}";
8124       }
8125
8126     default:
8127       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8128       if (get_attr_mode (insn) == MODE_SI)
8129         return "and{l}\t{%k2, %k0|%k0, %k2}";
8130       else
8131         return "and{q}\t{%2, %0|%0, %2}";
8132     }
8133 }
8134   [(set_attr "type" "alu,alu,alu,imovx")
8135    (set_attr "length_immediate" "*,*,*,0")
8136    (set_attr "mode" "SI,DI,DI,DI")])
8137
8138 (define_insn "*anddi_2"
8139   [(set (reg FLAGS_REG)
8140         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8141                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8142                  (const_int 0)))
8143    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8144         (and:DI (match_dup 1) (match_dup 2)))]
8145   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8146    && ix86_binary_operator_ok (AND, DImode, operands)"
8147   "@
8148    and{l}\t{%k2, %k0|%k0, %k2}
8149    and{q}\t{%2, %0|%0, %2}
8150    and{q}\t{%2, %0|%0, %2}"
8151   [(set_attr "type" "alu")
8152    (set_attr "mode" "SI,DI,DI")])
8153
8154 (define_expand "andsi3"
8155   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8156         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8157                 (match_operand:SI 2 "general_operand" "")))
8158    (clobber (reg:CC FLAGS_REG))]
8159   ""
8160   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8161
8162 (define_insn "*andsi_1"
8163   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8164         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8165                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8166    (clobber (reg:CC FLAGS_REG))]
8167   "ix86_binary_operator_ok (AND, SImode, operands)"
8168 {
8169   switch (get_attr_type (insn))
8170     {
8171     case TYPE_IMOVX:
8172       {
8173         enum machine_mode mode;
8174
8175         gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8176         if (INTVAL (operands[2]) == 0xff)
8177           mode = QImode;
8178         else
8179           {
8180             gcc_assert (INTVAL (operands[2]) == 0xffff);
8181             mode = HImode;
8182           }
8183
8184         operands[1] = gen_lowpart (mode, operands[1]);
8185         if (mode == QImode)
8186           return "movz{bl|x}\t{%1,%0|%0, %1}";
8187         else
8188           return "movz{wl|x}\t{%1,%0|%0, %1}";
8189       }
8190
8191     default:
8192       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8193       return "and{l}\t{%2, %0|%0, %2}";
8194     }
8195 }
8196   [(set_attr "type" "alu,alu,imovx")
8197    (set_attr "length_immediate" "*,*,0")
8198    (set_attr "mode" "SI")])
8199
8200 (define_split
8201   [(set (match_operand 0 "register_operand" "")
8202         (and (match_dup 0)
8203              (const_int -65536)))
8204    (clobber (reg:CC FLAGS_REG))]
8205   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8206   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8207   "operands[1] = gen_lowpart (HImode, operands[0]);")
8208
8209 (define_split
8210   [(set (match_operand 0 "ext_register_operand" "")
8211         (and (match_dup 0)
8212              (const_int -256)))
8213    (clobber (reg:CC FLAGS_REG))]
8214   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8215   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8216   "operands[1] = gen_lowpart (QImode, operands[0]);")
8217
8218 (define_split
8219   [(set (match_operand 0 "ext_register_operand" "")
8220         (and (match_dup 0)
8221              (const_int -65281)))
8222    (clobber (reg:CC FLAGS_REG))]
8223   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8224   [(parallel [(set (zero_extract:SI (match_dup 0)
8225                                     (const_int 8)
8226                                     (const_int 8))
8227                    (xor:SI
8228                      (zero_extract:SI (match_dup 0)
8229                                       (const_int 8)
8230                                       (const_int 8))
8231                      (zero_extract:SI (match_dup 0)
8232                                       (const_int 8)
8233                                       (const_int 8))))
8234               (clobber (reg:CC FLAGS_REG))])]
8235   "operands[0] = gen_lowpart (SImode, operands[0]);")
8236
8237 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8238 (define_insn "*andsi_1_zext"
8239   [(set (match_operand:DI 0 "register_operand" "=r")
8240         (zero_extend:DI
8241           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8242                   (match_operand:SI 2 "general_operand" "rim"))))
8243    (clobber (reg:CC FLAGS_REG))]
8244   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8245   "and{l}\t{%2, %k0|%k0, %2}"
8246   [(set_attr "type" "alu")
8247    (set_attr "mode" "SI")])
8248
8249 (define_insn "*andsi_2"
8250   [(set (reg FLAGS_REG)
8251         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8252                          (match_operand:SI 2 "general_operand" "rim,ri"))
8253                  (const_int 0)))
8254    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8255         (and:SI (match_dup 1) (match_dup 2)))]
8256   "ix86_match_ccmode (insn, CCNOmode)
8257    && ix86_binary_operator_ok (AND, SImode, operands)"
8258   "and{l}\t{%2, %0|%0, %2}"
8259   [(set_attr "type" "alu")
8260    (set_attr "mode" "SI")])
8261
8262 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8263 (define_insn "*andsi_2_zext"
8264   [(set (reg FLAGS_REG)
8265         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8266                          (match_operand:SI 2 "general_operand" "rim"))
8267                  (const_int 0)))
8268    (set (match_operand:DI 0 "register_operand" "=r")
8269         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8270   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8271    && ix86_binary_operator_ok (AND, SImode, operands)"
8272   "and{l}\t{%2, %k0|%k0, %2}"
8273   [(set_attr "type" "alu")
8274    (set_attr "mode" "SI")])
8275
8276 (define_expand "andhi3"
8277   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8278         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8279                 (match_operand:HI 2 "general_operand" "")))
8280    (clobber (reg:CC FLAGS_REG))]
8281   "TARGET_HIMODE_MATH"
8282   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8283
8284 (define_insn "*andhi_1"
8285   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8286         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8287                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8288    (clobber (reg:CC FLAGS_REG))]
8289   "ix86_binary_operator_ok (AND, HImode, operands)"
8290 {
8291   switch (get_attr_type (insn))
8292     {
8293     case TYPE_IMOVX:
8294       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8295       gcc_assert (INTVAL (operands[2]) == 0xff);
8296       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8297
8298     default:
8299       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8300
8301       return "and{w}\t{%2, %0|%0, %2}";
8302     }
8303 }
8304   [(set_attr "type" "alu,alu,imovx")
8305    (set_attr "length_immediate" "*,*,0")
8306    (set_attr "mode" "HI,HI,SI")])
8307
8308 (define_insn "*andhi_2"
8309   [(set (reg FLAGS_REG)
8310         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8311                          (match_operand:HI 2 "general_operand" "rim,ri"))
8312                  (const_int 0)))
8313    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8314         (and:HI (match_dup 1) (match_dup 2)))]
8315   "ix86_match_ccmode (insn, CCNOmode)
8316    && ix86_binary_operator_ok (AND, HImode, operands)"
8317   "and{w}\t{%2, %0|%0, %2}"
8318   [(set_attr "type" "alu")
8319    (set_attr "mode" "HI")])
8320
8321 (define_expand "andqi3"
8322   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8323         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8324                 (match_operand:QI 2 "general_operand" "")))
8325    (clobber (reg:CC FLAGS_REG))]
8326   "TARGET_QIMODE_MATH"
8327   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8328
8329 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8330 (define_insn "*andqi_1"
8331   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8332         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8333                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8334    (clobber (reg:CC FLAGS_REG))]
8335   "ix86_binary_operator_ok (AND, QImode, operands)"
8336   "@
8337    and{b}\t{%2, %0|%0, %2}
8338    and{b}\t{%2, %0|%0, %2}
8339    and{l}\t{%k2, %k0|%k0, %k2}"
8340   [(set_attr "type" "alu")
8341    (set_attr "mode" "QI,QI,SI")])
8342
8343 (define_insn "*andqi_1_slp"
8344   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8345         (and:QI (match_dup 0)
8346                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8347    (clobber (reg:CC FLAGS_REG))]
8348   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8349    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8350   "and{b}\t{%1, %0|%0, %1}"
8351   [(set_attr "type" "alu1")
8352    (set_attr "mode" "QI")])
8353
8354 (define_insn "*andqi_2_maybe_si"
8355   [(set (reg FLAGS_REG)
8356         (compare (and:QI
8357                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8358                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8359                  (const_int 0)))
8360    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8361         (and:QI (match_dup 1) (match_dup 2)))]
8362   "ix86_binary_operator_ok (AND, QImode, operands)
8363    && ix86_match_ccmode (insn,
8364                          GET_CODE (operands[2]) == CONST_INT
8365                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8366 {
8367   if (which_alternative == 2)
8368     {
8369       if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8370         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8371       return "and{l}\t{%2, %k0|%k0, %2}";
8372     }
8373   return "and{b}\t{%2, %0|%0, %2}";
8374 }
8375   [(set_attr "type" "alu")
8376    (set_attr "mode" "QI,QI,SI")])
8377
8378 (define_insn "*andqi_2"
8379   [(set (reg FLAGS_REG)
8380         (compare (and:QI
8381                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8382                    (match_operand:QI 2 "general_operand" "qim,qi"))
8383                  (const_int 0)))
8384    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8385         (and:QI (match_dup 1) (match_dup 2)))]
8386   "ix86_match_ccmode (insn, CCNOmode)
8387    && ix86_binary_operator_ok (AND, QImode, operands)"
8388   "and{b}\t{%2, %0|%0, %2}"
8389   [(set_attr "type" "alu")
8390    (set_attr "mode" "QI")])
8391
8392 (define_insn "*andqi_2_slp"
8393   [(set (reg FLAGS_REG)
8394         (compare (and:QI
8395                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8396                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8397                  (const_int 0)))
8398    (set (strict_low_part (match_dup 0))
8399         (and:QI (match_dup 0) (match_dup 1)))]
8400   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8401    && ix86_match_ccmode (insn, CCNOmode)
8402    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8403   "and{b}\t{%1, %0|%0, %1}"
8404   [(set_attr "type" "alu1")
8405    (set_attr "mode" "QI")])
8406
8407 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8408 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8409 ;; for a QImode operand, which of course failed.
8410
8411 (define_insn "andqi_ext_0"
8412   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8413                          (const_int 8)
8414                          (const_int 8))
8415         (and:SI
8416           (zero_extract:SI
8417             (match_operand 1 "ext_register_operand" "0")
8418             (const_int 8)
8419             (const_int 8))
8420           (match_operand 2 "const_int_operand" "n")))
8421    (clobber (reg:CC FLAGS_REG))]
8422   ""
8423   "and{b}\t{%2, %h0|%h0, %2}"
8424   [(set_attr "type" "alu")
8425    (set_attr "length_immediate" "1")
8426    (set_attr "mode" "QI")])
8427
8428 ;; Generated by peephole translating test to and.  This shows up
8429 ;; often in fp comparisons.
8430
8431 (define_insn "*andqi_ext_0_cc"
8432   [(set (reg FLAGS_REG)
8433         (compare
8434           (and:SI
8435             (zero_extract:SI
8436               (match_operand 1 "ext_register_operand" "0")
8437               (const_int 8)
8438               (const_int 8))
8439             (match_operand 2 "const_int_operand" "n"))
8440           (const_int 0)))
8441    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8442                          (const_int 8)
8443                          (const_int 8))
8444         (and:SI
8445           (zero_extract:SI
8446             (match_dup 1)
8447             (const_int 8)
8448             (const_int 8))
8449           (match_dup 2)))]
8450   "ix86_match_ccmode (insn, CCNOmode)"
8451   "and{b}\t{%2, %h0|%h0, %2}"
8452   [(set_attr "type" "alu")
8453    (set_attr "length_immediate" "1")
8454    (set_attr "mode" "QI")])
8455
8456 (define_insn "*andqi_ext_1"
8457   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8458                          (const_int 8)
8459                          (const_int 8))
8460         (and:SI
8461           (zero_extract:SI
8462             (match_operand 1 "ext_register_operand" "0")
8463             (const_int 8)
8464             (const_int 8))
8465           (zero_extend:SI
8466             (match_operand:QI 2 "general_operand" "Qm"))))
8467    (clobber (reg:CC FLAGS_REG))]
8468   "!TARGET_64BIT"
8469   "and{b}\t{%2, %h0|%h0, %2}"
8470   [(set_attr "type" "alu")
8471    (set_attr "length_immediate" "0")
8472    (set_attr "mode" "QI")])
8473
8474 (define_insn "*andqi_ext_1_rex64"
8475   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8476                          (const_int 8)
8477                          (const_int 8))
8478         (and:SI
8479           (zero_extract:SI
8480             (match_operand 1 "ext_register_operand" "0")
8481             (const_int 8)
8482             (const_int 8))
8483           (zero_extend:SI
8484             (match_operand 2 "ext_register_operand" "Q"))))
8485    (clobber (reg:CC FLAGS_REG))]
8486   "TARGET_64BIT"
8487   "and{b}\t{%2, %h0|%h0, %2}"
8488   [(set_attr "type" "alu")
8489    (set_attr "length_immediate" "0")
8490    (set_attr "mode" "QI")])
8491
8492 (define_insn "*andqi_ext_2"
8493   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8494                          (const_int 8)
8495                          (const_int 8))
8496         (and:SI
8497           (zero_extract:SI
8498             (match_operand 1 "ext_register_operand" "%0")
8499             (const_int 8)
8500             (const_int 8))
8501           (zero_extract:SI
8502             (match_operand 2 "ext_register_operand" "Q")
8503             (const_int 8)
8504             (const_int 8))))
8505    (clobber (reg:CC FLAGS_REG))]
8506   ""
8507   "and{b}\t{%h2, %h0|%h0, %h2}"
8508   [(set_attr "type" "alu")
8509    (set_attr "length_immediate" "0")
8510    (set_attr "mode" "QI")])
8511
8512 ;; Convert wide AND instructions with immediate operand to shorter QImode
8513 ;; equivalents when possible.
8514 ;; Don't do the splitting with memory operands, since it introduces risk
8515 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8516 ;; for size, but that can (should?) be handled by generic code instead.
8517 (define_split
8518   [(set (match_operand 0 "register_operand" "")
8519         (and (match_operand 1 "register_operand" "")
8520              (match_operand 2 "const_int_operand" "")))
8521    (clobber (reg:CC FLAGS_REG))]
8522    "reload_completed
8523     && QI_REG_P (operands[0])
8524     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8525     && !(~INTVAL (operands[2]) & ~(255 << 8))
8526     && GET_MODE (operands[0]) != QImode"
8527   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8528                    (and:SI (zero_extract:SI (match_dup 1)
8529                                             (const_int 8) (const_int 8))
8530                            (match_dup 2)))
8531               (clobber (reg:CC FLAGS_REG))])]
8532   "operands[0] = gen_lowpart (SImode, operands[0]);
8533    operands[1] = gen_lowpart (SImode, operands[1]);
8534    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8535
8536 ;; Since AND can be encoded with sign extended immediate, this is only
8537 ;; profitable when 7th bit is not set.
8538 (define_split
8539   [(set (match_operand 0 "register_operand" "")
8540         (and (match_operand 1 "general_operand" "")
8541              (match_operand 2 "const_int_operand" "")))
8542    (clobber (reg:CC FLAGS_REG))]
8543    "reload_completed
8544     && ANY_QI_REG_P (operands[0])
8545     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8546     && !(~INTVAL (operands[2]) & ~255)
8547     && !(INTVAL (operands[2]) & 128)
8548     && GET_MODE (operands[0]) != QImode"
8549   [(parallel [(set (strict_low_part (match_dup 0))
8550                    (and:QI (match_dup 1)
8551                            (match_dup 2)))
8552               (clobber (reg:CC FLAGS_REG))])]
8553   "operands[0] = gen_lowpart (QImode, operands[0]);
8554    operands[1] = gen_lowpart (QImode, operands[1]);
8555    operands[2] = gen_lowpart (QImode, operands[2]);")
8556 \f
8557 ;; Logical inclusive OR instructions
8558
8559 ;; %%% This used to optimize known byte-wide and operations to memory.
8560 ;; If this is considered useful, it should be done with splitters.
8561
8562 (define_expand "iordi3"
8563   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8564         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8565                 (match_operand:DI 2 "x86_64_general_operand" "")))
8566    (clobber (reg:CC FLAGS_REG))]
8567   "TARGET_64BIT"
8568   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8569
8570 (define_insn "*iordi_1_rex64"
8571   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8572         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8573                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8574    (clobber (reg:CC FLAGS_REG))]
8575   "TARGET_64BIT
8576    && ix86_binary_operator_ok (IOR, DImode, operands)"
8577   "or{q}\t{%2, %0|%0, %2}"
8578   [(set_attr "type" "alu")
8579    (set_attr "mode" "DI")])
8580
8581 (define_insn "*iordi_2_rex64"
8582   [(set (reg FLAGS_REG)
8583         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8584                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8585                  (const_int 0)))
8586    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8587         (ior:DI (match_dup 1) (match_dup 2)))]
8588   "TARGET_64BIT
8589    && ix86_match_ccmode (insn, CCNOmode)
8590    && ix86_binary_operator_ok (IOR, DImode, operands)"
8591   "or{q}\t{%2, %0|%0, %2}"
8592   [(set_attr "type" "alu")
8593    (set_attr "mode" "DI")])
8594
8595 (define_insn "*iordi_3_rex64"
8596   [(set (reg FLAGS_REG)
8597         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8598                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8599                  (const_int 0)))
8600    (clobber (match_scratch:DI 0 "=r"))]
8601   "TARGET_64BIT
8602    && ix86_match_ccmode (insn, CCNOmode)
8603    && ix86_binary_operator_ok (IOR, DImode, operands)"
8604   "or{q}\t{%2, %0|%0, %2}"
8605   [(set_attr "type" "alu")
8606    (set_attr "mode" "DI")])
8607
8608
8609 (define_expand "iorsi3"
8610   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8611         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8612                 (match_operand:SI 2 "general_operand" "")))
8613    (clobber (reg:CC FLAGS_REG))]
8614   ""
8615   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8616
8617 (define_insn "*iorsi_1"
8618   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8619         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8620                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8621    (clobber (reg:CC FLAGS_REG))]
8622   "ix86_binary_operator_ok (IOR, SImode, operands)"
8623   "or{l}\t{%2, %0|%0, %2}"
8624   [(set_attr "type" "alu")
8625    (set_attr "mode" "SI")])
8626
8627 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8628 (define_insn "*iorsi_1_zext"
8629   [(set (match_operand:DI 0 "register_operand" "=rm")
8630         (zero_extend:DI
8631           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8632                   (match_operand:SI 2 "general_operand" "rim"))))
8633    (clobber (reg:CC FLAGS_REG))]
8634   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8635   "or{l}\t{%2, %k0|%k0, %2}"
8636   [(set_attr "type" "alu")
8637    (set_attr "mode" "SI")])
8638
8639 (define_insn "*iorsi_1_zext_imm"
8640   [(set (match_operand:DI 0 "register_operand" "=rm")
8641         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8642                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8643    (clobber (reg:CC FLAGS_REG))]
8644   "TARGET_64BIT"
8645   "or{l}\t{%2, %k0|%k0, %2}"
8646   [(set_attr "type" "alu")
8647    (set_attr "mode" "SI")])
8648
8649 (define_insn "*iorsi_2"
8650   [(set (reg FLAGS_REG)
8651         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8652                          (match_operand:SI 2 "general_operand" "rim,ri"))
8653                  (const_int 0)))
8654    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8655         (ior:SI (match_dup 1) (match_dup 2)))]
8656   "ix86_match_ccmode (insn, CCNOmode)
8657    && ix86_binary_operator_ok (IOR, SImode, operands)"
8658   "or{l}\t{%2, %0|%0, %2}"
8659   [(set_attr "type" "alu")
8660    (set_attr "mode" "SI")])
8661
8662 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8663 ;; ??? Special case for immediate operand is missing - it is tricky.
8664 (define_insn "*iorsi_2_zext"
8665   [(set (reg FLAGS_REG)
8666         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8667                          (match_operand:SI 2 "general_operand" "rim"))
8668                  (const_int 0)))
8669    (set (match_operand:DI 0 "register_operand" "=r")
8670         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8671   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8672    && ix86_binary_operator_ok (IOR, SImode, operands)"
8673   "or{l}\t{%2, %k0|%k0, %2}"
8674   [(set_attr "type" "alu")
8675    (set_attr "mode" "SI")])
8676
8677 (define_insn "*iorsi_2_zext_imm"
8678   [(set (reg FLAGS_REG)
8679         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8680                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8681                  (const_int 0)))
8682    (set (match_operand:DI 0 "register_operand" "=r")
8683         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8684   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8685    && ix86_binary_operator_ok (IOR, SImode, operands)"
8686   "or{l}\t{%2, %k0|%k0, %2}"
8687   [(set_attr "type" "alu")
8688    (set_attr "mode" "SI")])
8689
8690 (define_insn "*iorsi_3"
8691   [(set (reg FLAGS_REG)
8692         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8693                          (match_operand:SI 2 "general_operand" "rim"))
8694                  (const_int 0)))
8695    (clobber (match_scratch:SI 0 "=r"))]
8696   "ix86_match_ccmode (insn, CCNOmode)
8697    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8698   "or{l}\t{%2, %0|%0, %2}"
8699   [(set_attr "type" "alu")
8700    (set_attr "mode" "SI")])
8701
8702 (define_expand "iorhi3"
8703   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8704         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8705                 (match_operand:HI 2 "general_operand" "")))
8706    (clobber (reg:CC FLAGS_REG))]
8707   "TARGET_HIMODE_MATH"
8708   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8709
8710 (define_insn "*iorhi_1"
8711   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8712         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8713                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8714    (clobber (reg:CC FLAGS_REG))]
8715   "ix86_binary_operator_ok (IOR, HImode, operands)"
8716   "or{w}\t{%2, %0|%0, %2}"
8717   [(set_attr "type" "alu")
8718    (set_attr "mode" "HI")])
8719
8720 (define_insn "*iorhi_2"
8721   [(set (reg FLAGS_REG)
8722         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8723                          (match_operand:HI 2 "general_operand" "rim,ri"))
8724                  (const_int 0)))
8725    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8726         (ior:HI (match_dup 1) (match_dup 2)))]
8727   "ix86_match_ccmode (insn, CCNOmode)
8728    && ix86_binary_operator_ok (IOR, HImode, operands)"
8729   "or{w}\t{%2, %0|%0, %2}"
8730   [(set_attr "type" "alu")
8731    (set_attr "mode" "HI")])
8732
8733 (define_insn "*iorhi_3"
8734   [(set (reg FLAGS_REG)
8735         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8736                          (match_operand:HI 2 "general_operand" "rim"))
8737                  (const_int 0)))
8738    (clobber (match_scratch:HI 0 "=r"))]
8739   "ix86_match_ccmode (insn, CCNOmode)
8740    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8741   "or{w}\t{%2, %0|%0, %2}"
8742   [(set_attr "type" "alu")
8743    (set_attr "mode" "HI")])
8744
8745 (define_expand "iorqi3"
8746   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8747         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8748                 (match_operand:QI 2 "general_operand" "")))
8749    (clobber (reg:CC FLAGS_REG))]
8750   "TARGET_QIMODE_MATH"
8751   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8752
8753 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8754 (define_insn "*iorqi_1"
8755   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8756         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8757                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8758    (clobber (reg:CC FLAGS_REG))]
8759   "ix86_binary_operator_ok (IOR, QImode, operands)"
8760   "@
8761    or{b}\t{%2, %0|%0, %2}
8762    or{b}\t{%2, %0|%0, %2}
8763    or{l}\t{%k2, %k0|%k0, %k2}"
8764   [(set_attr "type" "alu")
8765    (set_attr "mode" "QI,QI,SI")])
8766
8767 (define_insn "*iorqi_1_slp"
8768   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8769         (ior:QI (match_dup 0)
8770                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8771    (clobber (reg:CC FLAGS_REG))]
8772   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8773    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8774   "or{b}\t{%1, %0|%0, %1}"
8775   [(set_attr "type" "alu1")
8776    (set_attr "mode" "QI")])
8777
8778 (define_insn "*iorqi_2"
8779   [(set (reg FLAGS_REG)
8780         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8781                          (match_operand:QI 2 "general_operand" "qim,qi"))
8782                  (const_int 0)))
8783    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8784         (ior:QI (match_dup 1) (match_dup 2)))]
8785   "ix86_match_ccmode (insn, CCNOmode)
8786    && ix86_binary_operator_ok (IOR, QImode, operands)"
8787   "or{b}\t{%2, %0|%0, %2}"
8788   [(set_attr "type" "alu")
8789    (set_attr "mode" "QI")])
8790
8791 (define_insn "*iorqi_2_slp"
8792   [(set (reg FLAGS_REG)
8793         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8794                          (match_operand:QI 1 "general_operand" "qim,qi"))
8795                  (const_int 0)))
8796    (set (strict_low_part (match_dup 0))
8797         (ior:QI (match_dup 0) (match_dup 1)))]
8798   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8799    && ix86_match_ccmode (insn, CCNOmode)
8800    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8801   "or{b}\t{%1, %0|%0, %1}"
8802   [(set_attr "type" "alu1")
8803    (set_attr "mode" "QI")])
8804
8805 (define_insn "*iorqi_3"
8806   [(set (reg FLAGS_REG)
8807         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8808                          (match_operand:QI 2 "general_operand" "qim"))
8809                  (const_int 0)))
8810    (clobber (match_scratch:QI 0 "=q"))]
8811   "ix86_match_ccmode (insn, CCNOmode)
8812    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8813   "or{b}\t{%2, %0|%0, %2}"
8814   [(set_attr "type" "alu")
8815    (set_attr "mode" "QI")])
8816
8817 (define_insn "iorqi_ext_0"
8818   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8819                          (const_int 8)
8820                          (const_int 8))
8821         (ior:SI
8822           (zero_extract:SI
8823             (match_operand 1 "ext_register_operand" "0")
8824             (const_int 8)
8825             (const_int 8))
8826           (match_operand 2 "const_int_operand" "n")))
8827    (clobber (reg:CC FLAGS_REG))]
8828   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8829   "or{b}\t{%2, %h0|%h0, %2}"
8830   [(set_attr "type" "alu")
8831    (set_attr "length_immediate" "1")
8832    (set_attr "mode" "QI")])
8833
8834 (define_insn "*iorqi_ext_1"
8835   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8836                          (const_int 8)
8837                          (const_int 8))
8838         (ior:SI
8839           (zero_extract:SI
8840             (match_operand 1 "ext_register_operand" "0")
8841             (const_int 8)
8842             (const_int 8))
8843           (zero_extend:SI
8844             (match_operand:QI 2 "general_operand" "Qm"))))
8845    (clobber (reg:CC FLAGS_REG))]
8846   "!TARGET_64BIT
8847    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8848   "or{b}\t{%2, %h0|%h0, %2}"
8849   [(set_attr "type" "alu")
8850    (set_attr "length_immediate" "0")
8851    (set_attr "mode" "QI")])
8852
8853 (define_insn "*iorqi_ext_1_rex64"
8854   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8855                          (const_int 8)
8856                          (const_int 8))
8857         (ior:SI
8858           (zero_extract:SI
8859             (match_operand 1 "ext_register_operand" "0")
8860             (const_int 8)
8861             (const_int 8))
8862           (zero_extend:SI
8863             (match_operand 2 "ext_register_operand" "Q"))))
8864    (clobber (reg:CC FLAGS_REG))]
8865   "TARGET_64BIT
8866    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8867   "or{b}\t{%2, %h0|%h0, %2}"
8868   [(set_attr "type" "alu")
8869    (set_attr "length_immediate" "0")
8870    (set_attr "mode" "QI")])
8871
8872 (define_insn "*iorqi_ext_2"
8873   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8874                          (const_int 8)
8875                          (const_int 8))
8876         (ior:SI
8877           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8878                            (const_int 8)
8879                            (const_int 8))
8880           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8881                            (const_int 8)
8882                            (const_int 8))))
8883    (clobber (reg:CC FLAGS_REG))]
8884   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8885   "ior{b}\t{%h2, %h0|%h0, %h2}"
8886   [(set_attr "type" "alu")
8887    (set_attr "length_immediate" "0")
8888    (set_attr "mode" "QI")])
8889
8890 (define_split
8891   [(set (match_operand 0 "register_operand" "")
8892         (ior (match_operand 1 "register_operand" "")
8893              (match_operand 2 "const_int_operand" "")))
8894    (clobber (reg:CC FLAGS_REG))]
8895    "reload_completed
8896     && QI_REG_P (operands[0])
8897     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8898     && !(INTVAL (operands[2]) & ~(255 << 8))
8899     && GET_MODE (operands[0]) != QImode"
8900   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8901                    (ior:SI (zero_extract:SI (match_dup 1)
8902                                             (const_int 8) (const_int 8))
8903                            (match_dup 2)))
8904               (clobber (reg:CC FLAGS_REG))])]
8905   "operands[0] = gen_lowpart (SImode, operands[0]);
8906    operands[1] = gen_lowpart (SImode, operands[1]);
8907    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8908
8909 ;; Since OR can be encoded with sign extended immediate, this is only
8910 ;; profitable when 7th bit is set.
8911 (define_split
8912   [(set (match_operand 0 "register_operand" "")
8913         (ior (match_operand 1 "general_operand" "")
8914              (match_operand 2 "const_int_operand" "")))
8915    (clobber (reg:CC FLAGS_REG))]
8916    "reload_completed
8917     && ANY_QI_REG_P (operands[0])
8918     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8919     && !(INTVAL (operands[2]) & ~255)
8920     && (INTVAL (operands[2]) & 128)
8921     && GET_MODE (operands[0]) != QImode"
8922   [(parallel [(set (strict_low_part (match_dup 0))
8923                    (ior:QI (match_dup 1)
8924                            (match_dup 2)))
8925               (clobber (reg:CC FLAGS_REG))])]
8926   "operands[0] = gen_lowpart (QImode, operands[0]);
8927    operands[1] = gen_lowpart (QImode, operands[1]);
8928    operands[2] = gen_lowpart (QImode, operands[2]);")
8929 \f
8930 ;; Logical XOR instructions
8931
8932 ;; %%% This used to optimize known byte-wide and operations to memory.
8933 ;; If this is considered useful, it should be done with splitters.
8934
8935 (define_expand "xordi3"
8936   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8937         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8938                 (match_operand:DI 2 "x86_64_general_operand" "")))
8939    (clobber (reg:CC FLAGS_REG))]
8940   "TARGET_64BIT"
8941   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8942
8943 (define_insn "*xordi_1_rex64"
8944   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8945         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8946                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8947    (clobber (reg:CC FLAGS_REG))]
8948   "TARGET_64BIT
8949    && ix86_binary_operator_ok (XOR, DImode, operands)"
8950   "@
8951    xor{q}\t{%2, %0|%0, %2}
8952    xor{q}\t{%2, %0|%0, %2}"
8953   [(set_attr "type" "alu")
8954    (set_attr "mode" "DI,DI")])
8955
8956 (define_insn "*xordi_2_rex64"
8957   [(set (reg FLAGS_REG)
8958         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8959                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8960                  (const_int 0)))
8961    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8962         (xor:DI (match_dup 1) (match_dup 2)))]
8963   "TARGET_64BIT
8964    && ix86_match_ccmode (insn, CCNOmode)
8965    && ix86_binary_operator_ok (XOR, DImode, operands)"
8966   "@
8967    xor{q}\t{%2, %0|%0, %2}
8968    xor{q}\t{%2, %0|%0, %2}"
8969   [(set_attr "type" "alu")
8970    (set_attr "mode" "DI,DI")])
8971
8972 (define_insn "*xordi_3_rex64"
8973   [(set (reg FLAGS_REG)
8974         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8975                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8976                  (const_int 0)))
8977    (clobber (match_scratch:DI 0 "=r"))]
8978   "TARGET_64BIT
8979    && ix86_match_ccmode (insn, CCNOmode)
8980    && ix86_binary_operator_ok (XOR, DImode, operands)"
8981   "xor{q}\t{%2, %0|%0, %2}"
8982   [(set_attr "type" "alu")
8983    (set_attr "mode" "DI")])
8984
8985 (define_expand "xorsi3"
8986   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8987         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8988                 (match_operand:SI 2 "general_operand" "")))
8989    (clobber (reg:CC FLAGS_REG))]
8990   ""
8991   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8992
8993 (define_insn "*xorsi_1"
8994   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8995         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8996                 (match_operand:SI 2 "general_operand" "ri,rm")))
8997    (clobber (reg:CC FLAGS_REG))]
8998   "ix86_binary_operator_ok (XOR, SImode, operands)"
8999   "xor{l}\t{%2, %0|%0, %2}"
9000   [(set_attr "type" "alu")
9001    (set_attr "mode" "SI")])
9002
9003 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9004 ;; Add speccase for immediates
9005 (define_insn "*xorsi_1_zext"
9006   [(set (match_operand:DI 0 "register_operand" "=r")
9007         (zero_extend:DI
9008           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9009                   (match_operand:SI 2 "general_operand" "rim"))))
9010    (clobber (reg:CC FLAGS_REG))]
9011   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9012   "xor{l}\t{%2, %k0|%k0, %2}"
9013   [(set_attr "type" "alu")
9014    (set_attr "mode" "SI")])
9015
9016 (define_insn "*xorsi_1_zext_imm"
9017   [(set (match_operand:DI 0 "register_operand" "=r")
9018         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9019                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9020    (clobber (reg:CC FLAGS_REG))]
9021   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9022   "xor{l}\t{%2, %k0|%k0, %2}"
9023   [(set_attr "type" "alu")
9024    (set_attr "mode" "SI")])
9025
9026 (define_insn "*xorsi_2"
9027   [(set (reg FLAGS_REG)
9028         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9029                          (match_operand:SI 2 "general_operand" "rim,ri"))
9030                  (const_int 0)))
9031    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9032         (xor:SI (match_dup 1) (match_dup 2)))]
9033   "ix86_match_ccmode (insn, CCNOmode)
9034    && ix86_binary_operator_ok (XOR, SImode, operands)"
9035   "xor{l}\t{%2, %0|%0, %2}"
9036   [(set_attr "type" "alu")
9037    (set_attr "mode" "SI")])
9038
9039 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9040 ;; ??? Special case for immediate operand is missing - it is tricky.
9041 (define_insn "*xorsi_2_zext"
9042   [(set (reg FLAGS_REG)
9043         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9044                          (match_operand:SI 2 "general_operand" "rim"))
9045                  (const_int 0)))
9046    (set (match_operand:DI 0 "register_operand" "=r")
9047         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9048   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9049    && ix86_binary_operator_ok (XOR, SImode, operands)"
9050   "xor{l}\t{%2, %k0|%k0, %2}"
9051   [(set_attr "type" "alu")
9052    (set_attr "mode" "SI")])
9053
9054 (define_insn "*xorsi_2_zext_imm"
9055   [(set (reg FLAGS_REG)
9056         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9057                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9058                  (const_int 0)))
9059    (set (match_operand:DI 0 "register_operand" "=r")
9060         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9061   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9062    && ix86_binary_operator_ok (XOR, SImode, operands)"
9063   "xor{l}\t{%2, %k0|%k0, %2}"
9064   [(set_attr "type" "alu")
9065    (set_attr "mode" "SI")])
9066
9067 (define_insn "*xorsi_3"
9068   [(set (reg FLAGS_REG)
9069         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9070                          (match_operand:SI 2 "general_operand" "rim"))
9071                  (const_int 0)))
9072    (clobber (match_scratch:SI 0 "=r"))]
9073   "ix86_match_ccmode (insn, CCNOmode)
9074    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9075   "xor{l}\t{%2, %0|%0, %2}"
9076   [(set_attr "type" "alu")
9077    (set_attr "mode" "SI")])
9078
9079 (define_expand "xorhi3"
9080   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9081         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9082                 (match_operand:HI 2 "general_operand" "")))
9083    (clobber (reg:CC FLAGS_REG))]
9084   "TARGET_HIMODE_MATH"
9085   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9086
9087 (define_insn "*xorhi_1"
9088   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9089         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9090                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9091    (clobber (reg:CC FLAGS_REG))]
9092   "ix86_binary_operator_ok (XOR, HImode, operands)"
9093   "xor{w}\t{%2, %0|%0, %2}"
9094   [(set_attr "type" "alu")
9095    (set_attr "mode" "HI")])
9096
9097 (define_insn "*xorhi_2"
9098   [(set (reg FLAGS_REG)
9099         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9100                          (match_operand:HI 2 "general_operand" "rim,ri"))
9101                  (const_int 0)))
9102    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9103         (xor:HI (match_dup 1) (match_dup 2)))]
9104   "ix86_match_ccmode (insn, CCNOmode)
9105    && ix86_binary_operator_ok (XOR, HImode, operands)"
9106   "xor{w}\t{%2, %0|%0, %2}"
9107   [(set_attr "type" "alu")
9108    (set_attr "mode" "HI")])
9109
9110 (define_insn "*xorhi_3"
9111   [(set (reg FLAGS_REG)
9112         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9113                          (match_operand:HI 2 "general_operand" "rim"))
9114                  (const_int 0)))
9115    (clobber (match_scratch:HI 0 "=r"))]
9116   "ix86_match_ccmode (insn, CCNOmode)
9117    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9118   "xor{w}\t{%2, %0|%0, %2}"
9119   [(set_attr "type" "alu")
9120    (set_attr "mode" "HI")])
9121
9122 (define_expand "xorqi3"
9123   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9124         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9125                 (match_operand:QI 2 "general_operand" "")))
9126    (clobber (reg:CC FLAGS_REG))]
9127   "TARGET_QIMODE_MATH"
9128   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9129
9130 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9131 (define_insn "*xorqi_1"
9132   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9133         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9134                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9135    (clobber (reg:CC FLAGS_REG))]
9136   "ix86_binary_operator_ok (XOR, QImode, operands)"
9137   "@
9138    xor{b}\t{%2, %0|%0, %2}
9139    xor{b}\t{%2, %0|%0, %2}
9140    xor{l}\t{%k2, %k0|%k0, %k2}"
9141   [(set_attr "type" "alu")
9142    (set_attr "mode" "QI,QI,SI")])
9143
9144 (define_insn "*xorqi_1_slp"
9145   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9146         (xor:QI (match_dup 0)
9147                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9148    (clobber (reg:CC FLAGS_REG))]
9149   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9150    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9151   "xor{b}\t{%1, %0|%0, %1}"
9152   [(set_attr "type" "alu1")
9153    (set_attr "mode" "QI")])
9154
9155 (define_insn "xorqi_ext_0"
9156   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9157                          (const_int 8)
9158                          (const_int 8))
9159         (xor:SI
9160           (zero_extract:SI
9161             (match_operand 1 "ext_register_operand" "0")
9162             (const_int 8)
9163             (const_int 8))
9164           (match_operand 2 "const_int_operand" "n")))
9165    (clobber (reg:CC FLAGS_REG))]
9166   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9167   "xor{b}\t{%2, %h0|%h0, %2}"
9168   [(set_attr "type" "alu")
9169    (set_attr "length_immediate" "1")
9170    (set_attr "mode" "QI")])
9171
9172 (define_insn "*xorqi_ext_1"
9173   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9174                          (const_int 8)
9175                          (const_int 8))
9176         (xor:SI
9177           (zero_extract:SI
9178             (match_operand 1 "ext_register_operand" "0")
9179             (const_int 8)
9180             (const_int 8))
9181           (zero_extend:SI
9182             (match_operand:QI 2 "general_operand" "Qm"))))
9183    (clobber (reg:CC FLAGS_REG))]
9184   "!TARGET_64BIT
9185    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9186   "xor{b}\t{%2, %h0|%h0, %2}"
9187   [(set_attr "type" "alu")
9188    (set_attr "length_immediate" "0")
9189    (set_attr "mode" "QI")])
9190
9191 (define_insn "*xorqi_ext_1_rex64"
9192   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9193                          (const_int 8)
9194                          (const_int 8))
9195         (xor:SI
9196           (zero_extract:SI
9197             (match_operand 1 "ext_register_operand" "0")
9198             (const_int 8)
9199             (const_int 8))
9200           (zero_extend:SI
9201             (match_operand 2 "ext_register_operand" "Q"))))
9202    (clobber (reg:CC FLAGS_REG))]
9203   "TARGET_64BIT
9204    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9205   "xor{b}\t{%2, %h0|%h0, %2}"
9206   [(set_attr "type" "alu")
9207    (set_attr "length_immediate" "0")
9208    (set_attr "mode" "QI")])
9209
9210 (define_insn "*xorqi_ext_2"
9211   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9212                          (const_int 8)
9213                          (const_int 8))
9214         (xor:SI
9215           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9216                            (const_int 8)
9217                            (const_int 8))
9218           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9219                            (const_int 8)
9220                            (const_int 8))))
9221    (clobber (reg:CC FLAGS_REG))]
9222   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9223   "xor{b}\t{%h2, %h0|%h0, %h2}"
9224   [(set_attr "type" "alu")
9225    (set_attr "length_immediate" "0")
9226    (set_attr "mode" "QI")])
9227
9228 (define_insn "*xorqi_cc_1"
9229   [(set (reg FLAGS_REG)
9230         (compare
9231           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9232                   (match_operand:QI 2 "general_operand" "qim,qi"))
9233           (const_int 0)))
9234    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9235         (xor:QI (match_dup 1) (match_dup 2)))]
9236   "ix86_match_ccmode (insn, CCNOmode)
9237    && ix86_binary_operator_ok (XOR, QImode, operands)"
9238   "xor{b}\t{%2, %0|%0, %2}"
9239   [(set_attr "type" "alu")
9240    (set_attr "mode" "QI")])
9241
9242 (define_insn "*xorqi_2_slp"
9243   [(set (reg FLAGS_REG)
9244         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9245                          (match_operand:QI 1 "general_operand" "qim,qi"))
9246                  (const_int 0)))
9247    (set (strict_low_part (match_dup 0))
9248         (xor:QI (match_dup 0) (match_dup 1)))]
9249   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9250    && ix86_match_ccmode (insn, CCNOmode)
9251    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9252   "xor{b}\t{%1, %0|%0, %1}"
9253   [(set_attr "type" "alu1")
9254    (set_attr "mode" "QI")])
9255
9256 (define_insn "*xorqi_cc_2"
9257   [(set (reg FLAGS_REG)
9258         (compare
9259           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9260                   (match_operand:QI 2 "general_operand" "qim"))
9261           (const_int 0)))
9262    (clobber (match_scratch:QI 0 "=q"))]
9263   "ix86_match_ccmode (insn, CCNOmode)
9264    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9265   "xor{b}\t{%2, %0|%0, %2}"
9266   [(set_attr "type" "alu")
9267    (set_attr "mode" "QI")])
9268
9269 (define_insn "*xorqi_cc_ext_1"
9270   [(set (reg FLAGS_REG)
9271         (compare
9272           (xor:SI
9273             (zero_extract:SI
9274               (match_operand 1 "ext_register_operand" "0")
9275               (const_int 8)
9276               (const_int 8))
9277             (match_operand:QI 2 "general_operand" "qmn"))
9278           (const_int 0)))
9279    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9280                          (const_int 8)
9281                          (const_int 8))
9282         (xor:SI
9283           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9284           (match_dup 2)))]
9285   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9286   "xor{b}\t{%2, %h0|%h0, %2}"
9287   [(set_attr "type" "alu")
9288    (set_attr "mode" "QI")])
9289
9290 (define_insn "*xorqi_cc_ext_1_rex64"
9291   [(set (reg FLAGS_REG)
9292         (compare
9293           (xor:SI
9294             (zero_extract:SI
9295               (match_operand 1 "ext_register_operand" "0")
9296               (const_int 8)
9297               (const_int 8))
9298             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9299           (const_int 0)))
9300    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9301                          (const_int 8)
9302                          (const_int 8))
9303         (xor:SI
9304           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9305           (match_dup 2)))]
9306   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9307   "xor{b}\t{%2, %h0|%h0, %2}"
9308   [(set_attr "type" "alu")
9309    (set_attr "mode" "QI")])
9310
9311 (define_expand "xorqi_cc_ext_1"
9312   [(parallel [
9313      (set (reg:CCNO FLAGS_REG)
9314           (compare:CCNO
9315             (xor:SI
9316               (zero_extract:SI
9317                 (match_operand 1 "ext_register_operand" "")
9318                 (const_int 8)
9319                 (const_int 8))
9320               (match_operand:QI 2 "general_operand" ""))
9321             (const_int 0)))
9322      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9323                            (const_int 8)
9324                            (const_int 8))
9325           (xor:SI
9326             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9327             (match_dup 2)))])]
9328   ""
9329   "")
9330
9331 (define_split
9332   [(set (match_operand 0 "register_operand" "")
9333         (xor (match_operand 1 "register_operand" "")
9334              (match_operand 2 "const_int_operand" "")))
9335    (clobber (reg:CC FLAGS_REG))]
9336    "reload_completed
9337     && QI_REG_P (operands[0])
9338     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9339     && !(INTVAL (operands[2]) & ~(255 << 8))
9340     && GET_MODE (operands[0]) != QImode"
9341   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9342                    (xor:SI (zero_extract:SI (match_dup 1)
9343                                             (const_int 8) (const_int 8))
9344                            (match_dup 2)))
9345               (clobber (reg:CC FLAGS_REG))])]
9346   "operands[0] = gen_lowpart (SImode, operands[0]);
9347    operands[1] = gen_lowpart (SImode, operands[1]);
9348    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9349
9350 ;; Since XOR can be encoded with sign extended immediate, this is only
9351 ;; profitable when 7th bit is set.
9352 (define_split
9353   [(set (match_operand 0 "register_operand" "")
9354         (xor (match_operand 1 "general_operand" "")
9355              (match_operand 2 "const_int_operand" "")))
9356    (clobber (reg:CC FLAGS_REG))]
9357    "reload_completed
9358     && ANY_QI_REG_P (operands[0])
9359     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9360     && !(INTVAL (operands[2]) & ~255)
9361     && (INTVAL (operands[2]) & 128)
9362     && GET_MODE (operands[0]) != QImode"
9363   [(parallel [(set (strict_low_part (match_dup 0))
9364                    (xor:QI (match_dup 1)
9365                            (match_dup 2)))
9366               (clobber (reg:CC FLAGS_REG))])]
9367   "operands[0] = gen_lowpart (QImode, operands[0]);
9368    operands[1] = gen_lowpart (QImode, operands[1]);
9369    operands[2] = gen_lowpart (QImode, operands[2]);")
9370 \f
9371 ;; Negation instructions
9372
9373 (define_expand "negti2"
9374   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9375                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9376               (clobber (reg:CC FLAGS_REG))])]
9377   "TARGET_64BIT"
9378   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9379
9380 (define_insn "*negti2_1"
9381   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9382         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9383    (clobber (reg:CC FLAGS_REG))]
9384   "TARGET_64BIT
9385    && ix86_unary_operator_ok (NEG, TImode, operands)"
9386   "#")
9387
9388 (define_split
9389   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9390         (neg:TI (match_operand:TI 1 "general_operand" "")))
9391    (clobber (reg:CC FLAGS_REG))]
9392   "TARGET_64BIT && reload_completed"
9393   [(parallel
9394     [(set (reg:CCZ FLAGS_REG)
9395           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9396      (set (match_dup 0) (neg:DI (match_dup 2)))])
9397    (parallel
9398     [(set (match_dup 1)
9399           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9400                             (match_dup 3))
9401                    (const_int 0)))
9402      (clobber (reg:CC FLAGS_REG))])
9403    (parallel
9404     [(set (match_dup 1)
9405           (neg:DI (match_dup 1)))
9406      (clobber (reg:CC FLAGS_REG))])]
9407   "split_ti (operands+1, 1, operands+2, operands+3);
9408    split_ti (operands+0, 1, operands+0, operands+1);")
9409
9410 (define_expand "negdi2"
9411   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9412                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9413               (clobber (reg:CC FLAGS_REG))])]
9414   ""
9415   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9416
9417 (define_insn "*negdi2_1"
9418   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9419         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9420    (clobber (reg:CC FLAGS_REG))]
9421   "!TARGET_64BIT
9422    && ix86_unary_operator_ok (NEG, DImode, operands)"
9423   "#")
9424
9425 (define_split
9426   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9427         (neg:DI (match_operand:DI 1 "general_operand" "")))
9428    (clobber (reg:CC FLAGS_REG))]
9429   "!TARGET_64BIT && reload_completed"
9430   [(parallel
9431     [(set (reg:CCZ FLAGS_REG)
9432           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9433      (set (match_dup 0) (neg:SI (match_dup 2)))])
9434    (parallel
9435     [(set (match_dup 1)
9436           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9437                             (match_dup 3))
9438                    (const_int 0)))
9439      (clobber (reg:CC FLAGS_REG))])
9440    (parallel
9441     [(set (match_dup 1)
9442           (neg:SI (match_dup 1)))
9443      (clobber (reg:CC FLAGS_REG))])]
9444   "split_di (operands+1, 1, operands+2, operands+3);
9445    split_di (operands+0, 1, operands+0, operands+1);")
9446
9447 (define_insn "*negdi2_1_rex64"
9448   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9449         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9450    (clobber (reg:CC FLAGS_REG))]
9451   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9452   "neg{q}\t%0"
9453   [(set_attr "type" "negnot")
9454    (set_attr "mode" "DI")])
9455
9456 ;; The problem with neg is that it does not perform (compare x 0),
9457 ;; it really performs (compare 0 x), which leaves us with the zero
9458 ;; flag being the only useful item.
9459
9460 (define_insn "*negdi2_cmpz_rex64"
9461   [(set (reg:CCZ FLAGS_REG)
9462         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9463                      (const_int 0)))
9464    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9465         (neg:DI (match_dup 1)))]
9466   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9467   "neg{q}\t%0"
9468   [(set_attr "type" "negnot")
9469    (set_attr "mode" "DI")])
9470
9471
9472 (define_expand "negsi2"
9473   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9474                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9475               (clobber (reg:CC FLAGS_REG))])]
9476   ""
9477   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9478
9479 (define_insn "*negsi2_1"
9480   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9481         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9482    (clobber (reg:CC FLAGS_REG))]
9483   "ix86_unary_operator_ok (NEG, SImode, operands)"
9484   "neg{l}\t%0"
9485   [(set_attr "type" "negnot")
9486    (set_attr "mode" "SI")])
9487
9488 ;; Combine is quite creative about this pattern.
9489 (define_insn "*negsi2_1_zext"
9490   [(set (match_operand:DI 0 "register_operand" "=r")
9491         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9492                                         (const_int 32)))
9493                      (const_int 32)))
9494    (clobber (reg:CC FLAGS_REG))]
9495   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9496   "neg{l}\t%k0"
9497   [(set_attr "type" "negnot")
9498    (set_attr "mode" "SI")])
9499
9500 ;; The problem with neg is that it does not perform (compare x 0),
9501 ;; it really performs (compare 0 x), which leaves us with the zero
9502 ;; flag being the only useful item.
9503
9504 (define_insn "*negsi2_cmpz"
9505   [(set (reg:CCZ FLAGS_REG)
9506         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9507                      (const_int 0)))
9508    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9509         (neg:SI (match_dup 1)))]
9510   "ix86_unary_operator_ok (NEG, SImode, operands)"
9511   "neg{l}\t%0"
9512   [(set_attr "type" "negnot")
9513    (set_attr "mode" "SI")])
9514
9515 (define_insn "*negsi2_cmpz_zext"
9516   [(set (reg:CCZ FLAGS_REG)
9517         (compare:CCZ (lshiftrt:DI
9518                        (neg:DI (ashift:DI
9519                                  (match_operand:DI 1 "register_operand" "0")
9520                                  (const_int 32)))
9521                        (const_int 32))
9522                      (const_int 0)))
9523    (set (match_operand:DI 0 "register_operand" "=r")
9524         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9525                                         (const_int 32)))
9526                      (const_int 32)))]
9527   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9528   "neg{l}\t%k0"
9529   [(set_attr "type" "negnot")
9530    (set_attr "mode" "SI")])
9531
9532 (define_expand "neghi2"
9533   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9534                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9535               (clobber (reg:CC FLAGS_REG))])]
9536   "TARGET_HIMODE_MATH"
9537   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9538
9539 (define_insn "*neghi2_1"
9540   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9541         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9542    (clobber (reg:CC FLAGS_REG))]
9543   "ix86_unary_operator_ok (NEG, HImode, operands)"
9544   "neg{w}\t%0"
9545   [(set_attr "type" "negnot")
9546    (set_attr "mode" "HI")])
9547
9548 (define_insn "*neghi2_cmpz"
9549   [(set (reg:CCZ FLAGS_REG)
9550         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9551                      (const_int 0)))
9552    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9553         (neg:HI (match_dup 1)))]
9554   "ix86_unary_operator_ok (NEG, HImode, operands)"
9555   "neg{w}\t%0"
9556   [(set_attr "type" "negnot")
9557    (set_attr "mode" "HI")])
9558
9559 (define_expand "negqi2"
9560   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9561                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9562               (clobber (reg:CC FLAGS_REG))])]
9563   "TARGET_QIMODE_MATH"
9564   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9565
9566 (define_insn "*negqi2_1"
9567   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9568         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9569    (clobber (reg:CC FLAGS_REG))]
9570   "ix86_unary_operator_ok (NEG, QImode, operands)"
9571   "neg{b}\t%0"
9572   [(set_attr "type" "negnot")
9573    (set_attr "mode" "QI")])
9574
9575 (define_insn "*negqi2_cmpz"
9576   [(set (reg:CCZ FLAGS_REG)
9577         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9578                      (const_int 0)))
9579    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9580         (neg:QI (match_dup 1)))]
9581   "ix86_unary_operator_ok (NEG, QImode, operands)"
9582   "neg{b}\t%0"
9583   [(set_attr "type" "negnot")
9584    (set_attr "mode" "QI")])
9585
9586 ;; Changing of sign for FP values is doable using integer unit too.
9587
9588 (define_expand "negsf2"
9589   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9590         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9591   "TARGET_80387 || TARGET_SSE_MATH"
9592   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9593
9594 (define_expand "abssf2"
9595   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9596         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9597   "TARGET_80387 || TARGET_SSE_MATH"
9598   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9599
9600 (define_insn "*absnegsf2_mixed"
9601   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9602         (match_operator:SF 3 "absneg_operator"
9603           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9604    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9605    (clobber (reg:CC FLAGS_REG))]
9606   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9607    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9608   "#")
9609
9610 (define_insn "*absnegsf2_sse"
9611   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9612         (match_operator:SF 3 "absneg_operator"
9613           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9614    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9615    (clobber (reg:CC FLAGS_REG))]
9616   "TARGET_SSE_MATH
9617    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9618   "#")
9619
9620 (define_insn "*absnegsf2_i387"
9621   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9622         (match_operator:SF 3 "absneg_operator"
9623           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9624    (use (match_operand 2 "" ""))
9625    (clobber (reg:CC FLAGS_REG))]
9626   "TARGET_80387 && !TARGET_SSE_MATH
9627    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9628   "#")
9629
9630 (define_expand "copysignsf3"
9631   [(match_operand:SF 0 "register_operand" "")
9632    (match_operand:SF 1 "nonmemory_operand" "")
9633    (match_operand:SF 2 "register_operand" "")]
9634   "TARGET_SSE_MATH"
9635 {
9636   ix86_expand_copysign (operands);
9637   DONE;
9638 })
9639
9640 (define_insn_and_split "copysignsf3_const"
9641   [(set (match_operand:SF 0 "register_operand"          "=x")
9642         (unspec:SF
9643           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9644            (match_operand:SF 2 "register_operand"       "0")
9645            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9646           UNSPEC_COPYSIGN))]
9647   "TARGET_SSE_MATH"
9648   "#"
9649   "&& reload_completed"
9650   [(const_int 0)]
9651 {
9652   ix86_split_copysign_const (operands);
9653   DONE;
9654 })
9655
9656 (define_insn "copysignsf3_var"
9657   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9658         (unspec:SF
9659           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9660            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9661            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9662            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9663           UNSPEC_COPYSIGN))
9664    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9665   "TARGET_SSE_MATH"
9666   "#")
9667
9668 (define_split
9669   [(set (match_operand:SF 0 "register_operand" "")
9670         (unspec:SF
9671           [(match_operand:SF 2 "register_operand" "")
9672            (match_operand:SF 3 "register_operand" "")
9673            (match_operand:V4SF 4 "" "")
9674            (match_operand:V4SF 5 "" "")]
9675           UNSPEC_COPYSIGN))
9676    (clobber (match_scratch:V4SF 1 ""))]
9677   "TARGET_SSE_MATH && reload_completed"
9678   [(const_int 0)]
9679 {
9680   ix86_split_copysign_var (operands);
9681   DONE;
9682 })
9683
9684 (define_expand "negdf2"
9685   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9686         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9687   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9688   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9689
9690 (define_expand "absdf2"
9691   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9692         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9693   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9694   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9695
9696 (define_insn "*absnegdf2_mixed"
9697   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,f,rm")
9698         (match_operator:DF 3 "absneg_operator"
9699           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9700    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X,X"))
9701    (clobber (reg:CC FLAGS_REG))]
9702   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9703    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9704   "#")
9705
9706 (define_insn "*absnegdf2_sse"
9707   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9708         (match_operator:DF 3 "absneg_operator"
9709           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9710    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X "))
9711    (clobber (reg:CC FLAGS_REG))]
9712   "TARGET_SSE2 && TARGET_SSE_MATH
9713    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9714   "#")
9715
9716 (define_insn "*absnegdf2_i387"
9717   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9718         (match_operator:DF 3 "absneg_operator"
9719           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9720    (use (match_operand 2 "" ""))
9721    (clobber (reg:CC FLAGS_REG))]
9722   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9723    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9724   "#")
9725
9726 (define_expand "copysigndf3"
9727   [(match_operand:DF 0 "register_operand" "")
9728    (match_operand:DF 1 "nonmemory_operand" "")
9729    (match_operand:DF 2 "register_operand" "")]
9730   "TARGET_SSE2 && TARGET_SSE_MATH"
9731 {
9732   ix86_expand_copysign (operands);
9733   DONE;
9734 })
9735
9736 (define_insn_and_split "copysigndf3_const"
9737   [(set (match_operand:DF 0 "register_operand"          "=x")
9738         (unspec:DF
9739           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9740            (match_operand:DF 2 "register_operand"       "0")
9741            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9742           UNSPEC_COPYSIGN))]
9743   "TARGET_SSE2 && TARGET_SSE_MATH"
9744   "#"
9745   "&& reload_completed"
9746   [(const_int 0)]
9747 {
9748   ix86_split_copysign_const (operands);
9749   DONE;
9750 })
9751
9752 (define_insn "copysigndf3_var"
9753   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9754         (unspec:DF
9755           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9756            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9757            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9758            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9759           UNSPEC_COPYSIGN))
9760    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9761   "TARGET_SSE2 && TARGET_SSE_MATH"
9762   "#")
9763
9764 (define_split
9765   [(set (match_operand:DF 0 "register_operand" "")
9766         (unspec:DF
9767           [(match_operand:DF 2 "register_operand" "")
9768            (match_operand:DF 3 "register_operand" "")
9769            (match_operand:V2DF 4 "" "")
9770            (match_operand:V2DF 5 "" "")]
9771           UNSPEC_COPYSIGN))
9772    (clobber (match_scratch:V2DF 1 ""))]
9773   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9774   [(const_int 0)]
9775 {
9776   ix86_split_copysign_var (operands);
9777   DONE;
9778 })
9779
9780 (define_expand "negxf2"
9781   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9782         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9783   "TARGET_80387"
9784   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9785
9786 (define_expand "absxf2"
9787   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9788         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9789   "TARGET_80387"
9790   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9791
9792 (define_insn "*absnegxf2_i387"
9793   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9794         (match_operator:XF 3 "absneg_operator"
9795           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9796    (use (match_operand 2 "" ""))
9797    (clobber (reg:CC FLAGS_REG))]
9798   "TARGET_80387
9799    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9800   "#")
9801
9802 ;; Splitters for fp abs and neg.
9803
9804 (define_split
9805   [(set (match_operand 0 "fp_register_operand" "")
9806         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9807    (use (match_operand 2 "" ""))
9808    (clobber (reg:CC FLAGS_REG))]
9809   "reload_completed"
9810   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9811
9812 (define_split
9813   [(set (match_operand 0 "register_operand" "")
9814         (match_operator 3 "absneg_operator"
9815           [(match_operand 1 "register_operand" "")]))
9816    (use (match_operand 2 "nonimmediate_operand" ""))
9817    (clobber (reg:CC FLAGS_REG))]
9818   "reload_completed && SSE_REG_P (operands[0])"
9819   [(set (match_dup 0) (match_dup 3))]
9820 {
9821   enum machine_mode mode = GET_MODE (operands[0]);
9822   enum machine_mode vmode = GET_MODE (operands[2]);
9823   rtx tmp;
9824
9825   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9826   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9827   if (operands_match_p (operands[0], operands[2]))
9828     {
9829       tmp = operands[1];
9830       operands[1] = operands[2];
9831       operands[2] = tmp;
9832     }
9833   if (GET_CODE (operands[3]) == ABS)
9834     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9835   else
9836     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9837   operands[3] = tmp;
9838 })
9839
9840 (define_split
9841   [(set (match_operand:SF 0 "register_operand" "")
9842         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9843    (use (match_operand:V4SF 2 "" ""))
9844    (clobber (reg:CC FLAGS_REG))]
9845   "reload_completed"
9846   [(parallel [(set (match_dup 0) (match_dup 1))
9847               (clobber (reg:CC FLAGS_REG))])]
9848 {
9849   rtx tmp;
9850   operands[0] = gen_lowpart (SImode, operands[0]);
9851   if (GET_CODE (operands[1]) == ABS)
9852     {
9853       tmp = gen_int_mode (0x7fffffff, SImode);
9854       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9855     }
9856   else
9857     {
9858       tmp = gen_int_mode (0x80000000, SImode);
9859       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9860     }
9861   operands[1] = tmp;
9862 })
9863
9864 (define_split
9865   [(set (match_operand:DF 0 "register_operand" "")
9866         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9867    (use (match_operand 2 "" ""))
9868    (clobber (reg:CC FLAGS_REG))]
9869   "reload_completed"
9870   [(parallel [(set (match_dup 0) (match_dup 1))
9871               (clobber (reg:CC FLAGS_REG))])]
9872 {
9873   rtx tmp;
9874   if (TARGET_64BIT)
9875     {
9876       tmp = gen_lowpart (DImode, operands[0]);
9877       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9878       operands[0] = tmp;
9879
9880       if (GET_CODE (operands[1]) == ABS)
9881         tmp = const0_rtx;
9882       else
9883         tmp = gen_rtx_NOT (DImode, tmp);
9884     }
9885   else
9886     {
9887       operands[0] = gen_highpart (SImode, operands[0]);
9888       if (GET_CODE (operands[1]) == ABS)
9889         {
9890           tmp = gen_int_mode (0x7fffffff, SImode);
9891           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9892         }
9893       else
9894         {
9895           tmp = gen_int_mode (0x80000000, SImode);
9896           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9897         }
9898     }
9899   operands[1] = tmp;
9900 })
9901
9902 (define_split
9903   [(set (match_operand:XF 0 "register_operand" "")
9904         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9905    (use (match_operand 2 "" ""))
9906    (clobber (reg:CC FLAGS_REG))]
9907   "reload_completed"
9908   [(parallel [(set (match_dup 0) (match_dup 1))
9909               (clobber (reg:CC FLAGS_REG))])]
9910 {
9911   rtx tmp;
9912   operands[0] = gen_rtx_REG (SImode,
9913                              true_regnum (operands[0])
9914                              + (TARGET_64BIT ? 1 : 2));
9915   if (GET_CODE (operands[1]) == ABS)
9916     {
9917       tmp = GEN_INT (0x7fff);
9918       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9919     }
9920   else
9921     {
9922       tmp = GEN_INT (0x8000);
9923       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9924     }
9925   operands[1] = tmp;
9926 })
9927
9928 (define_split
9929   [(set (match_operand 0 "memory_operand" "")
9930         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9931    (use (match_operand 2 "" ""))
9932    (clobber (reg:CC FLAGS_REG))]
9933   "reload_completed"
9934   [(parallel [(set (match_dup 0) (match_dup 1))
9935               (clobber (reg:CC FLAGS_REG))])]
9936 {
9937   enum machine_mode mode = GET_MODE (operands[0]);
9938   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9939   rtx tmp;
9940
9941   operands[0] = adjust_address (operands[0], QImode, size - 1);
9942   if (GET_CODE (operands[1]) == ABS)
9943     {
9944       tmp = gen_int_mode (0x7f, QImode);
9945       tmp = gen_rtx_AND (QImode, operands[0], tmp);
9946     }
9947   else
9948     {
9949       tmp = gen_int_mode (0x80, QImode);
9950       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9951     }
9952   operands[1] = tmp;
9953 })
9954
9955 ;; Conditionalize these after reload. If they match before reload, we
9956 ;; lose the clobber and ability to use integer instructions.
9957
9958 (define_insn "*negsf2_1"
9959   [(set (match_operand:SF 0 "register_operand" "=f")
9960         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9961   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9962   "fchs"
9963   [(set_attr "type" "fsgn")
9964    (set_attr "mode" "SF")])
9965
9966 (define_insn "*negdf2_1"
9967   [(set (match_operand:DF 0 "register_operand" "=f")
9968         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9969   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9970   "fchs"
9971   [(set_attr "type" "fsgn")
9972    (set_attr "mode" "DF")])
9973
9974 (define_insn "*negxf2_1"
9975   [(set (match_operand:XF 0 "register_operand" "=f")
9976         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9977   "TARGET_80387"
9978   "fchs"
9979   [(set_attr "type" "fsgn")
9980    (set_attr "mode" "XF")])
9981
9982 (define_insn "*abssf2_1"
9983   [(set (match_operand:SF 0 "register_operand" "=f")
9984         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9985   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9986   "fabs"
9987   [(set_attr "type" "fsgn")
9988    (set_attr "mode" "SF")])
9989
9990 (define_insn "*absdf2_1"
9991   [(set (match_operand:DF 0 "register_operand" "=f")
9992         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9993   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9994   "fabs"
9995   [(set_attr "type" "fsgn")
9996    (set_attr "mode" "DF")])
9997
9998 (define_insn "*absxf2_1"
9999   [(set (match_operand:XF 0 "register_operand" "=f")
10000         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10001   "TARGET_80387"
10002   "fabs"
10003   [(set_attr "type" "fsgn")
10004    (set_attr "mode" "DF")])
10005
10006 (define_insn "*negextendsfdf2"
10007   [(set (match_operand:DF 0 "register_operand" "=f")
10008         (neg:DF (float_extend:DF
10009                   (match_operand:SF 1 "register_operand" "0"))))]
10010   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10011   "fchs"
10012   [(set_attr "type" "fsgn")
10013    (set_attr "mode" "DF")])
10014
10015 (define_insn "*negextenddfxf2"
10016   [(set (match_operand:XF 0 "register_operand" "=f")
10017         (neg:XF (float_extend:XF
10018                   (match_operand:DF 1 "register_operand" "0"))))]
10019   "TARGET_80387"
10020   "fchs"
10021   [(set_attr "type" "fsgn")
10022    (set_attr "mode" "XF")])
10023
10024 (define_insn "*negextendsfxf2"
10025   [(set (match_operand:XF 0 "register_operand" "=f")
10026         (neg:XF (float_extend:XF
10027                   (match_operand:SF 1 "register_operand" "0"))))]
10028   "TARGET_80387"
10029   "fchs"
10030   [(set_attr "type" "fsgn")
10031    (set_attr "mode" "XF")])
10032
10033 (define_insn "*absextendsfdf2"
10034   [(set (match_operand:DF 0 "register_operand" "=f")
10035         (abs:DF (float_extend:DF
10036                   (match_operand:SF 1 "register_operand" "0"))))]
10037   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10038   "fabs"
10039   [(set_attr "type" "fsgn")
10040    (set_attr "mode" "DF")])
10041
10042 (define_insn "*absextenddfxf2"
10043   [(set (match_operand:XF 0 "register_operand" "=f")
10044         (abs:XF (float_extend:XF
10045           (match_operand:DF 1 "register_operand" "0"))))]
10046   "TARGET_80387"
10047   "fabs"
10048   [(set_attr "type" "fsgn")
10049    (set_attr "mode" "XF")])
10050
10051 (define_insn "*absextendsfxf2"
10052   [(set (match_operand:XF 0 "register_operand" "=f")
10053         (abs:XF (float_extend:XF
10054           (match_operand:SF 1 "register_operand" "0"))))]
10055   "TARGET_80387"
10056   "fabs"
10057   [(set_attr "type" "fsgn")
10058    (set_attr "mode" "XF")])
10059 \f
10060 ;; One complement instructions
10061
10062 (define_expand "one_cmpldi2"
10063   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10064         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10065   "TARGET_64BIT"
10066   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10067
10068 (define_insn "*one_cmpldi2_1_rex64"
10069   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10070         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10071   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10072   "not{q}\t%0"
10073   [(set_attr "type" "negnot")
10074    (set_attr "mode" "DI")])
10075
10076 (define_insn "*one_cmpldi2_2_rex64"
10077   [(set (reg FLAGS_REG)
10078         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10079                  (const_int 0)))
10080    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10081         (not:DI (match_dup 1)))]
10082   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10083    && ix86_unary_operator_ok (NOT, DImode, operands)"
10084   "#"
10085   [(set_attr "type" "alu1")
10086    (set_attr "mode" "DI")])
10087
10088 (define_split
10089   [(set (match_operand 0 "flags_reg_operand" "")
10090         (match_operator 2 "compare_operator"
10091           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10092            (const_int 0)]))
10093    (set (match_operand:DI 1 "nonimmediate_operand" "")
10094         (not:DI (match_dup 3)))]
10095   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10096   [(parallel [(set (match_dup 0)
10097                    (match_op_dup 2
10098                      [(xor:DI (match_dup 3) (const_int -1))
10099                       (const_int 0)]))
10100               (set (match_dup 1)
10101                    (xor:DI (match_dup 3) (const_int -1)))])]
10102   "")
10103
10104 (define_expand "one_cmplsi2"
10105   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10106         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10107   ""
10108   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10109
10110 (define_insn "*one_cmplsi2_1"
10111   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10112         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10113   "ix86_unary_operator_ok (NOT, SImode, operands)"
10114   "not{l}\t%0"
10115   [(set_attr "type" "negnot")
10116    (set_attr "mode" "SI")])
10117
10118 ;; ??? Currently never generated - xor is used instead.
10119 (define_insn "*one_cmplsi2_1_zext"
10120   [(set (match_operand:DI 0 "register_operand" "=r")
10121         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10122   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10123   "not{l}\t%k0"
10124   [(set_attr "type" "negnot")
10125    (set_attr "mode" "SI")])
10126
10127 (define_insn "*one_cmplsi2_2"
10128   [(set (reg FLAGS_REG)
10129         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10130                  (const_int 0)))
10131    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10132         (not:SI (match_dup 1)))]
10133   "ix86_match_ccmode (insn, CCNOmode)
10134    && ix86_unary_operator_ok (NOT, SImode, operands)"
10135   "#"
10136   [(set_attr "type" "alu1")
10137    (set_attr "mode" "SI")])
10138
10139 (define_split
10140   [(set (match_operand 0 "flags_reg_operand" "")
10141         (match_operator 2 "compare_operator"
10142           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10143            (const_int 0)]))
10144    (set (match_operand:SI 1 "nonimmediate_operand" "")
10145         (not:SI (match_dup 3)))]
10146   "ix86_match_ccmode (insn, CCNOmode)"
10147   [(parallel [(set (match_dup 0)
10148                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10149                                     (const_int 0)]))
10150               (set (match_dup 1)
10151                    (xor:SI (match_dup 3) (const_int -1)))])]
10152   "")
10153
10154 ;; ??? Currently never generated - xor is used instead.
10155 (define_insn "*one_cmplsi2_2_zext"
10156   [(set (reg FLAGS_REG)
10157         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10158                  (const_int 0)))
10159    (set (match_operand:DI 0 "register_operand" "=r")
10160         (zero_extend:DI (not:SI (match_dup 1))))]
10161   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10162    && ix86_unary_operator_ok (NOT, SImode, operands)"
10163   "#"
10164   [(set_attr "type" "alu1")
10165    (set_attr "mode" "SI")])
10166
10167 (define_split
10168   [(set (match_operand 0 "flags_reg_operand" "")
10169         (match_operator 2 "compare_operator"
10170           [(not:SI (match_operand:SI 3 "register_operand" ""))
10171            (const_int 0)]))
10172    (set (match_operand:DI 1 "register_operand" "")
10173         (zero_extend:DI (not:SI (match_dup 3))))]
10174   "ix86_match_ccmode (insn, CCNOmode)"
10175   [(parallel [(set (match_dup 0)
10176                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10177                                     (const_int 0)]))
10178               (set (match_dup 1)
10179                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10180   "")
10181
10182 (define_expand "one_cmplhi2"
10183   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10184         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10185   "TARGET_HIMODE_MATH"
10186   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10187
10188 (define_insn "*one_cmplhi2_1"
10189   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10190         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10191   "ix86_unary_operator_ok (NOT, HImode, operands)"
10192   "not{w}\t%0"
10193   [(set_attr "type" "negnot")
10194    (set_attr "mode" "HI")])
10195
10196 (define_insn "*one_cmplhi2_2"
10197   [(set (reg FLAGS_REG)
10198         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10199                  (const_int 0)))
10200    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10201         (not:HI (match_dup 1)))]
10202   "ix86_match_ccmode (insn, CCNOmode)
10203    && ix86_unary_operator_ok (NEG, HImode, operands)"
10204   "#"
10205   [(set_attr "type" "alu1")
10206    (set_attr "mode" "HI")])
10207
10208 (define_split
10209   [(set (match_operand 0 "flags_reg_operand" "")
10210         (match_operator 2 "compare_operator"
10211           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10212            (const_int 0)]))
10213    (set (match_operand:HI 1 "nonimmediate_operand" "")
10214         (not:HI (match_dup 3)))]
10215   "ix86_match_ccmode (insn, CCNOmode)"
10216   [(parallel [(set (match_dup 0)
10217                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10218                                     (const_int 0)]))
10219               (set (match_dup 1)
10220                    (xor:HI (match_dup 3) (const_int -1)))])]
10221   "")
10222
10223 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10224 (define_expand "one_cmplqi2"
10225   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10226         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10227   "TARGET_QIMODE_MATH"
10228   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10229
10230 (define_insn "*one_cmplqi2_1"
10231   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10232         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10233   "ix86_unary_operator_ok (NOT, QImode, operands)"
10234   "@
10235    not{b}\t%0
10236    not{l}\t%k0"
10237   [(set_attr "type" "negnot")
10238    (set_attr "mode" "QI,SI")])
10239
10240 (define_insn "*one_cmplqi2_2"
10241   [(set (reg FLAGS_REG)
10242         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10243                  (const_int 0)))
10244    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10245         (not:QI (match_dup 1)))]
10246   "ix86_match_ccmode (insn, CCNOmode)
10247    && ix86_unary_operator_ok (NOT, QImode, operands)"
10248   "#"
10249   [(set_attr "type" "alu1")
10250    (set_attr "mode" "QI")])
10251
10252 (define_split
10253   [(set (match_operand 0 "flags_reg_operand" "")
10254         (match_operator 2 "compare_operator"
10255           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10256            (const_int 0)]))
10257    (set (match_operand:QI 1 "nonimmediate_operand" "")
10258         (not:QI (match_dup 3)))]
10259   "ix86_match_ccmode (insn, CCNOmode)"
10260   [(parallel [(set (match_dup 0)
10261                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10262                                     (const_int 0)]))
10263               (set (match_dup 1)
10264                    (xor:QI (match_dup 3) (const_int -1)))])]
10265   "")
10266 \f
10267 ;; Arithmetic shift instructions
10268
10269 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10270 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10271 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10272 ;; from the assembler input.
10273 ;;
10274 ;; This instruction shifts the target reg/mem as usual, but instead of
10275 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10276 ;; is a left shift double, bits are taken from the high order bits of
10277 ;; reg, else if the insn is a shift right double, bits are taken from the
10278 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10279 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10280 ;;
10281 ;; Since sh[lr]d does not change the `reg' operand, that is done
10282 ;; separately, making all shifts emit pairs of shift double and normal
10283 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10284 ;; support a 63 bit shift, each shift where the count is in a reg expands
10285 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10286 ;;
10287 ;; If the shift count is a constant, we need never emit more than one
10288 ;; shift pair, instead using moves and sign extension for counts greater
10289 ;; than 31.
10290
10291 (define_expand "ashlti3"
10292   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10293                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10294                               (match_operand:QI 2 "nonmemory_operand" "")))
10295               (clobber (reg:CC FLAGS_REG))])]
10296   "TARGET_64BIT"
10297 {
10298   if (! immediate_operand (operands[2], QImode))
10299     {
10300       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10301       DONE;
10302     }
10303   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10304   DONE;
10305 })
10306
10307 (define_insn "ashlti3_1"
10308   [(set (match_operand:TI 0 "register_operand" "=r")
10309         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10310                    (match_operand:QI 2 "register_operand" "c")))
10311    (clobber (match_scratch:DI 3 "=&r"))
10312    (clobber (reg:CC FLAGS_REG))]
10313   "TARGET_64BIT"
10314   "#"
10315   [(set_attr "type" "multi")])
10316
10317 (define_insn "*ashlti3_2"
10318   [(set (match_operand:TI 0 "register_operand" "=r")
10319         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10320                    (match_operand:QI 2 "immediate_operand" "O")))
10321    (clobber (reg:CC FLAGS_REG))]
10322   "TARGET_64BIT"
10323   "#"
10324   [(set_attr "type" "multi")])
10325
10326 (define_split
10327   [(set (match_operand:TI 0 "register_operand" "")
10328         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10329                    (match_operand:QI 2 "register_operand" "")))
10330    (clobber (match_scratch:DI 3 ""))
10331    (clobber (reg:CC FLAGS_REG))]
10332   "TARGET_64BIT && reload_completed"
10333   [(const_int 0)]
10334   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10335
10336 (define_split
10337   [(set (match_operand:TI 0 "register_operand" "")
10338         (ashift:TI (match_operand:TI 1 "register_operand" "")
10339                    (match_operand:QI 2 "immediate_operand" "")))
10340    (clobber (reg:CC FLAGS_REG))]
10341   "TARGET_64BIT && reload_completed"
10342   [(const_int 0)]
10343   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10344
10345 (define_insn "x86_64_shld"
10346   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10347         (ior:DI (ashift:DI (match_dup 0)
10348                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10349                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10350                   (minus:QI (const_int 64) (match_dup 2)))))
10351    (clobber (reg:CC FLAGS_REG))]
10352   "TARGET_64BIT"
10353   "@
10354    shld{q}\t{%2, %1, %0|%0, %1, %2}
10355    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10356   [(set_attr "type" "ishift")
10357    (set_attr "prefix_0f" "1")
10358    (set_attr "mode" "DI")
10359    (set_attr "athlon_decode" "vector")])
10360
10361 (define_expand "x86_64_shift_adj"
10362   [(set (reg:CCZ FLAGS_REG)
10363         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10364                              (const_int 64))
10365                      (const_int 0)))
10366    (set (match_operand:DI 0 "register_operand" "")
10367         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10368                          (match_operand:DI 1 "register_operand" "")
10369                          (match_dup 0)))
10370    (set (match_dup 1)
10371         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10372                          (match_operand:DI 3 "register_operand" "r")
10373                          (match_dup 1)))]
10374   "TARGET_64BIT"
10375   "")
10376
10377 (define_expand "ashldi3"
10378   [(set (match_operand:DI 0 "shiftdi_operand" "")
10379         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10380                    (match_operand:QI 2 "nonmemory_operand" "")))]
10381   ""
10382   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10383
10384 (define_insn "*ashldi3_1_rex64"
10385   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10386         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10387                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10388    (clobber (reg:CC FLAGS_REG))]
10389   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10390 {
10391   switch (get_attr_type (insn))
10392     {
10393     case TYPE_ALU:
10394       gcc_assert (operands[2] == const1_rtx);
10395       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10396       return "add{q}\t{%0, %0|%0, %0}";
10397
10398     case TYPE_LEA:
10399       gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10400       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10401       operands[1] = gen_rtx_MULT (DImode, operands[1],
10402                                   GEN_INT (1 << INTVAL (operands[2])));
10403       return "lea{q}\t{%a1, %0|%0, %a1}";
10404
10405     default:
10406       if (REG_P (operands[2]))
10407         return "sal{q}\t{%b2, %0|%0, %b2}";
10408       else if (operands[2] == const1_rtx
10409                && (TARGET_SHIFT1 || optimize_size))
10410         return "sal{q}\t%0";
10411       else
10412         return "sal{q}\t{%2, %0|%0, %2}";
10413     }
10414 }
10415   [(set (attr "type")
10416      (cond [(eq_attr "alternative" "1")
10417               (const_string "lea")
10418             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10419                           (const_int 0))
10420                       (match_operand 0 "register_operand" ""))
10421                  (match_operand 2 "const1_operand" ""))
10422               (const_string "alu")
10423            ]
10424            (const_string "ishift")))
10425    (set_attr "mode" "DI")])
10426
10427 ;; Convert lea to the lea pattern to avoid flags dependency.
10428 (define_split
10429   [(set (match_operand:DI 0 "register_operand" "")
10430         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10431                    (match_operand:QI 2 "immediate_operand" "")))
10432    (clobber (reg:CC FLAGS_REG))]
10433   "TARGET_64BIT && reload_completed
10434    && true_regnum (operands[0]) != true_regnum (operands[1])"
10435   [(set (match_dup 0)
10436         (mult:DI (match_dup 1)
10437                  (match_dup 2)))]
10438   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10439
10440 ;; This pattern can't accept a variable shift count, since shifts by
10441 ;; zero don't affect the flags.  We assume that shifts by constant
10442 ;; zero are optimized away.
10443 (define_insn "*ashldi3_cmp_rex64"
10444   [(set (reg FLAGS_REG)
10445         (compare
10446           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10447                      (match_operand:QI 2 "immediate_operand" "e"))
10448           (const_int 0)))
10449    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10450         (ashift:DI (match_dup 1) (match_dup 2)))]
10451   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10452    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10453    && (optimize_size
10454        || !TARGET_PARTIAL_FLAG_REG_STALL
10455        || (operands[2] == const1_rtx
10456            && (TARGET_SHIFT1
10457                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10458 {
10459   switch (get_attr_type (insn))
10460     {
10461     case TYPE_ALU:
10462       gcc_assert (operands[2] == const1_rtx);
10463       return "add{q}\t{%0, %0|%0, %0}";
10464
10465     default:
10466       if (REG_P (operands[2]))
10467         return "sal{q}\t{%b2, %0|%0, %b2}";
10468       else if (operands[2] == const1_rtx
10469                && (TARGET_SHIFT1 || optimize_size))
10470         return "sal{q}\t%0";
10471       else
10472         return "sal{q}\t{%2, %0|%0, %2}";
10473     }
10474 }
10475   [(set (attr "type")
10476      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10477                           (const_int 0))
10478                       (match_operand 0 "register_operand" ""))
10479                  (match_operand 2 "const1_operand" ""))
10480               (const_string "alu")
10481            ]
10482            (const_string "ishift")))
10483    (set_attr "mode" "DI")])
10484
10485 (define_insn "*ashldi3_cconly_rex64"
10486   [(set (reg FLAGS_REG)
10487         (compare
10488           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10489                      (match_operand:QI 2 "immediate_operand" "e"))
10490           (const_int 0)))
10491    (clobber (match_scratch:DI 0 "=r"))]
10492   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10493    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10494    && (optimize_size
10495        || !TARGET_PARTIAL_FLAG_REG_STALL
10496        || (operands[2] == const1_rtx
10497            && (TARGET_SHIFT1
10498                || TARGET_DOUBLE_WITH_ADD)))"
10499 {
10500   switch (get_attr_type (insn))
10501     {
10502     case TYPE_ALU:
10503       gcc_assert (operands[2] == const1_rtx);
10504       return "add{q}\t{%0, %0|%0, %0}";
10505
10506     default:
10507       if (REG_P (operands[2]))
10508         return "sal{q}\t{%b2, %0|%0, %b2}";
10509       else if (operands[2] == const1_rtx
10510                && (TARGET_SHIFT1 || optimize_size))
10511         return "sal{q}\t%0";
10512       else
10513         return "sal{q}\t{%2, %0|%0, %2}";
10514     }
10515 }
10516   [(set (attr "type")
10517      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10518                           (const_int 0))
10519                       (match_operand 0 "register_operand" ""))
10520                  (match_operand 2 "const1_operand" ""))
10521               (const_string "alu")
10522            ]
10523            (const_string "ishift")))
10524    (set_attr "mode" "DI")])
10525
10526 (define_insn "*ashldi3_1"
10527   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10528         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10529                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10530    (clobber (reg:CC FLAGS_REG))]
10531   "!TARGET_64BIT"
10532   "#"
10533   [(set_attr "type" "multi")])
10534
10535 ;; By default we don't ask for a scratch register, because when DImode
10536 ;; values are manipulated, registers are already at a premium.  But if
10537 ;; we have one handy, we won't turn it away.
10538 (define_peephole2
10539   [(match_scratch:SI 3 "r")
10540    (parallel [(set (match_operand:DI 0 "register_operand" "")
10541                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10542                               (match_operand:QI 2 "nonmemory_operand" "")))
10543               (clobber (reg:CC FLAGS_REG))])
10544    (match_dup 3)]
10545   "!TARGET_64BIT && TARGET_CMOVE"
10546   [(const_int 0)]
10547   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10548
10549 (define_split
10550   [(set (match_operand:DI 0 "register_operand" "")
10551         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10552                    (match_operand:QI 2 "nonmemory_operand" "")))
10553    (clobber (reg:CC FLAGS_REG))]
10554   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10555                      ? flow2_completed : reload_completed)"
10556   [(const_int 0)]
10557   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10558
10559 (define_insn "x86_shld_1"
10560   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10561         (ior:SI (ashift:SI (match_dup 0)
10562                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10563                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10564                   (minus:QI (const_int 32) (match_dup 2)))))
10565    (clobber (reg:CC FLAGS_REG))]
10566   ""
10567   "@
10568    shld{l}\t{%2, %1, %0|%0, %1, %2}
10569    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10570   [(set_attr "type" "ishift")
10571    (set_attr "prefix_0f" "1")
10572    (set_attr "mode" "SI")
10573    (set_attr "pent_pair" "np")
10574    (set_attr "athlon_decode" "vector")])
10575
10576 (define_expand "x86_shift_adj_1"
10577   [(set (reg:CCZ FLAGS_REG)
10578         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10579                              (const_int 32))
10580                      (const_int 0)))
10581    (set (match_operand:SI 0 "register_operand" "")
10582         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10583                          (match_operand:SI 1 "register_operand" "")
10584                          (match_dup 0)))
10585    (set (match_dup 1)
10586         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10587                          (match_operand:SI 3 "register_operand" "r")
10588                          (match_dup 1)))]
10589   "TARGET_CMOVE"
10590   "")
10591
10592 (define_expand "x86_shift_adj_2"
10593   [(use (match_operand:SI 0 "register_operand" ""))
10594    (use (match_operand:SI 1 "register_operand" ""))
10595    (use (match_operand:QI 2 "register_operand" ""))]
10596   ""
10597 {
10598   rtx label = gen_label_rtx ();
10599   rtx tmp;
10600
10601   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10602
10603   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10604   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10605   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10606                               gen_rtx_LABEL_REF (VOIDmode, label),
10607                               pc_rtx);
10608   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10609   JUMP_LABEL (tmp) = label;
10610
10611   emit_move_insn (operands[0], operands[1]);
10612   ix86_expand_clear (operands[1]);
10613
10614   emit_label (label);
10615   LABEL_NUSES (label) = 1;
10616
10617   DONE;
10618 })
10619
10620 (define_expand "ashlsi3"
10621   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10622         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10623                    (match_operand:QI 2 "nonmemory_operand" "")))
10624    (clobber (reg:CC FLAGS_REG))]
10625   ""
10626   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10627
10628 (define_insn "*ashlsi3_1"
10629   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10630         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10631                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10632    (clobber (reg:CC FLAGS_REG))]
10633   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10634 {
10635   switch (get_attr_type (insn))
10636     {
10637     case TYPE_ALU:
10638       gcc_assert (operands[2] == const1_rtx);
10639       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10640       return "add{l}\t{%0, %0|%0, %0}";
10641
10642     case TYPE_LEA:
10643       return "#";
10644
10645     default:
10646       if (REG_P (operands[2]))
10647         return "sal{l}\t{%b2, %0|%0, %b2}";
10648       else if (operands[2] == const1_rtx
10649                && (TARGET_SHIFT1 || optimize_size))
10650         return "sal{l}\t%0";
10651       else
10652         return "sal{l}\t{%2, %0|%0, %2}";
10653     }
10654 }
10655   [(set (attr "type")
10656      (cond [(eq_attr "alternative" "1")
10657               (const_string "lea")
10658             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10659                           (const_int 0))
10660                       (match_operand 0 "register_operand" ""))
10661                  (match_operand 2 "const1_operand" ""))
10662               (const_string "alu")
10663            ]
10664            (const_string "ishift")))
10665    (set_attr "mode" "SI")])
10666
10667 ;; Convert lea to the lea pattern to avoid flags dependency.
10668 (define_split
10669   [(set (match_operand 0 "register_operand" "")
10670         (ashift (match_operand 1 "index_register_operand" "")
10671                 (match_operand:QI 2 "const_int_operand" "")))
10672    (clobber (reg:CC FLAGS_REG))]
10673   "reload_completed
10674    && true_regnum (operands[0]) != true_regnum (operands[1])
10675    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10676   [(const_int 0)]
10677 {
10678   rtx pat;
10679   enum machine_mode mode = GET_MODE (operands[0]);
10680
10681   if (GET_MODE_SIZE (mode) < 4)
10682     operands[0] = gen_lowpart (SImode, operands[0]);
10683   if (mode != Pmode)
10684     operands[1] = gen_lowpart (Pmode, operands[1]);
10685   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10686
10687   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10688   if (Pmode != SImode)
10689     pat = gen_rtx_SUBREG (SImode, pat, 0);
10690   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10691   DONE;
10692 })
10693
10694 ;; Rare case of shifting RSP is handled by generating move and shift
10695 (define_split
10696   [(set (match_operand 0 "register_operand" "")
10697         (ashift (match_operand 1 "register_operand" "")
10698                 (match_operand:QI 2 "const_int_operand" "")))
10699    (clobber (reg:CC FLAGS_REG))]
10700   "reload_completed
10701    && true_regnum (operands[0]) != true_regnum (operands[1])"
10702   [(const_int 0)]
10703 {
10704   rtx pat, clob;
10705   emit_move_insn (operands[0], operands[1]);
10706   pat = gen_rtx_SET (VOIDmode, operands[0],
10707                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10708                                      operands[0], operands[2]));
10709   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10710   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10711   DONE;
10712 })
10713
10714 (define_insn "*ashlsi3_1_zext"
10715   [(set (match_operand:DI 0 "register_operand" "=r,r")
10716         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10717                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10718    (clobber (reg:CC FLAGS_REG))]
10719   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10720 {
10721   switch (get_attr_type (insn))
10722     {
10723     case TYPE_ALU:
10724       gcc_assert (operands[2] == const1_rtx);
10725       return "add{l}\t{%k0, %k0|%k0, %k0}";
10726
10727     case TYPE_LEA:
10728       return "#";
10729
10730     default:
10731       if (REG_P (operands[2]))
10732         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10733       else if (operands[2] == const1_rtx
10734                && (TARGET_SHIFT1 || optimize_size))
10735         return "sal{l}\t%k0";
10736       else
10737         return "sal{l}\t{%2, %k0|%k0, %2}";
10738     }
10739 }
10740   [(set (attr "type")
10741      (cond [(eq_attr "alternative" "1")
10742               (const_string "lea")
10743             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10744                      (const_int 0))
10745                  (match_operand 2 "const1_operand" ""))
10746               (const_string "alu")
10747            ]
10748            (const_string "ishift")))
10749    (set_attr "mode" "SI")])
10750
10751 ;; Convert lea to the lea pattern to avoid flags dependency.
10752 (define_split
10753   [(set (match_operand:DI 0 "register_operand" "")
10754         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10755                                 (match_operand:QI 2 "const_int_operand" ""))))
10756    (clobber (reg:CC FLAGS_REG))]
10757   "TARGET_64BIT && reload_completed
10758    && true_regnum (operands[0]) != true_regnum (operands[1])"
10759   [(set (match_dup 0) (zero_extend:DI
10760                         (subreg:SI (mult:SI (match_dup 1)
10761                                             (match_dup 2)) 0)))]
10762 {
10763   operands[1] = gen_lowpart (Pmode, operands[1]);
10764   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10765 })
10766
10767 ;; This pattern can't accept a variable shift count, since shifts by
10768 ;; zero don't affect the flags.  We assume that shifts by constant
10769 ;; zero are optimized away.
10770 (define_insn "*ashlsi3_cmp"
10771   [(set (reg FLAGS_REG)
10772         (compare
10773           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10774                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10775           (const_int 0)))
10776    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10777         (ashift:SI (match_dup 1) (match_dup 2)))]
10778   "ix86_match_ccmode (insn, CCGOCmode)
10779    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10780    && (optimize_size
10781        || !TARGET_PARTIAL_FLAG_REG_STALL
10782        || (operands[2] == const1_rtx
10783            && (TARGET_SHIFT1
10784                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10785 {
10786   switch (get_attr_type (insn))
10787     {
10788     case TYPE_ALU:
10789       gcc_assert (operands[2] == const1_rtx);
10790       return "add{l}\t{%0, %0|%0, %0}";
10791
10792     default:
10793       if (REG_P (operands[2]))
10794         return "sal{l}\t{%b2, %0|%0, %b2}";
10795       else if (operands[2] == const1_rtx
10796                && (TARGET_SHIFT1 || optimize_size))
10797         return "sal{l}\t%0";
10798       else
10799         return "sal{l}\t{%2, %0|%0, %2}";
10800     }
10801 }
10802   [(set (attr "type")
10803      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10804                           (const_int 0))
10805                       (match_operand 0 "register_operand" ""))
10806                  (match_operand 2 "const1_operand" ""))
10807               (const_string "alu")
10808            ]
10809            (const_string "ishift")))
10810    (set_attr "mode" "SI")])
10811
10812 (define_insn "*ashlsi3_cconly"
10813   [(set (reg FLAGS_REG)
10814         (compare
10815           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10816                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10817           (const_int 0)))
10818    (clobber (match_scratch:SI 0 "=r"))]
10819   "ix86_match_ccmode (insn, CCGOCmode)
10820    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10821    && (optimize_size
10822        || !TARGET_PARTIAL_FLAG_REG_STALL
10823        || (operands[2] == const1_rtx
10824            && (TARGET_SHIFT1
10825                || TARGET_DOUBLE_WITH_ADD)))"
10826 {
10827   switch (get_attr_type (insn))
10828     {
10829     case TYPE_ALU:
10830       gcc_assert (operands[2] == const1_rtx);
10831       return "add{l}\t{%0, %0|%0, %0}";
10832
10833     default:
10834       if (REG_P (operands[2]))
10835         return "sal{l}\t{%b2, %0|%0, %b2}";
10836       else if (operands[2] == const1_rtx
10837                && (TARGET_SHIFT1 || optimize_size))
10838         return "sal{l}\t%0";
10839       else
10840         return "sal{l}\t{%2, %0|%0, %2}";
10841     }
10842 }
10843   [(set (attr "type")
10844      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10845                           (const_int 0))
10846                       (match_operand 0 "register_operand" ""))
10847                  (match_operand 2 "const1_operand" ""))
10848               (const_string "alu")
10849            ]
10850            (const_string "ishift")))
10851    (set_attr "mode" "SI")])
10852
10853 (define_insn "*ashlsi3_cmp_zext"
10854   [(set (reg FLAGS_REG)
10855         (compare
10856           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10857                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10858           (const_int 0)))
10859    (set (match_operand:DI 0 "register_operand" "=r")
10860         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10861   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10862    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10863    && (optimize_size
10864        || !TARGET_PARTIAL_FLAG_REG_STALL
10865        || (operands[2] == const1_rtx
10866            && (TARGET_SHIFT1
10867                || TARGET_DOUBLE_WITH_ADD)))"
10868 {
10869   switch (get_attr_type (insn))
10870     {
10871     case TYPE_ALU:
10872       gcc_assert (operands[2] == const1_rtx);
10873       return "add{l}\t{%k0, %k0|%k0, %k0}";
10874
10875     default:
10876       if (REG_P (operands[2]))
10877         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10878       else if (operands[2] == const1_rtx
10879                && (TARGET_SHIFT1 || optimize_size))
10880         return "sal{l}\t%k0";
10881       else
10882         return "sal{l}\t{%2, %k0|%k0, %2}";
10883     }
10884 }
10885   [(set (attr "type")
10886      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10887                      (const_int 0))
10888                  (match_operand 2 "const1_operand" ""))
10889               (const_string "alu")
10890            ]
10891            (const_string "ishift")))
10892    (set_attr "mode" "SI")])
10893
10894 (define_expand "ashlhi3"
10895   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10896         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10897                    (match_operand:QI 2 "nonmemory_operand" "")))
10898    (clobber (reg:CC FLAGS_REG))]
10899   "TARGET_HIMODE_MATH"
10900   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10901
10902 (define_insn "*ashlhi3_1_lea"
10903   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10904         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10905                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10906    (clobber (reg:CC FLAGS_REG))]
10907   "!TARGET_PARTIAL_REG_STALL
10908    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10909 {
10910   switch (get_attr_type (insn))
10911     {
10912     case TYPE_LEA:
10913       return "#";
10914     case TYPE_ALU:
10915       gcc_assert (operands[2] == const1_rtx);
10916       return "add{w}\t{%0, %0|%0, %0}";
10917
10918     default:
10919       if (REG_P (operands[2]))
10920         return "sal{w}\t{%b2, %0|%0, %b2}";
10921       else if (operands[2] == const1_rtx
10922                && (TARGET_SHIFT1 || optimize_size))
10923         return "sal{w}\t%0";
10924       else
10925         return "sal{w}\t{%2, %0|%0, %2}";
10926     }
10927 }
10928   [(set (attr "type")
10929      (cond [(eq_attr "alternative" "1")
10930               (const_string "lea")
10931             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10932                           (const_int 0))
10933                       (match_operand 0 "register_operand" ""))
10934                  (match_operand 2 "const1_operand" ""))
10935               (const_string "alu")
10936            ]
10937            (const_string "ishift")))
10938    (set_attr "mode" "HI,SI")])
10939
10940 (define_insn "*ashlhi3_1"
10941   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10942         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10943                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10944    (clobber (reg:CC FLAGS_REG))]
10945   "TARGET_PARTIAL_REG_STALL
10946    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10947 {
10948   switch (get_attr_type (insn))
10949     {
10950     case TYPE_ALU:
10951       gcc_assert (operands[2] == const1_rtx);
10952       return "add{w}\t{%0, %0|%0, %0}";
10953
10954     default:
10955       if (REG_P (operands[2]))
10956         return "sal{w}\t{%b2, %0|%0, %b2}";
10957       else if (operands[2] == const1_rtx
10958                && (TARGET_SHIFT1 || optimize_size))
10959         return "sal{w}\t%0";
10960       else
10961         return "sal{w}\t{%2, %0|%0, %2}";
10962     }
10963 }
10964   [(set (attr "type")
10965      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10966                           (const_int 0))
10967                       (match_operand 0 "register_operand" ""))
10968                  (match_operand 2 "const1_operand" ""))
10969               (const_string "alu")
10970            ]
10971            (const_string "ishift")))
10972    (set_attr "mode" "HI")])
10973
10974 ;; This pattern can't accept a variable shift count, since shifts by
10975 ;; zero don't affect the flags.  We assume that shifts by constant
10976 ;; zero are optimized away.
10977 (define_insn "*ashlhi3_cmp"
10978   [(set (reg FLAGS_REG)
10979         (compare
10980           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10981                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10982           (const_int 0)))
10983    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10984         (ashift:HI (match_dup 1) (match_dup 2)))]
10985   "ix86_match_ccmode (insn, CCGOCmode)
10986    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10987    && (optimize_size
10988        || !TARGET_PARTIAL_FLAG_REG_STALL
10989        || (operands[2] == const1_rtx
10990            && (TARGET_SHIFT1
10991                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10992 {
10993   switch (get_attr_type (insn))
10994     {
10995     case TYPE_ALU:
10996       gcc_assert (operands[2] == const1_rtx);
10997       return "add{w}\t{%0, %0|%0, %0}";
10998
10999     default:
11000       if (REG_P (operands[2]))
11001         return "sal{w}\t{%b2, %0|%0, %b2}";
11002       else if (operands[2] == const1_rtx
11003                && (TARGET_SHIFT1 || optimize_size))
11004         return "sal{w}\t%0";
11005       else
11006         return "sal{w}\t{%2, %0|%0, %2}";
11007     }
11008 }
11009   [(set (attr "type")
11010      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11011                           (const_int 0))
11012                       (match_operand 0 "register_operand" ""))
11013                  (match_operand 2 "const1_operand" ""))
11014               (const_string "alu")
11015            ]
11016            (const_string "ishift")))
11017    (set_attr "mode" "HI")])
11018
11019 (define_insn "*ashlhi3_cconly"
11020   [(set (reg FLAGS_REG)
11021         (compare
11022           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11023                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11024           (const_int 0)))
11025    (clobber (match_scratch:HI 0 "=r"))]
11026   "ix86_match_ccmode (insn, CCGOCmode)
11027    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11028    && (optimize_size
11029        || !TARGET_PARTIAL_FLAG_REG_STALL
11030        || (operands[2] == const1_rtx
11031            && (TARGET_SHIFT1
11032                || TARGET_DOUBLE_WITH_ADD)))"
11033 {
11034   switch (get_attr_type (insn))
11035     {
11036     case TYPE_ALU:
11037       gcc_assert (operands[2] == const1_rtx);
11038       return "add{w}\t{%0, %0|%0, %0}";
11039
11040     default:
11041       if (REG_P (operands[2]))
11042         return "sal{w}\t{%b2, %0|%0, %b2}";
11043       else if (operands[2] == const1_rtx
11044                && (TARGET_SHIFT1 || optimize_size))
11045         return "sal{w}\t%0";
11046       else
11047         return "sal{w}\t{%2, %0|%0, %2}";
11048     }
11049 }
11050   [(set (attr "type")
11051      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11052                           (const_int 0))
11053                       (match_operand 0 "register_operand" ""))
11054                  (match_operand 2 "const1_operand" ""))
11055               (const_string "alu")
11056            ]
11057            (const_string "ishift")))
11058    (set_attr "mode" "HI")])
11059
11060 (define_expand "ashlqi3"
11061   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11062         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11063                    (match_operand:QI 2 "nonmemory_operand" "")))
11064    (clobber (reg:CC FLAGS_REG))]
11065   "TARGET_QIMODE_MATH"
11066   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11067
11068 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11069
11070 (define_insn "*ashlqi3_1_lea"
11071   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11072         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11073                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11074    (clobber (reg:CC FLAGS_REG))]
11075   "!TARGET_PARTIAL_REG_STALL
11076    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11077 {
11078   switch (get_attr_type (insn))
11079     {
11080     case TYPE_LEA:
11081       return "#";
11082     case TYPE_ALU:
11083       gcc_assert (operands[2] == const1_rtx);
11084       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11085         return "add{l}\t{%k0, %k0|%k0, %k0}";
11086       else
11087         return "add{b}\t{%0, %0|%0, %0}";
11088
11089     default:
11090       if (REG_P (operands[2]))
11091         {
11092           if (get_attr_mode (insn) == MODE_SI)
11093             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11094           else
11095             return "sal{b}\t{%b2, %0|%0, %b2}";
11096         }
11097       else if (operands[2] == const1_rtx
11098                && (TARGET_SHIFT1 || optimize_size))
11099         {
11100           if (get_attr_mode (insn) == MODE_SI)
11101             return "sal{l}\t%0";
11102           else
11103             return "sal{b}\t%0";
11104         }
11105       else
11106         {
11107           if (get_attr_mode (insn) == MODE_SI)
11108             return "sal{l}\t{%2, %k0|%k0, %2}";
11109           else
11110             return "sal{b}\t{%2, %0|%0, %2}";
11111         }
11112     }
11113 }
11114   [(set (attr "type")
11115      (cond [(eq_attr "alternative" "2")
11116               (const_string "lea")
11117             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11118                           (const_int 0))
11119                       (match_operand 0 "register_operand" ""))
11120                  (match_operand 2 "const1_operand" ""))
11121               (const_string "alu")
11122            ]
11123            (const_string "ishift")))
11124    (set_attr "mode" "QI,SI,SI")])
11125
11126 (define_insn "*ashlqi3_1"
11127   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11128         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11129                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11130    (clobber (reg:CC FLAGS_REG))]
11131   "TARGET_PARTIAL_REG_STALL
11132    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11133 {
11134   switch (get_attr_type (insn))
11135     {
11136     case TYPE_ALU:
11137       gcc_assert (operands[2] == const1_rtx);
11138       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11139         return "add{l}\t{%k0, %k0|%k0, %k0}";
11140       else
11141         return "add{b}\t{%0, %0|%0, %0}";
11142
11143     default:
11144       if (REG_P (operands[2]))
11145         {
11146           if (get_attr_mode (insn) == MODE_SI)
11147             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11148           else
11149             return "sal{b}\t{%b2, %0|%0, %b2}";
11150         }
11151       else if (operands[2] == const1_rtx
11152                && (TARGET_SHIFT1 || optimize_size))
11153         {
11154           if (get_attr_mode (insn) == MODE_SI)
11155             return "sal{l}\t%0";
11156           else
11157             return "sal{b}\t%0";
11158         }
11159       else
11160         {
11161           if (get_attr_mode (insn) == MODE_SI)
11162             return "sal{l}\t{%2, %k0|%k0, %2}";
11163           else
11164             return "sal{b}\t{%2, %0|%0, %2}";
11165         }
11166     }
11167 }
11168   [(set (attr "type")
11169      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11170                           (const_int 0))
11171                       (match_operand 0 "register_operand" ""))
11172                  (match_operand 2 "const1_operand" ""))
11173               (const_string "alu")
11174            ]
11175            (const_string "ishift")))
11176    (set_attr "mode" "QI,SI")])
11177
11178 ;; This pattern can't accept a variable shift count, since shifts by
11179 ;; zero don't affect the flags.  We assume that shifts by constant
11180 ;; zero are optimized away.
11181 (define_insn "*ashlqi3_cmp"
11182   [(set (reg FLAGS_REG)
11183         (compare
11184           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11185                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11186           (const_int 0)))
11187    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11188         (ashift:QI (match_dup 1) (match_dup 2)))]
11189   "ix86_match_ccmode (insn, CCGOCmode)
11190    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11191    && (optimize_size
11192        || !TARGET_PARTIAL_FLAG_REG_STALL
11193        || (operands[2] == const1_rtx
11194            && (TARGET_SHIFT1
11195                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11196 {
11197   switch (get_attr_type (insn))
11198     {
11199     case TYPE_ALU:
11200       gcc_assert (operands[2] == const1_rtx);
11201       return "add{b}\t{%0, %0|%0, %0}";
11202
11203     default:
11204       if (REG_P (operands[2]))
11205         return "sal{b}\t{%b2, %0|%0, %b2}";
11206       else if (operands[2] == const1_rtx
11207                && (TARGET_SHIFT1 || optimize_size))
11208         return "sal{b}\t%0";
11209       else
11210         return "sal{b}\t{%2, %0|%0, %2}";
11211     }
11212 }
11213   [(set (attr "type")
11214      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11215                           (const_int 0))
11216                       (match_operand 0 "register_operand" ""))
11217                  (match_operand 2 "const1_operand" ""))
11218               (const_string "alu")
11219            ]
11220            (const_string "ishift")))
11221    (set_attr "mode" "QI")])
11222
11223 (define_insn "*ashlqi3_cconly"
11224   [(set (reg FLAGS_REG)
11225         (compare
11226           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11227                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11228           (const_int 0)))
11229    (clobber (match_scratch:QI 0 "=q"))]
11230   "ix86_match_ccmode (insn, CCGOCmode)
11231    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11232    && (optimize_size
11233        || !TARGET_PARTIAL_FLAG_REG_STALL
11234        || (operands[2] == const1_rtx
11235            && (TARGET_SHIFT1
11236                || TARGET_DOUBLE_WITH_ADD)))"
11237 {
11238   switch (get_attr_type (insn))
11239     {
11240     case TYPE_ALU:
11241       gcc_assert (operands[2] == const1_rtx);
11242       return "add{b}\t{%0, %0|%0, %0}";
11243
11244     default:
11245       if (REG_P (operands[2]))
11246         return "sal{b}\t{%b2, %0|%0, %b2}";
11247       else if (operands[2] == const1_rtx
11248                && (TARGET_SHIFT1 || optimize_size))
11249         return "sal{b}\t%0";
11250       else
11251         return "sal{b}\t{%2, %0|%0, %2}";
11252     }
11253 }
11254   [(set (attr "type")
11255      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11256                           (const_int 0))
11257                       (match_operand 0 "register_operand" ""))
11258                  (match_operand 2 "const1_operand" ""))
11259               (const_string "alu")
11260            ]
11261            (const_string "ishift")))
11262    (set_attr "mode" "QI")])
11263
11264 ;; See comment above `ashldi3' about how this works.
11265
11266 (define_expand "ashrti3"
11267   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11268                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11269                                 (match_operand:QI 2 "nonmemory_operand" "")))
11270               (clobber (reg:CC FLAGS_REG))])]
11271   "TARGET_64BIT"
11272 {
11273   if (! immediate_operand (operands[2], QImode))
11274     {
11275       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11276       DONE;
11277     }
11278   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11279   DONE;
11280 })
11281
11282 (define_insn "ashrti3_1"
11283   [(set (match_operand:TI 0 "register_operand" "=r")
11284         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11285                      (match_operand:QI 2 "register_operand" "c")))
11286    (clobber (match_scratch:DI 3 "=&r"))
11287    (clobber (reg:CC FLAGS_REG))]
11288   "TARGET_64BIT"
11289   "#"
11290   [(set_attr "type" "multi")])
11291
11292 (define_insn "*ashrti3_2"
11293   [(set (match_operand:TI 0 "register_operand" "=r")
11294         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11295                      (match_operand:QI 2 "immediate_operand" "O")))
11296    (clobber (reg:CC FLAGS_REG))]
11297   "TARGET_64BIT"
11298   "#"
11299   [(set_attr "type" "multi")])
11300
11301 (define_split
11302   [(set (match_operand:TI 0 "register_operand" "")
11303         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11304                      (match_operand:QI 2 "register_operand" "")))
11305    (clobber (match_scratch:DI 3 ""))
11306    (clobber (reg:CC FLAGS_REG))]
11307   "TARGET_64BIT && reload_completed"
11308   [(const_int 0)]
11309   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11310
11311 (define_split
11312   [(set (match_operand:TI 0 "register_operand" "")
11313         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11314                      (match_operand:QI 2 "immediate_operand" "")))
11315    (clobber (reg:CC FLAGS_REG))]
11316   "TARGET_64BIT && reload_completed"
11317   [(const_int 0)]
11318   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11319
11320 (define_insn "x86_64_shrd"
11321   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11322         (ior:DI (ashiftrt:DI (match_dup 0)
11323                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11324                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11325                   (minus:QI (const_int 64) (match_dup 2)))))
11326    (clobber (reg:CC FLAGS_REG))]
11327   "TARGET_64BIT"
11328   "@
11329    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11330    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11331   [(set_attr "type" "ishift")
11332    (set_attr "prefix_0f" "1")
11333    (set_attr "mode" "DI")
11334    (set_attr "athlon_decode" "vector")])
11335
11336 (define_expand "ashrdi3"
11337   [(set (match_operand:DI 0 "shiftdi_operand" "")
11338         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11339                      (match_operand:QI 2 "nonmemory_operand" "")))]
11340   ""
11341   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11342
11343 (define_insn "*ashrdi3_63_rex64"
11344   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11345         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11346                      (match_operand:DI 2 "const_int_operand" "i,i")))
11347    (clobber (reg:CC FLAGS_REG))]
11348   "TARGET_64BIT && INTVAL (operands[2]) == 63
11349    && (TARGET_USE_CLTD || optimize_size)
11350    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11351   "@
11352    {cqto|cqo}
11353    sar{q}\t{%2, %0|%0, %2}"
11354   [(set_attr "type" "imovx,ishift")
11355    (set_attr "prefix_0f" "0,*")
11356    (set_attr "length_immediate" "0,*")
11357    (set_attr "modrm" "0,1")
11358    (set_attr "mode" "DI")])
11359
11360 (define_insn "*ashrdi3_1_one_bit_rex64"
11361   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11362         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11363                      (match_operand:QI 2 "const1_operand" "")))
11364    (clobber (reg:CC FLAGS_REG))]
11365   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11366    && (TARGET_SHIFT1 || optimize_size)"
11367   "sar{q}\t%0"
11368   [(set_attr "type" "ishift")
11369    (set (attr "length")
11370      (if_then_else (match_operand:DI 0 "register_operand" "")
11371         (const_string "2")
11372         (const_string "*")))])
11373
11374 (define_insn "*ashrdi3_1_rex64"
11375   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11376         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11377                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11378    (clobber (reg:CC FLAGS_REG))]
11379   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11380   "@
11381    sar{q}\t{%2, %0|%0, %2}
11382    sar{q}\t{%b2, %0|%0, %b2}"
11383   [(set_attr "type" "ishift")
11384    (set_attr "mode" "DI")])
11385
11386 ;; This pattern can't accept a variable shift count, since shifts by
11387 ;; zero don't affect the flags.  We assume that shifts by constant
11388 ;; zero are optimized away.
11389 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11390   [(set (reg FLAGS_REG)
11391         (compare
11392           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11393                        (match_operand:QI 2 "const1_operand" ""))
11394           (const_int 0)))
11395    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11396         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11397   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11398    && (TARGET_SHIFT1 || optimize_size)
11399    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11400   "sar{q}\t%0"
11401   [(set_attr "type" "ishift")
11402    (set (attr "length")
11403      (if_then_else (match_operand:DI 0 "register_operand" "")
11404         (const_string "2")
11405         (const_string "*")))])
11406
11407 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11408   [(set (reg FLAGS_REG)
11409         (compare
11410           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11411                        (match_operand:QI 2 "const1_operand" ""))
11412           (const_int 0)))
11413    (clobber (match_scratch:DI 0 "=r"))]
11414   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11415    && (TARGET_SHIFT1 || optimize_size)
11416    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11417   "sar{q}\t%0"
11418   [(set_attr "type" "ishift")
11419    (set_attr "length" "2")])
11420
11421 ;; This pattern can't accept a variable shift count, since shifts by
11422 ;; zero don't affect the flags.  We assume that shifts by constant
11423 ;; zero are optimized away.
11424 (define_insn "*ashrdi3_cmp_rex64"
11425   [(set (reg FLAGS_REG)
11426         (compare
11427           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11428                        (match_operand:QI 2 "const_int_operand" "n"))
11429           (const_int 0)))
11430    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11431         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11432   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11433    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11434    && (optimize_size
11435        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11436   "sar{q}\t{%2, %0|%0, %2}"
11437   [(set_attr "type" "ishift")
11438    (set_attr "mode" "DI")])
11439
11440 (define_insn "*ashrdi3_cconly_rex64"
11441   [(set (reg FLAGS_REG)
11442         (compare
11443           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11444                        (match_operand:QI 2 "const_int_operand" "n"))
11445           (const_int 0)))
11446    (clobber (match_scratch:DI 0 "=r"))]
11447   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11448    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11449    && (optimize_size
11450        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11451   "sar{q}\t{%2, %0|%0, %2}"
11452   [(set_attr "type" "ishift")
11453    (set_attr "mode" "DI")])
11454
11455 (define_insn "*ashrdi3_1"
11456   [(set (match_operand:DI 0 "register_operand" "=r")
11457         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11458                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11459    (clobber (reg:CC FLAGS_REG))]
11460   "!TARGET_64BIT"
11461   "#"
11462   [(set_attr "type" "multi")])
11463
11464 ;; By default we don't ask for a scratch register, because when DImode
11465 ;; values are manipulated, registers are already at a premium.  But if
11466 ;; we have one handy, we won't turn it away.
11467 (define_peephole2
11468   [(match_scratch:SI 3 "r")
11469    (parallel [(set (match_operand:DI 0 "register_operand" "")
11470                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11471                                 (match_operand:QI 2 "nonmemory_operand" "")))
11472               (clobber (reg:CC FLAGS_REG))])
11473    (match_dup 3)]
11474   "!TARGET_64BIT && TARGET_CMOVE"
11475   [(const_int 0)]
11476   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11477
11478 (define_split
11479   [(set (match_operand:DI 0 "register_operand" "")
11480         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11481                      (match_operand:QI 2 "nonmemory_operand" "")))
11482    (clobber (reg:CC FLAGS_REG))]
11483   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11484                      ? flow2_completed : reload_completed)"
11485   [(const_int 0)]
11486   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11487
11488 (define_insn "x86_shrd_1"
11489   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11490         (ior:SI (ashiftrt:SI (match_dup 0)
11491                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11492                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11493                   (minus:QI (const_int 32) (match_dup 2)))))
11494    (clobber (reg:CC FLAGS_REG))]
11495   ""
11496   "@
11497    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11498    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11499   [(set_attr "type" "ishift")
11500    (set_attr "prefix_0f" "1")
11501    (set_attr "pent_pair" "np")
11502    (set_attr "mode" "SI")])
11503
11504 (define_expand "x86_shift_adj_3"
11505   [(use (match_operand:SI 0 "register_operand" ""))
11506    (use (match_operand:SI 1 "register_operand" ""))
11507    (use (match_operand:QI 2 "register_operand" ""))]
11508   ""
11509 {
11510   rtx label = gen_label_rtx ();
11511   rtx tmp;
11512
11513   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11514
11515   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11516   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11517   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11518                               gen_rtx_LABEL_REF (VOIDmode, label),
11519                               pc_rtx);
11520   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11521   JUMP_LABEL (tmp) = label;
11522
11523   emit_move_insn (operands[0], operands[1]);
11524   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11525
11526   emit_label (label);
11527   LABEL_NUSES (label) = 1;
11528
11529   DONE;
11530 })
11531
11532 (define_insn "ashrsi3_31"
11533   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11534         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11535                      (match_operand:SI 2 "const_int_operand" "i,i")))
11536    (clobber (reg:CC FLAGS_REG))]
11537   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11538    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11539   "@
11540    {cltd|cdq}
11541    sar{l}\t{%2, %0|%0, %2}"
11542   [(set_attr "type" "imovx,ishift")
11543    (set_attr "prefix_0f" "0,*")
11544    (set_attr "length_immediate" "0,*")
11545    (set_attr "modrm" "0,1")
11546    (set_attr "mode" "SI")])
11547
11548 (define_insn "*ashrsi3_31_zext"
11549   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11550         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11551                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11552    (clobber (reg:CC FLAGS_REG))]
11553   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11554    && INTVAL (operands[2]) == 31
11555    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11556   "@
11557    {cltd|cdq}
11558    sar{l}\t{%2, %k0|%k0, %2}"
11559   [(set_attr "type" "imovx,ishift")
11560    (set_attr "prefix_0f" "0,*")
11561    (set_attr "length_immediate" "0,*")
11562    (set_attr "modrm" "0,1")
11563    (set_attr "mode" "SI")])
11564
11565 (define_expand "ashrsi3"
11566   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11567         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11568                      (match_operand:QI 2 "nonmemory_operand" "")))
11569    (clobber (reg:CC FLAGS_REG))]
11570   ""
11571   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11572
11573 (define_insn "*ashrsi3_1_one_bit"
11574   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11575         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11576                      (match_operand:QI 2 "const1_operand" "")))
11577    (clobber (reg:CC FLAGS_REG))]
11578   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11579    && (TARGET_SHIFT1 || optimize_size)"
11580   "sar{l}\t%0"
11581   [(set_attr "type" "ishift")
11582    (set (attr "length")
11583      (if_then_else (match_operand:SI 0 "register_operand" "")
11584         (const_string "2")
11585         (const_string "*")))])
11586
11587 (define_insn "*ashrsi3_1_one_bit_zext"
11588   [(set (match_operand:DI 0 "register_operand" "=r")
11589         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11590                                      (match_operand:QI 2 "const1_operand" ""))))
11591    (clobber (reg:CC FLAGS_REG))]
11592   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11593    && (TARGET_SHIFT1 || optimize_size)"
11594   "sar{l}\t%k0"
11595   [(set_attr "type" "ishift")
11596    (set_attr "length" "2")])
11597
11598 (define_insn "*ashrsi3_1"
11599   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11600         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11601                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11602    (clobber (reg:CC FLAGS_REG))]
11603   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11604   "@
11605    sar{l}\t{%2, %0|%0, %2}
11606    sar{l}\t{%b2, %0|%0, %b2}"
11607   [(set_attr "type" "ishift")
11608    (set_attr "mode" "SI")])
11609
11610 (define_insn "*ashrsi3_1_zext"
11611   [(set (match_operand:DI 0 "register_operand" "=r,r")
11612         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11613                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11614    (clobber (reg:CC FLAGS_REG))]
11615   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11616   "@
11617    sar{l}\t{%2, %k0|%k0, %2}
11618    sar{l}\t{%b2, %k0|%k0, %b2}"
11619   [(set_attr "type" "ishift")
11620    (set_attr "mode" "SI")])
11621
11622 ;; This pattern can't accept a variable shift count, since shifts by
11623 ;; zero don't affect the flags.  We assume that shifts by constant
11624 ;; zero are optimized away.
11625 (define_insn "*ashrsi3_one_bit_cmp"
11626   [(set (reg FLAGS_REG)
11627         (compare
11628           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11629                        (match_operand:QI 2 "const1_operand" ""))
11630           (const_int 0)))
11631    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11632         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11633   "ix86_match_ccmode (insn, CCGOCmode)
11634    && (TARGET_SHIFT1 || optimize_size)
11635    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11636   "sar{l}\t%0"
11637   [(set_attr "type" "ishift")
11638    (set (attr "length")
11639      (if_then_else (match_operand:SI 0 "register_operand" "")
11640         (const_string "2")
11641         (const_string "*")))])
11642
11643 (define_insn "*ashrsi3_one_bit_cconly"
11644   [(set (reg FLAGS_REG)
11645         (compare
11646           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11647                        (match_operand:QI 2 "const1_operand" ""))
11648           (const_int 0)))
11649    (clobber (match_scratch:SI 0 "=r"))]
11650   "ix86_match_ccmode (insn, CCGOCmode)
11651    && (TARGET_SHIFT1 || optimize_size)
11652    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11653   "sar{l}\t%0"
11654   [(set_attr "type" "ishift")
11655    (set_attr "length" "2")])
11656
11657 (define_insn "*ashrsi3_one_bit_cmp_zext"
11658   [(set (reg FLAGS_REG)
11659         (compare
11660           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11661                        (match_operand:QI 2 "const1_operand" ""))
11662           (const_int 0)))
11663    (set (match_operand:DI 0 "register_operand" "=r")
11664         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11665   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11666    && (TARGET_SHIFT1 || optimize_size)
11667    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11668   "sar{l}\t%k0"
11669   [(set_attr "type" "ishift")
11670    (set_attr "length" "2")])
11671
11672 ;; This pattern can't accept a variable shift count, since shifts by
11673 ;; zero don't affect the flags.  We assume that shifts by constant
11674 ;; zero are optimized away.
11675 (define_insn "*ashrsi3_cmp"
11676   [(set (reg FLAGS_REG)
11677         (compare
11678           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11679                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11680           (const_int 0)))
11681    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11682         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11683   "ix86_match_ccmode (insn, CCGOCmode)
11684    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11685    && (optimize_size
11686        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11687   "sar{l}\t{%2, %0|%0, %2}"
11688   [(set_attr "type" "ishift")
11689    (set_attr "mode" "SI")])
11690
11691 (define_insn "*ashrsi3_cconly"
11692   [(set (reg FLAGS_REG)
11693         (compare
11694           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11695                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11696           (const_int 0)))
11697    (clobber (match_scratch:SI 0 "=r"))]
11698   "ix86_match_ccmode (insn, CCGOCmode)
11699    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11700    && (optimize_size
11701        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11702   "sar{l}\t{%2, %0|%0, %2}"
11703   [(set_attr "type" "ishift")
11704    (set_attr "mode" "SI")])
11705
11706 (define_insn "*ashrsi3_cmp_zext"
11707   [(set (reg FLAGS_REG)
11708         (compare
11709           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11710                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11711           (const_int 0)))
11712    (set (match_operand:DI 0 "register_operand" "=r")
11713         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11714   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11715    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11716    && (optimize_size
11717        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11718   "sar{l}\t{%2, %k0|%k0, %2}"
11719   [(set_attr "type" "ishift")
11720    (set_attr "mode" "SI")])
11721
11722 (define_expand "ashrhi3"
11723   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11724         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11725                      (match_operand:QI 2 "nonmemory_operand" "")))
11726    (clobber (reg:CC FLAGS_REG))]
11727   "TARGET_HIMODE_MATH"
11728   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11729
11730 (define_insn "*ashrhi3_1_one_bit"
11731   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11732         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11733                      (match_operand:QI 2 "const1_operand" "")))
11734    (clobber (reg:CC FLAGS_REG))]
11735   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11736    && (TARGET_SHIFT1 || optimize_size)"
11737   "sar{w}\t%0"
11738   [(set_attr "type" "ishift")
11739    (set (attr "length")
11740      (if_then_else (match_operand 0 "register_operand" "")
11741         (const_string "2")
11742         (const_string "*")))])
11743
11744 (define_insn "*ashrhi3_1"
11745   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11746         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11747                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11748    (clobber (reg:CC FLAGS_REG))]
11749   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11750   "@
11751    sar{w}\t{%2, %0|%0, %2}
11752    sar{w}\t{%b2, %0|%0, %b2}"
11753   [(set_attr "type" "ishift")
11754    (set_attr "mode" "HI")])
11755
11756 ;; This pattern can't accept a variable shift count, since shifts by
11757 ;; zero don't affect the flags.  We assume that shifts by constant
11758 ;; zero are optimized away.
11759 (define_insn "*ashrhi3_one_bit_cmp"
11760   [(set (reg FLAGS_REG)
11761         (compare
11762           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11763                        (match_operand:QI 2 "const1_operand" ""))
11764           (const_int 0)))
11765    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11766         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11767   "ix86_match_ccmode (insn, CCGOCmode)
11768    && (TARGET_SHIFT1 || optimize_size)
11769    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11770   "sar{w}\t%0"
11771   [(set_attr "type" "ishift")
11772    (set (attr "length")
11773      (if_then_else (match_operand 0 "register_operand" "")
11774         (const_string "2")
11775         (const_string "*")))])
11776
11777 (define_insn "*ashrhi3_one_bit_cconly"
11778   [(set (reg FLAGS_REG)
11779         (compare
11780           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11781                        (match_operand:QI 2 "const1_operand" ""))
11782           (const_int 0)))
11783    (clobber (match_scratch:HI 0 "=r"))]
11784   "ix86_match_ccmode (insn, CCGOCmode)
11785    && (TARGET_SHIFT1 || optimize_size)
11786    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11787   "sar{w}\t%0"
11788   [(set_attr "type" "ishift")
11789    (set_attr "length" "2")])
11790
11791 ;; This pattern can't accept a variable shift count, since shifts by
11792 ;; zero don't affect the flags.  We assume that shifts by constant
11793 ;; zero are optimized away.
11794 (define_insn "*ashrhi3_cmp"
11795   [(set (reg FLAGS_REG)
11796         (compare
11797           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11798                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11799           (const_int 0)))
11800    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11801         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11802   "ix86_match_ccmode (insn, CCGOCmode)
11803    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11804    && (optimize_size
11805        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11806   "sar{w}\t{%2, %0|%0, %2}"
11807   [(set_attr "type" "ishift")
11808    (set_attr "mode" "HI")])
11809
11810 (define_insn "*ashrhi3_cconly"
11811   [(set (reg FLAGS_REG)
11812         (compare
11813           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11814                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11815           (const_int 0)))
11816    (clobber (match_scratch:HI 0 "=r"))]
11817   "ix86_match_ccmode (insn, CCGOCmode)
11818    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11819    && (optimize_size
11820        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11821   "sar{w}\t{%2, %0|%0, %2}"
11822   [(set_attr "type" "ishift")
11823    (set_attr "mode" "HI")])
11824
11825 (define_expand "ashrqi3"
11826   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11827         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11828                      (match_operand:QI 2 "nonmemory_operand" "")))
11829    (clobber (reg:CC FLAGS_REG))]
11830   "TARGET_QIMODE_MATH"
11831   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11832
11833 (define_insn "*ashrqi3_1_one_bit"
11834   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11835         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11836                      (match_operand:QI 2 "const1_operand" "")))
11837    (clobber (reg:CC FLAGS_REG))]
11838   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11839    && (TARGET_SHIFT1 || optimize_size)"
11840   "sar{b}\t%0"
11841   [(set_attr "type" "ishift")
11842    (set (attr "length")
11843      (if_then_else (match_operand 0 "register_operand" "")
11844         (const_string "2")
11845         (const_string "*")))])
11846
11847 (define_insn "*ashrqi3_1_one_bit_slp"
11848   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11849         (ashiftrt:QI (match_dup 0)
11850                      (match_operand:QI 1 "const1_operand" "")))
11851    (clobber (reg:CC FLAGS_REG))]
11852   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11853    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11854    && (TARGET_SHIFT1 || optimize_size)"
11855   "sar{b}\t%0"
11856   [(set_attr "type" "ishift1")
11857    (set (attr "length")
11858      (if_then_else (match_operand 0 "register_operand" "")
11859         (const_string "2")
11860         (const_string "*")))])
11861
11862 (define_insn "*ashrqi3_1"
11863   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11864         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11865                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11866    (clobber (reg:CC FLAGS_REG))]
11867   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11868   "@
11869    sar{b}\t{%2, %0|%0, %2}
11870    sar{b}\t{%b2, %0|%0, %b2}"
11871   [(set_attr "type" "ishift")
11872    (set_attr "mode" "QI")])
11873
11874 (define_insn "*ashrqi3_1_slp"
11875   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11876         (ashiftrt:QI (match_dup 0)
11877                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11878    (clobber (reg:CC FLAGS_REG))]
11879   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11880    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11881   "@
11882    sar{b}\t{%1, %0|%0, %1}
11883    sar{b}\t{%b1, %0|%0, %b1}"
11884   [(set_attr "type" "ishift1")
11885    (set_attr "mode" "QI")])
11886
11887 ;; This pattern can't accept a variable shift count, since shifts by
11888 ;; zero don't affect the flags.  We assume that shifts by constant
11889 ;; zero are optimized away.
11890 (define_insn "*ashrqi3_one_bit_cmp"
11891   [(set (reg FLAGS_REG)
11892         (compare
11893           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11894                        (match_operand:QI 2 "const1_operand" "I"))
11895           (const_int 0)))
11896    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11897         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11898   "ix86_match_ccmode (insn, CCGOCmode)
11899    && (TARGET_SHIFT1 || optimize_size)
11900    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11901   "sar{b}\t%0"
11902   [(set_attr "type" "ishift")
11903    (set (attr "length")
11904      (if_then_else (match_operand 0 "register_operand" "")
11905         (const_string "2")
11906         (const_string "*")))])
11907
11908 (define_insn "*ashrqi3_one_bit_cconly"
11909   [(set (reg FLAGS_REG)
11910         (compare
11911           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11912                        (match_operand:QI 2 "const1_operand" "I"))
11913           (const_int 0)))
11914    (clobber (match_scratch:QI 0 "=q"))]
11915   "ix86_match_ccmode (insn, CCGOCmode)
11916    && (TARGET_SHIFT1 || optimize_size)
11917    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11918   "sar{b}\t%0"
11919   [(set_attr "type" "ishift")
11920    (set_attr "length" "2")])
11921
11922 ;; This pattern can't accept a variable shift count, since shifts by
11923 ;; zero don't affect the flags.  We assume that shifts by constant
11924 ;; zero are optimized away.
11925 (define_insn "*ashrqi3_cmp"
11926   [(set (reg FLAGS_REG)
11927         (compare
11928           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11929                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11930           (const_int 0)))
11931    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11932         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11933   "ix86_match_ccmode (insn, CCGOCmode)
11934    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11935    && (optimize_size
11936        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11937   "sar{b}\t{%2, %0|%0, %2}"
11938   [(set_attr "type" "ishift")
11939    (set_attr "mode" "QI")])
11940
11941 (define_insn "*ashrqi3_cconly"
11942   [(set (reg FLAGS_REG)
11943         (compare
11944           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11945                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11946           (const_int 0)))
11947    (clobber (match_scratch:QI 0 "=q"))]
11948   "ix86_match_ccmode (insn, CCGOCmode)
11949    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11950    && (optimize_size
11951        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11952   "sar{b}\t{%2, %0|%0, %2}"
11953   [(set_attr "type" "ishift")
11954    (set_attr "mode" "QI")])
11955
11956 \f
11957 ;; Logical shift instructions
11958
11959 ;; See comment above `ashldi3' about how this works.
11960
11961 (define_expand "lshrti3"
11962   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11963                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11964                                 (match_operand:QI 2 "nonmemory_operand" "")))
11965               (clobber (reg:CC FLAGS_REG))])]
11966   "TARGET_64BIT"
11967 {
11968   if (! immediate_operand (operands[2], QImode))
11969     {
11970       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11971       DONE;
11972     }
11973   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11974   DONE;
11975 })
11976
11977 (define_insn "lshrti3_1"
11978   [(set (match_operand:TI 0 "register_operand" "=r")
11979         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11980                      (match_operand:QI 2 "register_operand" "c")))
11981    (clobber (match_scratch:DI 3 "=&r"))
11982    (clobber (reg:CC FLAGS_REG))]
11983   "TARGET_64BIT"
11984   "#"
11985   [(set_attr "type" "multi")])
11986
11987 (define_insn "*lshrti3_2"
11988   [(set (match_operand:TI 0 "register_operand" "=r")
11989         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11990                      (match_operand:QI 2 "immediate_operand" "O")))
11991    (clobber (reg:CC FLAGS_REG))]
11992   "TARGET_64BIT"
11993   "#"
11994   [(set_attr "type" "multi")])
11995
11996 (define_split
11997   [(set (match_operand:TI 0 "register_operand" "")
11998         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11999                      (match_operand:QI 2 "register_operand" "")))
12000    (clobber (match_scratch:DI 3 ""))
12001    (clobber (reg:CC FLAGS_REG))]
12002   "TARGET_64BIT && reload_completed"
12003   [(const_int 0)]
12004   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12005
12006 (define_split
12007   [(set (match_operand:TI 0 "register_operand" "")
12008         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12009                      (match_operand:QI 2 "immediate_operand" "")))
12010    (clobber (reg:CC FLAGS_REG))]
12011   "TARGET_64BIT && reload_completed"
12012   [(const_int 0)]
12013   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12014
12015 (define_expand "lshrdi3"
12016   [(set (match_operand:DI 0 "shiftdi_operand" "")
12017         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12018                      (match_operand:QI 2 "nonmemory_operand" "")))]
12019   ""
12020   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12021
12022 (define_insn "*lshrdi3_1_one_bit_rex64"
12023   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12024         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12025                      (match_operand:QI 2 "const1_operand" "")))
12026    (clobber (reg:CC FLAGS_REG))]
12027   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12028    && (TARGET_SHIFT1 || optimize_size)"
12029   "shr{q}\t%0"
12030   [(set_attr "type" "ishift")
12031    (set (attr "length")
12032      (if_then_else (match_operand:DI 0 "register_operand" "")
12033         (const_string "2")
12034         (const_string "*")))])
12035
12036 (define_insn "*lshrdi3_1_rex64"
12037   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12038         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12039                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12040    (clobber (reg:CC FLAGS_REG))]
12041   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12042   "@
12043    shr{q}\t{%2, %0|%0, %2}
12044    shr{q}\t{%b2, %0|%0, %b2}"
12045   [(set_attr "type" "ishift")
12046    (set_attr "mode" "DI")])
12047
12048 ;; This pattern can't accept a variable shift count, since shifts by
12049 ;; zero don't affect the flags.  We assume that shifts by constant
12050 ;; zero are optimized away.
12051 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12052   [(set (reg FLAGS_REG)
12053         (compare
12054           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12055                        (match_operand:QI 2 "const1_operand" ""))
12056           (const_int 0)))
12057    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12058         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12059   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12060    && (TARGET_SHIFT1 || optimize_size)
12061    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12062   "shr{q}\t%0"
12063   [(set_attr "type" "ishift")
12064    (set (attr "length")
12065      (if_then_else (match_operand:DI 0 "register_operand" "")
12066         (const_string "2")
12067         (const_string "*")))])
12068
12069 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12070   [(set (reg FLAGS_REG)
12071         (compare
12072           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12073                        (match_operand:QI 2 "const1_operand" ""))
12074           (const_int 0)))
12075    (clobber (match_scratch:DI 0 "=r"))]
12076   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12077    && (TARGET_SHIFT1 || optimize_size)
12078    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12079   "shr{q}\t%0"
12080   [(set_attr "type" "ishift")
12081    (set_attr "length" "2")])
12082
12083 ;; This pattern can't accept a variable shift count, since shifts by
12084 ;; zero don't affect the flags.  We assume that shifts by constant
12085 ;; zero are optimized away.
12086 (define_insn "*lshrdi3_cmp_rex64"
12087   [(set (reg FLAGS_REG)
12088         (compare
12089           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12090                        (match_operand:QI 2 "const_int_operand" "e"))
12091           (const_int 0)))
12092    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12093         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12094   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12095    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12096    && (optimize_size
12097        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12098   "shr{q}\t{%2, %0|%0, %2}"
12099   [(set_attr "type" "ishift")
12100    (set_attr "mode" "DI")])
12101
12102 (define_insn "*lshrdi3_cconly_rex64"
12103   [(set (reg FLAGS_REG)
12104         (compare
12105           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12106                        (match_operand:QI 2 "const_int_operand" "e"))
12107           (const_int 0)))
12108    (clobber (match_scratch:DI 0 "=r"))]
12109   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12110    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12111    && (optimize_size
12112        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12113   "shr{q}\t{%2, %0|%0, %2}"
12114   [(set_attr "type" "ishift")
12115    (set_attr "mode" "DI")])
12116
12117 (define_insn "*lshrdi3_1"
12118   [(set (match_operand:DI 0 "register_operand" "=r")
12119         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12120                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12121    (clobber (reg:CC FLAGS_REG))]
12122   "!TARGET_64BIT"
12123   "#"
12124   [(set_attr "type" "multi")])
12125
12126 ;; By default we don't ask for a scratch register, because when DImode
12127 ;; values are manipulated, registers are already at a premium.  But if
12128 ;; we have one handy, we won't turn it away.
12129 (define_peephole2
12130   [(match_scratch:SI 3 "r")
12131    (parallel [(set (match_operand:DI 0 "register_operand" "")
12132                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12133                                 (match_operand:QI 2 "nonmemory_operand" "")))
12134               (clobber (reg:CC FLAGS_REG))])
12135    (match_dup 3)]
12136   "!TARGET_64BIT && TARGET_CMOVE"
12137   [(const_int 0)]
12138   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12139
12140 (define_split
12141   [(set (match_operand:DI 0 "register_operand" "")
12142         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12143                      (match_operand:QI 2 "nonmemory_operand" "")))
12144    (clobber (reg:CC FLAGS_REG))]
12145   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12146                      ? flow2_completed : reload_completed)"
12147   [(const_int 0)]
12148   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12149
12150 (define_expand "lshrsi3"
12151   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12152         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12153                      (match_operand:QI 2 "nonmemory_operand" "")))
12154    (clobber (reg:CC FLAGS_REG))]
12155   ""
12156   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12157
12158 (define_insn "*lshrsi3_1_one_bit"
12159   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12160         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12161                      (match_operand:QI 2 "const1_operand" "")))
12162    (clobber (reg:CC FLAGS_REG))]
12163   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12164    && (TARGET_SHIFT1 || optimize_size)"
12165   "shr{l}\t%0"
12166   [(set_attr "type" "ishift")
12167    (set (attr "length")
12168      (if_then_else (match_operand:SI 0 "register_operand" "")
12169         (const_string "2")
12170         (const_string "*")))])
12171
12172 (define_insn "*lshrsi3_1_one_bit_zext"
12173   [(set (match_operand:DI 0 "register_operand" "=r")
12174         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12175                      (match_operand:QI 2 "const1_operand" "")))
12176    (clobber (reg:CC FLAGS_REG))]
12177   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12178    && (TARGET_SHIFT1 || optimize_size)"
12179   "shr{l}\t%k0"
12180   [(set_attr "type" "ishift")
12181    (set_attr "length" "2")])
12182
12183 (define_insn "*lshrsi3_1"
12184   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12185         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12186                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12187    (clobber (reg:CC FLAGS_REG))]
12188   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12189   "@
12190    shr{l}\t{%2, %0|%0, %2}
12191    shr{l}\t{%b2, %0|%0, %b2}"
12192   [(set_attr "type" "ishift")
12193    (set_attr "mode" "SI")])
12194
12195 (define_insn "*lshrsi3_1_zext"
12196   [(set (match_operand:DI 0 "register_operand" "=r,r")
12197         (zero_extend:DI
12198           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12199                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12200    (clobber (reg:CC FLAGS_REG))]
12201   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12202   "@
12203    shr{l}\t{%2, %k0|%k0, %2}
12204    shr{l}\t{%b2, %k0|%k0, %b2}"
12205   [(set_attr "type" "ishift")
12206    (set_attr "mode" "SI")])
12207
12208 ;; This pattern can't accept a variable shift count, since shifts by
12209 ;; zero don't affect the flags.  We assume that shifts by constant
12210 ;; zero are optimized away.
12211 (define_insn "*lshrsi3_one_bit_cmp"
12212   [(set (reg FLAGS_REG)
12213         (compare
12214           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12215                        (match_operand:QI 2 "const1_operand" ""))
12216           (const_int 0)))
12217    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12218         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12219   "ix86_match_ccmode (insn, CCGOCmode)
12220    && (TARGET_SHIFT1 || optimize_size)
12221    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12222   "shr{l}\t%0"
12223   [(set_attr "type" "ishift")
12224    (set (attr "length")
12225      (if_then_else (match_operand:SI 0 "register_operand" "")
12226         (const_string "2")
12227         (const_string "*")))])
12228
12229 (define_insn "*lshrsi3_one_bit_cconly"
12230   [(set (reg FLAGS_REG)
12231         (compare
12232           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12233                        (match_operand:QI 2 "const1_operand" ""))
12234           (const_int 0)))
12235    (clobber (match_scratch:SI 0 "=r"))]
12236   "ix86_match_ccmode (insn, CCGOCmode)
12237    && (TARGET_SHIFT1 || optimize_size)
12238    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12239   "shr{l}\t%0"
12240   [(set_attr "type" "ishift")
12241    (set_attr "length" "2")])
12242
12243 (define_insn "*lshrsi3_cmp_one_bit_zext"
12244   [(set (reg FLAGS_REG)
12245         (compare
12246           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12247                        (match_operand:QI 2 "const1_operand" ""))
12248           (const_int 0)))
12249    (set (match_operand:DI 0 "register_operand" "=r")
12250         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12251   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12252    && (TARGET_SHIFT1 || optimize_size)
12253    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12254   "shr{l}\t%k0"
12255   [(set_attr "type" "ishift")
12256    (set_attr "length" "2")])
12257
12258 ;; This pattern can't accept a variable shift count, since shifts by
12259 ;; zero don't affect the flags.  We assume that shifts by constant
12260 ;; zero are optimized away.
12261 (define_insn "*lshrsi3_cmp"
12262   [(set (reg FLAGS_REG)
12263         (compare
12264           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12265                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12266           (const_int 0)))
12267    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12268         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12269   "ix86_match_ccmode (insn, CCGOCmode)
12270    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12271    && (optimize_size
12272        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12273   "shr{l}\t{%2, %0|%0, %2}"
12274   [(set_attr "type" "ishift")
12275    (set_attr "mode" "SI")])
12276
12277 (define_insn "*lshrsi3_cconly"
12278   [(set (reg FLAGS_REG)
12279       (compare
12280         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12281                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12282         (const_int 0)))
12283    (clobber (match_scratch:SI 0 "=r"))]
12284   "ix86_match_ccmode (insn, CCGOCmode)
12285    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12286    && (optimize_size
12287        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12288   "shr{l}\t{%2, %0|%0, %2}"
12289   [(set_attr "type" "ishift")
12290    (set_attr "mode" "SI")])
12291
12292 (define_insn "*lshrsi3_cmp_zext"
12293   [(set (reg FLAGS_REG)
12294         (compare
12295           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12296                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12297           (const_int 0)))
12298    (set (match_operand:DI 0 "register_operand" "=r")
12299         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12300   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12301    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12302    && (optimize_size
12303        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12304   "shr{l}\t{%2, %k0|%k0, %2}"
12305   [(set_attr "type" "ishift")
12306    (set_attr "mode" "SI")])
12307
12308 (define_expand "lshrhi3"
12309   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12310         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12311                      (match_operand:QI 2 "nonmemory_operand" "")))
12312    (clobber (reg:CC FLAGS_REG))]
12313   "TARGET_HIMODE_MATH"
12314   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12315
12316 (define_insn "*lshrhi3_1_one_bit"
12317   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12318         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12319                      (match_operand:QI 2 "const1_operand" "")))
12320    (clobber (reg:CC FLAGS_REG))]
12321   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12322    && (TARGET_SHIFT1 || optimize_size)"
12323   "shr{w}\t%0"
12324   [(set_attr "type" "ishift")
12325    (set (attr "length")
12326      (if_then_else (match_operand 0 "register_operand" "")
12327         (const_string "2")
12328         (const_string "*")))])
12329
12330 (define_insn "*lshrhi3_1"
12331   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12332         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12333                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12334    (clobber (reg:CC FLAGS_REG))]
12335   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12336   "@
12337    shr{w}\t{%2, %0|%0, %2}
12338    shr{w}\t{%b2, %0|%0, %b2}"
12339   [(set_attr "type" "ishift")
12340    (set_attr "mode" "HI")])
12341
12342 ;; This pattern can't accept a variable shift count, since shifts by
12343 ;; zero don't affect the flags.  We assume that shifts by constant
12344 ;; zero are optimized away.
12345 (define_insn "*lshrhi3_one_bit_cmp"
12346   [(set (reg FLAGS_REG)
12347         (compare
12348           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12349                        (match_operand:QI 2 "const1_operand" ""))
12350           (const_int 0)))
12351    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12352         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12353   "ix86_match_ccmode (insn, CCGOCmode)
12354    && (TARGET_SHIFT1 || optimize_size)
12355    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12356   "shr{w}\t%0"
12357   [(set_attr "type" "ishift")
12358    (set (attr "length")
12359      (if_then_else (match_operand:SI 0 "register_operand" "")
12360         (const_string "2")
12361         (const_string "*")))])
12362
12363 (define_insn "*lshrhi3_one_bit_cconly"
12364   [(set (reg FLAGS_REG)
12365         (compare
12366           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12367                        (match_operand:QI 2 "const1_operand" ""))
12368           (const_int 0)))
12369    (clobber (match_scratch:HI 0 "=r"))]
12370   "ix86_match_ccmode (insn, CCGOCmode)
12371    && (TARGET_SHIFT1 || optimize_size)
12372    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12373   "shr{w}\t%0"
12374   [(set_attr "type" "ishift")
12375    (set_attr "length" "2")])
12376
12377 ;; This pattern can't accept a variable shift count, since shifts by
12378 ;; zero don't affect the flags.  We assume that shifts by constant
12379 ;; zero are optimized away.
12380 (define_insn "*lshrhi3_cmp"
12381   [(set (reg FLAGS_REG)
12382         (compare
12383           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12384                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12385           (const_int 0)))
12386    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12387         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12388   "ix86_match_ccmode (insn, CCGOCmode)
12389    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12390    && (optimize_size
12391        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12392   "shr{w}\t{%2, %0|%0, %2}"
12393   [(set_attr "type" "ishift")
12394    (set_attr "mode" "HI")])
12395
12396 (define_insn "*lshrhi3_cconly"
12397   [(set (reg FLAGS_REG)
12398         (compare
12399           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12400                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12401           (const_int 0)))
12402    (clobber (match_scratch:HI 0 "=r"))]
12403   "ix86_match_ccmode (insn, CCGOCmode)
12404    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12405    && (optimize_size
12406        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12407   "shr{w}\t{%2, %0|%0, %2}"
12408   [(set_attr "type" "ishift")
12409    (set_attr "mode" "HI")])
12410
12411 (define_expand "lshrqi3"
12412   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12413         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12414                      (match_operand:QI 2 "nonmemory_operand" "")))
12415    (clobber (reg:CC FLAGS_REG))]
12416   "TARGET_QIMODE_MATH"
12417   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12418
12419 (define_insn "*lshrqi3_1_one_bit"
12420   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12421         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12422                      (match_operand:QI 2 "const1_operand" "")))
12423    (clobber (reg:CC FLAGS_REG))]
12424   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12425    && (TARGET_SHIFT1 || optimize_size)"
12426   "shr{b}\t%0"
12427   [(set_attr "type" "ishift")
12428    (set (attr "length")
12429      (if_then_else (match_operand 0 "register_operand" "")
12430         (const_string "2")
12431         (const_string "*")))])
12432
12433 (define_insn "*lshrqi3_1_one_bit_slp"
12434   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12435         (lshiftrt:QI (match_dup 0)
12436                      (match_operand:QI 1 "const1_operand" "")))
12437    (clobber (reg:CC FLAGS_REG))]
12438   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12439    && (TARGET_SHIFT1 || optimize_size)"
12440   "shr{b}\t%0"
12441   [(set_attr "type" "ishift1")
12442    (set (attr "length")
12443      (if_then_else (match_operand 0 "register_operand" "")
12444         (const_string "2")
12445         (const_string "*")))])
12446
12447 (define_insn "*lshrqi3_1"
12448   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12449         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12450                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12451    (clobber (reg:CC FLAGS_REG))]
12452   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12453   "@
12454    shr{b}\t{%2, %0|%0, %2}
12455    shr{b}\t{%b2, %0|%0, %b2}"
12456   [(set_attr "type" "ishift")
12457    (set_attr "mode" "QI")])
12458
12459 (define_insn "*lshrqi3_1_slp"
12460   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12461         (lshiftrt:QI (match_dup 0)
12462                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12463    (clobber (reg:CC FLAGS_REG))]
12464   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12465    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12466   "@
12467    shr{b}\t{%1, %0|%0, %1}
12468    shr{b}\t{%b1, %0|%0, %b1}"
12469   [(set_attr "type" "ishift1")
12470    (set_attr "mode" "QI")])
12471
12472 ;; This pattern can't accept a variable shift count, since shifts by
12473 ;; zero don't affect the flags.  We assume that shifts by constant
12474 ;; zero are optimized away.
12475 (define_insn "*lshrqi2_one_bit_cmp"
12476   [(set (reg FLAGS_REG)
12477         (compare
12478           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12479                        (match_operand:QI 2 "const1_operand" ""))
12480           (const_int 0)))
12481    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12482         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12483   "ix86_match_ccmode (insn, CCGOCmode)
12484    && (TARGET_SHIFT1 || optimize_size)
12485    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12486   "shr{b}\t%0"
12487   [(set_attr "type" "ishift")
12488    (set (attr "length")
12489      (if_then_else (match_operand:SI 0 "register_operand" "")
12490         (const_string "2")
12491         (const_string "*")))])
12492
12493 (define_insn "*lshrqi2_one_bit_cconly"
12494   [(set (reg FLAGS_REG)
12495         (compare
12496           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12497                        (match_operand:QI 2 "const1_operand" ""))
12498           (const_int 0)))
12499    (clobber (match_scratch:QI 0 "=q"))]
12500   "ix86_match_ccmode (insn, CCGOCmode)
12501    && (TARGET_SHIFT1 || optimize_size)
12502    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12503   "shr{b}\t%0"
12504   [(set_attr "type" "ishift")
12505    (set_attr "length" "2")])
12506
12507 ;; This pattern can't accept a variable shift count, since shifts by
12508 ;; zero don't affect the flags.  We assume that shifts by constant
12509 ;; zero are optimized away.
12510 (define_insn "*lshrqi2_cmp"
12511   [(set (reg FLAGS_REG)
12512         (compare
12513           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12514                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12515           (const_int 0)))
12516    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12517         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12518   "ix86_match_ccmode (insn, CCGOCmode)
12519    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12520    && (optimize_size
12521        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12522   "shr{b}\t{%2, %0|%0, %2}"
12523   [(set_attr "type" "ishift")
12524    (set_attr "mode" "QI")])
12525
12526 (define_insn "*lshrqi2_cconly"
12527   [(set (reg FLAGS_REG)
12528         (compare
12529           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12530                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12531           (const_int 0)))
12532    (clobber (match_scratch:QI 0 "=q"))]
12533   "ix86_match_ccmode (insn, CCGOCmode)
12534    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12535    && (optimize_size
12536        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12537   "shr{b}\t{%2, %0|%0, %2}"
12538   [(set_attr "type" "ishift")
12539    (set_attr "mode" "QI")])
12540 \f
12541 ;; Rotate instructions
12542
12543 (define_expand "rotldi3"
12544   [(set (match_operand:DI 0 "shiftdi_operand" "")
12545         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12546                    (match_operand:QI 2 "nonmemory_operand" "")))
12547    (clobber (reg:CC FLAGS_REG))]
12548  ""
12549 {
12550   if (TARGET_64BIT)
12551     {
12552       ix86_expand_binary_operator (ROTATE, DImode, operands);
12553       DONE;
12554     }
12555   if (!const_1_to_31_operand (operands[2], VOIDmode))
12556     FAIL;
12557   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12558   DONE;
12559 })
12560
12561 ;; Implement rotation using two double-precision shift instructions
12562 ;; and a scratch register.
12563 (define_insn_and_split "ix86_rotldi3"
12564  [(set (match_operand:DI 0 "register_operand" "=r")
12565        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12566                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12567   (clobber (reg:CC FLAGS_REG))
12568   (clobber (match_scratch:SI 3 "=&r"))]
12569  "!TARGET_64BIT"
12570  ""
12571  "&& reload_completed"
12572  [(set (match_dup 3) (match_dup 4))
12573   (parallel
12574    [(set (match_dup 4)
12575          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12576                  (lshiftrt:SI (match_dup 5)
12577                               (minus:QI (const_int 32) (match_dup 2)))))
12578     (clobber (reg:CC FLAGS_REG))])
12579   (parallel
12580    [(set (match_dup 5)
12581          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12582                  (lshiftrt:SI (match_dup 3)
12583                               (minus:QI (const_int 32) (match_dup 2)))))
12584     (clobber (reg:CC FLAGS_REG))])]
12585  "split_di (operands, 1, operands + 4, operands + 5);")
12586
12587 (define_insn "*rotlsi3_1_one_bit_rex64"
12588   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12589         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12590                    (match_operand:QI 2 "const1_operand" "")))
12591    (clobber (reg:CC FLAGS_REG))]
12592   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12593    && (TARGET_SHIFT1 || optimize_size)"
12594   "rol{q}\t%0"
12595   [(set_attr "type" "rotate")
12596    (set (attr "length")
12597      (if_then_else (match_operand:DI 0 "register_operand" "")
12598         (const_string "2")
12599         (const_string "*")))])
12600
12601 (define_insn "*rotldi3_1_rex64"
12602   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12603         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12604                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12605    (clobber (reg:CC FLAGS_REG))]
12606   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12607   "@
12608    rol{q}\t{%2, %0|%0, %2}
12609    rol{q}\t{%b2, %0|%0, %b2}"
12610   [(set_attr "type" "rotate")
12611    (set_attr "mode" "DI")])
12612
12613 (define_expand "rotlsi3"
12614   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12615         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12616                    (match_operand:QI 2 "nonmemory_operand" "")))
12617    (clobber (reg:CC FLAGS_REG))]
12618   ""
12619   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12620
12621 (define_insn "*rotlsi3_1_one_bit"
12622   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12623         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12624                    (match_operand:QI 2 "const1_operand" "")))
12625    (clobber (reg:CC FLAGS_REG))]
12626   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12627    && (TARGET_SHIFT1 || optimize_size)"
12628   "rol{l}\t%0"
12629   [(set_attr "type" "rotate")
12630    (set (attr "length")
12631      (if_then_else (match_operand:SI 0 "register_operand" "")
12632         (const_string "2")
12633         (const_string "*")))])
12634
12635 (define_insn "*rotlsi3_1_one_bit_zext"
12636   [(set (match_operand:DI 0 "register_operand" "=r")
12637         (zero_extend:DI
12638           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12639                      (match_operand:QI 2 "const1_operand" ""))))
12640    (clobber (reg:CC FLAGS_REG))]
12641   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12642    && (TARGET_SHIFT1 || optimize_size)"
12643   "rol{l}\t%k0"
12644   [(set_attr "type" "rotate")
12645    (set_attr "length" "2")])
12646
12647 (define_insn "*rotlsi3_1"
12648   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12649         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12650                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12651    (clobber (reg:CC FLAGS_REG))]
12652   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12653   "@
12654    rol{l}\t{%2, %0|%0, %2}
12655    rol{l}\t{%b2, %0|%0, %b2}"
12656   [(set_attr "type" "rotate")
12657    (set_attr "mode" "SI")])
12658
12659 (define_insn "*rotlsi3_1_zext"
12660   [(set (match_operand:DI 0 "register_operand" "=r,r")
12661         (zero_extend:DI
12662           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12663                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12664    (clobber (reg:CC FLAGS_REG))]
12665   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12666   "@
12667    rol{l}\t{%2, %k0|%k0, %2}
12668    rol{l}\t{%b2, %k0|%k0, %b2}"
12669   [(set_attr "type" "rotate")
12670    (set_attr "mode" "SI")])
12671
12672 (define_expand "rotlhi3"
12673   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12674         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12675                    (match_operand:QI 2 "nonmemory_operand" "")))
12676    (clobber (reg:CC FLAGS_REG))]
12677   "TARGET_HIMODE_MATH"
12678   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12679
12680 (define_insn "*rotlhi3_1_one_bit"
12681   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12682         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12683                    (match_operand:QI 2 "const1_operand" "")))
12684    (clobber (reg:CC FLAGS_REG))]
12685   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12686    && (TARGET_SHIFT1 || optimize_size)"
12687   "rol{w}\t%0"
12688   [(set_attr "type" "rotate")
12689    (set (attr "length")
12690      (if_then_else (match_operand 0 "register_operand" "")
12691         (const_string "2")
12692         (const_string "*")))])
12693
12694 (define_insn "*rotlhi3_1"
12695   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12696         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12697                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12698    (clobber (reg:CC FLAGS_REG))]
12699   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12700   "@
12701    rol{w}\t{%2, %0|%0, %2}
12702    rol{w}\t{%b2, %0|%0, %b2}"
12703   [(set_attr "type" "rotate")
12704    (set_attr "mode" "HI")])
12705
12706 (define_expand "rotlqi3"
12707   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12708         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12709                    (match_operand:QI 2 "nonmemory_operand" "")))
12710    (clobber (reg:CC FLAGS_REG))]
12711   "TARGET_QIMODE_MATH"
12712   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12713
12714 (define_insn "*rotlqi3_1_one_bit_slp"
12715   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12716         (rotate:QI (match_dup 0)
12717                    (match_operand:QI 1 "const1_operand" "")))
12718    (clobber (reg:CC FLAGS_REG))]
12719   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12720    && (TARGET_SHIFT1 || optimize_size)"
12721   "rol{b}\t%0"
12722   [(set_attr "type" "rotate1")
12723    (set (attr "length")
12724      (if_then_else (match_operand 0 "register_operand" "")
12725         (const_string "2")
12726         (const_string "*")))])
12727
12728 (define_insn "*rotlqi3_1_one_bit"
12729   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12730         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12731                    (match_operand:QI 2 "const1_operand" "")))
12732    (clobber (reg:CC FLAGS_REG))]
12733   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12734    && (TARGET_SHIFT1 || optimize_size)"
12735   "rol{b}\t%0"
12736   [(set_attr "type" "rotate")
12737    (set (attr "length")
12738      (if_then_else (match_operand 0 "register_operand" "")
12739         (const_string "2")
12740         (const_string "*")))])
12741
12742 (define_insn "*rotlqi3_1_slp"
12743   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12744         (rotate:QI (match_dup 0)
12745                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12746    (clobber (reg:CC FLAGS_REG))]
12747   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12748    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12749   "@
12750    rol{b}\t{%1, %0|%0, %1}
12751    rol{b}\t{%b1, %0|%0, %b1}"
12752   [(set_attr "type" "rotate1")
12753    (set_attr "mode" "QI")])
12754
12755 (define_insn "*rotlqi3_1"
12756   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12757         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12758                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12759    (clobber (reg:CC FLAGS_REG))]
12760   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12761   "@
12762    rol{b}\t{%2, %0|%0, %2}
12763    rol{b}\t{%b2, %0|%0, %b2}"
12764   [(set_attr "type" "rotate")
12765    (set_attr "mode" "QI")])
12766
12767 (define_expand "rotrdi3"
12768   [(set (match_operand:DI 0 "shiftdi_operand" "")
12769         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12770                    (match_operand:QI 2 "nonmemory_operand" "")))
12771    (clobber (reg:CC FLAGS_REG))]
12772  ""
12773 {
12774   if (TARGET_64BIT)
12775     {
12776       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12777       DONE;
12778     }
12779   if (!const_1_to_31_operand (operands[2], VOIDmode))
12780     FAIL;
12781   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12782   DONE;
12783 })
12784
12785 ;; Implement rotation using two double-precision shift instructions
12786 ;; and a scratch register.
12787 (define_insn_and_split "ix86_rotrdi3"
12788  [(set (match_operand:DI 0 "register_operand" "=r")
12789        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12790                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12791   (clobber (reg:CC FLAGS_REG))
12792   (clobber (match_scratch:SI 3 "=&r"))]
12793  "!TARGET_64BIT"
12794  ""
12795  "&& reload_completed"
12796  [(set (match_dup 3) (match_dup 4))
12797   (parallel
12798    [(set (match_dup 4)
12799          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12800                  (ashift:SI (match_dup 5)
12801                             (minus:QI (const_int 32) (match_dup 2)))))
12802     (clobber (reg:CC FLAGS_REG))])
12803   (parallel
12804    [(set (match_dup 5)
12805          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12806                  (ashift:SI (match_dup 3)
12807                             (minus:QI (const_int 32) (match_dup 2)))))
12808     (clobber (reg:CC FLAGS_REG))])]
12809  "split_di (operands, 1, operands + 4, operands + 5);")
12810
12811 (define_insn "*rotrdi3_1_one_bit_rex64"
12812   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12813         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12814                      (match_operand:QI 2 "const1_operand" "")))
12815    (clobber (reg:CC FLAGS_REG))]
12816   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12817    && (TARGET_SHIFT1 || optimize_size)"
12818   "ror{q}\t%0"
12819   [(set_attr "type" "rotate")
12820    (set (attr "length")
12821      (if_then_else (match_operand:DI 0 "register_operand" "")
12822         (const_string "2")
12823         (const_string "*")))])
12824
12825 (define_insn "*rotrdi3_1_rex64"
12826   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12827         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12828                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12829    (clobber (reg:CC FLAGS_REG))]
12830   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12831   "@
12832    ror{q}\t{%2, %0|%0, %2}
12833    ror{q}\t{%b2, %0|%0, %b2}"
12834   [(set_attr "type" "rotate")
12835    (set_attr "mode" "DI")])
12836
12837 (define_expand "rotrsi3"
12838   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12839         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12840                      (match_operand:QI 2 "nonmemory_operand" "")))
12841    (clobber (reg:CC FLAGS_REG))]
12842   ""
12843   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12844
12845 (define_insn "*rotrsi3_1_one_bit"
12846   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12847         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12848                      (match_operand:QI 2 "const1_operand" "")))
12849    (clobber (reg:CC FLAGS_REG))]
12850   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12851    && (TARGET_SHIFT1 || optimize_size)"
12852   "ror{l}\t%0"
12853   [(set_attr "type" "rotate")
12854    (set (attr "length")
12855      (if_then_else (match_operand:SI 0 "register_operand" "")
12856         (const_string "2")
12857         (const_string "*")))])
12858
12859 (define_insn "*rotrsi3_1_one_bit_zext"
12860   [(set (match_operand:DI 0 "register_operand" "=r")
12861         (zero_extend:DI
12862           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12863                        (match_operand:QI 2 "const1_operand" ""))))
12864    (clobber (reg:CC FLAGS_REG))]
12865   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12866    && (TARGET_SHIFT1 || optimize_size)"
12867   "ror{l}\t%k0"
12868   [(set_attr "type" "rotate")
12869    (set (attr "length")
12870      (if_then_else (match_operand:SI 0 "register_operand" "")
12871         (const_string "2")
12872         (const_string "*")))])
12873
12874 (define_insn "*rotrsi3_1"
12875   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12876         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12877                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12878    (clobber (reg:CC FLAGS_REG))]
12879   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12880   "@
12881    ror{l}\t{%2, %0|%0, %2}
12882    ror{l}\t{%b2, %0|%0, %b2}"
12883   [(set_attr "type" "rotate")
12884    (set_attr "mode" "SI")])
12885
12886 (define_insn "*rotrsi3_1_zext"
12887   [(set (match_operand:DI 0 "register_operand" "=r,r")
12888         (zero_extend:DI
12889           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12890                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12891    (clobber (reg:CC FLAGS_REG))]
12892   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12893   "@
12894    ror{l}\t{%2, %k0|%k0, %2}
12895    ror{l}\t{%b2, %k0|%k0, %b2}"
12896   [(set_attr "type" "rotate")
12897    (set_attr "mode" "SI")])
12898
12899 (define_expand "rotrhi3"
12900   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12901         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12902                      (match_operand:QI 2 "nonmemory_operand" "")))
12903    (clobber (reg:CC FLAGS_REG))]
12904   "TARGET_HIMODE_MATH"
12905   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12906
12907 (define_insn "*rotrhi3_one_bit"
12908   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12909         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12910                      (match_operand:QI 2 "const1_operand" "")))
12911    (clobber (reg:CC FLAGS_REG))]
12912   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12913    && (TARGET_SHIFT1 || optimize_size)"
12914   "ror{w}\t%0"
12915   [(set_attr "type" "rotate")
12916    (set (attr "length")
12917      (if_then_else (match_operand 0 "register_operand" "")
12918         (const_string "2")
12919         (const_string "*")))])
12920
12921 (define_insn "*rotrhi3"
12922   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12923         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12924                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12925    (clobber (reg:CC FLAGS_REG))]
12926   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12927   "@
12928    ror{w}\t{%2, %0|%0, %2}
12929    ror{w}\t{%b2, %0|%0, %b2}"
12930   [(set_attr "type" "rotate")
12931    (set_attr "mode" "HI")])
12932
12933 (define_expand "rotrqi3"
12934   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12935         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12936                      (match_operand:QI 2 "nonmemory_operand" "")))
12937    (clobber (reg:CC FLAGS_REG))]
12938   "TARGET_QIMODE_MATH"
12939   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12940
12941 (define_insn "*rotrqi3_1_one_bit"
12942   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12943         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12944                      (match_operand:QI 2 "const1_operand" "")))
12945    (clobber (reg:CC FLAGS_REG))]
12946   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12947    && (TARGET_SHIFT1 || optimize_size)"
12948   "ror{b}\t%0"
12949   [(set_attr "type" "rotate")
12950    (set (attr "length")
12951      (if_then_else (match_operand 0 "register_operand" "")
12952         (const_string "2")
12953         (const_string "*")))])
12954
12955 (define_insn "*rotrqi3_1_one_bit_slp"
12956   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12957         (rotatert:QI (match_dup 0)
12958                      (match_operand:QI 1 "const1_operand" "")))
12959    (clobber (reg:CC FLAGS_REG))]
12960   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12961    && (TARGET_SHIFT1 || optimize_size)"
12962   "ror{b}\t%0"
12963   [(set_attr "type" "rotate1")
12964    (set (attr "length")
12965      (if_then_else (match_operand 0 "register_operand" "")
12966         (const_string "2")
12967         (const_string "*")))])
12968
12969 (define_insn "*rotrqi3_1"
12970   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12971         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12972                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12973    (clobber (reg:CC FLAGS_REG))]
12974   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12975   "@
12976    ror{b}\t{%2, %0|%0, %2}
12977    ror{b}\t{%b2, %0|%0, %b2}"
12978   [(set_attr "type" "rotate")
12979    (set_attr "mode" "QI")])
12980
12981 (define_insn "*rotrqi3_1_slp"
12982   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12983         (rotatert:QI (match_dup 0)
12984                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12985    (clobber (reg:CC FLAGS_REG))]
12986   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12987    && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12988   "@
12989    ror{b}\t{%1, %0|%0, %1}
12990    ror{b}\t{%b1, %0|%0, %b1}"
12991   [(set_attr "type" "rotate1")
12992    (set_attr "mode" "QI")])
12993 \f
12994 ;; Bit set / bit test instructions
12995
12996 (define_expand "extv"
12997   [(set (match_operand:SI 0 "register_operand" "")
12998         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12999                          (match_operand:SI 2 "const8_operand" "")
13000                          (match_operand:SI 3 "const8_operand" "")))]
13001   ""
13002 {
13003   /* Handle extractions from %ah et al.  */
13004   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13005     FAIL;
13006
13007   /* From mips.md: extract_bit_field doesn't verify that our source
13008      matches the predicate, so check it again here.  */
13009   if (! ext_register_operand (operands[1], VOIDmode))
13010     FAIL;
13011 })
13012
13013 (define_expand "extzv"
13014   [(set (match_operand:SI 0 "register_operand" "")
13015         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13016                          (match_operand:SI 2 "const8_operand" "")
13017                          (match_operand:SI 3 "const8_operand" "")))]
13018   ""
13019 {
13020   /* Handle extractions from %ah et al.  */
13021   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13022     FAIL;
13023
13024   /* From mips.md: extract_bit_field doesn't verify that our source
13025      matches the predicate, so check it again here.  */
13026   if (! ext_register_operand (operands[1], VOIDmode))
13027     FAIL;
13028 })
13029
13030 (define_expand "insv"
13031   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13032                       (match_operand 1 "const8_operand" "")
13033                       (match_operand 2 "const8_operand" ""))
13034         (match_operand 3 "register_operand" ""))]
13035   ""
13036 {
13037   /* Handle insertions to %ah et al.  */
13038   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13039     FAIL;
13040
13041   /* From mips.md: insert_bit_field doesn't verify that our source
13042      matches the predicate, so check it again here.  */
13043   if (! ext_register_operand (operands[0], VOIDmode))
13044     FAIL;
13045
13046   if (TARGET_64BIT)
13047     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13048   else
13049     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13050
13051   DONE;
13052 })
13053
13054 ;; %%% bts, btr, btc, bt.
13055 ;; In general these instructions are *slow* when applied to memory,
13056 ;; since they enforce atomic operation.  When applied to registers,
13057 ;; it depends on the cpu implementation.  They're never faster than
13058 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13059 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13060 ;; within the instruction itself, so operating on bits in the high
13061 ;; 32-bits of a register becomes easier.
13062 ;;
13063 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13064 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13065 ;; negdf respectively, so they can never be disabled entirely.
13066
13067 (define_insn "*btsq"
13068   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13069                          (const_int 1)
13070                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13071         (const_int 1))
13072    (clobber (reg:CC FLAGS_REG))]
13073   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13074   "bts{q} %1,%0"
13075   [(set_attr "type" "alu1")])
13076
13077 (define_insn "*btrq"
13078   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13079                          (const_int 1)
13080                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13081         (const_int 0))
13082    (clobber (reg:CC FLAGS_REG))]
13083   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13084   "btr{q} %1,%0"
13085   [(set_attr "type" "alu1")])
13086
13087 (define_insn "*btcq"
13088   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13089                          (const_int 1)
13090                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13091         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13092    (clobber (reg:CC FLAGS_REG))]
13093   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13094   "btc{q} %1,%0"
13095   [(set_attr "type" "alu1")])
13096
13097 ;; Allow Nocona to avoid these instructions if a register is available.
13098
13099 (define_peephole2
13100   [(match_scratch:DI 2 "r")
13101    (parallel [(set (zero_extract:DI
13102                      (match_operand:DI 0 "register_operand" "")
13103                      (const_int 1)
13104                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13105                    (const_int 1))
13106               (clobber (reg:CC FLAGS_REG))])]
13107   "TARGET_64BIT && !TARGET_USE_BT"
13108   [(const_int 0)]
13109 {
13110   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13111   rtx op1;
13112
13113   if (HOST_BITS_PER_WIDE_INT >= 64)
13114     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13115   else if (i < HOST_BITS_PER_WIDE_INT)
13116     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13117   else
13118     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13119
13120   op1 = immed_double_const (lo, hi, DImode);
13121   if (i >= 31)
13122     {
13123       emit_move_insn (operands[2], op1);
13124       op1 = operands[2];
13125     }
13126
13127   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13128   DONE;
13129 })
13130
13131 (define_peephole2
13132   [(match_scratch:DI 2 "r")
13133    (parallel [(set (zero_extract:DI
13134                      (match_operand:DI 0 "register_operand" "")
13135                      (const_int 1)
13136                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13137                    (const_int 0))
13138               (clobber (reg:CC FLAGS_REG))])]
13139   "TARGET_64BIT && !TARGET_USE_BT"
13140   [(const_int 0)]
13141 {
13142   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13143   rtx op1;
13144
13145   if (HOST_BITS_PER_WIDE_INT >= 64)
13146     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13147   else if (i < HOST_BITS_PER_WIDE_INT)
13148     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13149   else
13150     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13151
13152   op1 = immed_double_const (~lo, ~hi, DImode);
13153   if (i >= 32)
13154     {
13155       emit_move_insn (operands[2], op1);
13156       op1 = operands[2];
13157     }
13158
13159   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13160   DONE;
13161 })
13162
13163 (define_peephole2
13164   [(match_scratch:DI 2 "r")
13165    (parallel [(set (zero_extract:DI
13166                      (match_operand:DI 0 "register_operand" "")
13167                      (const_int 1)
13168                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13169               (not:DI (zero_extract:DI
13170                         (match_dup 0) (const_int 1) (match_dup 1))))
13171               (clobber (reg:CC FLAGS_REG))])]
13172   "TARGET_64BIT && !TARGET_USE_BT"
13173   [(const_int 0)]
13174 {
13175   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13176   rtx op1;
13177
13178   if (HOST_BITS_PER_WIDE_INT >= 64)
13179     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13180   else if (i < HOST_BITS_PER_WIDE_INT)
13181     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13182   else
13183     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13184
13185   op1 = immed_double_const (lo, hi, DImode);
13186   if (i >= 31)
13187     {
13188       emit_move_insn (operands[2], op1);
13189       op1 = operands[2];
13190     }
13191
13192   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13193   DONE;
13194 })
13195 \f
13196 ;; Store-flag instructions.
13197
13198 ;; For all sCOND expanders, also expand the compare or test insn that
13199 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13200
13201 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13202 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13203 ;; way, which can later delete the movzx if only QImode is needed.
13204
13205 (define_expand "seq"
13206   [(set (match_operand:QI 0 "register_operand" "")
13207         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13208   ""
13209   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13210
13211 (define_expand "sne"
13212   [(set (match_operand:QI 0 "register_operand" "")
13213         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13214   ""
13215   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13216
13217 (define_expand "sgt"
13218   [(set (match_operand:QI 0 "register_operand" "")
13219         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13220   ""
13221   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13222
13223 (define_expand "sgtu"
13224   [(set (match_operand:QI 0 "register_operand" "")
13225         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13226   ""
13227   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13228
13229 (define_expand "slt"
13230   [(set (match_operand:QI 0 "register_operand" "")
13231         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13232   ""
13233   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13234
13235 (define_expand "sltu"
13236   [(set (match_operand:QI 0 "register_operand" "")
13237         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13238   ""
13239   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13240
13241 (define_expand "sge"
13242   [(set (match_operand:QI 0 "register_operand" "")
13243         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13244   ""
13245   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13246
13247 (define_expand "sgeu"
13248   [(set (match_operand:QI 0 "register_operand" "")
13249         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13250   ""
13251   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13252
13253 (define_expand "sle"
13254   [(set (match_operand:QI 0 "register_operand" "")
13255         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13256   ""
13257   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13258
13259 (define_expand "sleu"
13260   [(set (match_operand:QI 0 "register_operand" "")
13261         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13262   ""
13263   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13264
13265 (define_expand "sunordered"
13266   [(set (match_operand:QI 0 "register_operand" "")
13267         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13268   "TARGET_80387 || TARGET_SSE"
13269   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13270
13271 (define_expand "sordered"
13272   [(set (match_operand:QI 0 "register_operand" "")
13273         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13274   "TARGET_80387"
13275   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13276
13277 (define_expand "suneq"
13278   [(set (match_operand:QI 0 "register_operand" "")
13279         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13280   "TARGET_80387 || TARGET_SSE"
13281   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13282
13283 (define_expand "sunge"
13284   [(set (match_operand:QI 0 "register_operand" "")
13285         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13286   "TARGET_80387 || TARGET_SSE"
13287   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13288
13289 (define_expand "sungt"
13290   [(set (match_operand:QI 0 "register_operand" "")
13291         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13292   "TARGET_80387 || TARGET_SSE"
13293   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13294
13295 (define_expand "sunle"
13296   [(set (match_operand:QI 0 "register_operand" "")
13297         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13298   "TARGET_80387 || TARGET_SSE"
13299   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13300
13301 (define_expand "sunlt"
13302   [(set (match_operand:QI 0 "register_operand" "")
13303         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13304   "TARGET_80387 || TARGET_SSE"
13305   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13306
13307 (define_expand "sltgt"
13308   [(set (match_operand:QI 0 "register_operand" "")
13309         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13310   "TARGET_80387 || TARGET_SSE"
13311   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13312
13313 (define_insn "*setcc_1"
13314   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13315         (match_operator:QI 1 "ix86_comparison_operator"
13316           [(reg FLAGS_REG) (const_int 0)]))]
13317   ""
13318   "set%C1\t%0"
13319   [(set_attr "type" "setcc")
13320    (set_attr "mode" "QI")])
13321
13322 (define_insn "*setcc_2"
13323   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13324         (match_operator:QI 1 "ix86_comparison_operator"
13325           [(reg FLAGS_REG) (const_int 0)]))]
13326   ""
13327   "set%C1\t%0"
13328   [(set_attr "type" "setcc")
13329    (set_attr "mode" "QI")])
13330
13331 ;; In general it is not safe to assume too much about CCmode registers,
13332 ;; so simplify-rtx stops when it sees a second one.  Under certain
13333 ;; conditions this is safe on x86, so help combine not create
13334 ;;
13335 ;;      seta    %al
13336 ;;      testb   %al, %al
13337 ;;      sete    %al
13338
13339 (define_split
13340   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13341         (ne:QI (match_operator 1 "ix86_comparison_operator"
13342                  [(reg FLAGS_REG) (const_int 0)])
13343             (const_int 0)))]
13344   ""
13345   [(set (match_dup 0) (match_dup 1))]
13346 {
13347   PUT_MODE (operands[1], QImode);
13348 })
13349
13350 (define_split
13351   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13352         (ne:QI (match_operator 1 "ix86_comparison_operator"
13353                  [(reg FLAGS_REG) (const_int 0)])
13354             (const_int 0)))]
13355   ""
13356   [(set (match_dup 0) (match_dup 1))]
13357 {
13358   PUT_MODE (operands[1], QImode);
13359 })
13360
13361 (define_split
13362   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13363         (eq:QI (match_operator 1 "ix86_comparison_operator"
13364                  [(reg FLAGS_REG) (const_int 0)])
13365             (const_int 0)))]
13366   ""
13367   [(set (match_dup 0) (match_dup 1))]
13368 {
13369   rtx new_op1 = copy_rtx (operands[1]);
13370   operands[1] = new_op1;
13371   PUT_MODE (new_op1, QImode);
13372   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13373                                              GET_MODE (XEXP (new_op1, 0))));
13374
13375   /* Make sure that (a) the CCmode we have for the flags is strong
13376      enough for the reversed compare or (b) we have a valid FP compare.  */
13377   if (! ix86_comparison_operator (new_op1, VOIDmode))
13378     FAIL;
13379 })
13380
13381 (define_split
13382   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13383         (eq:QI (match_operator 1 "ix86_comparison_operator"
13384                  [(reg FLAGS_REG) (const_int 0)])
13385             (const_int 0)))]
13386   ""
13387   [(set (match_dup 0) (match_dup 1))]
13388 {
13389   rtx new_op1 = copy_rtx (operands[1]);
13390   operands[1] = new_op1;
13391   PUT_MODE (new_op1, QImode);
13392   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13393                                              GET_MODE (XEXP (new_op1, 0))));
13394
13395   /* Make sure that (a) the CCmode we have for the flags is strong
13396      enough for the reversed compare or (b) we have a valid FP compare.  */
13397   if (! ix86_comparison_operator (new_op1, VOIDmode))
13398     FAIL;
13399 })
13400
13401 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13402 ;; subsequent logical operations are used to imitate conditional moves.
13403 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13404 ;; it directly.
13405
13406 (define_insn "*sse_setccsf"
13407   [(set (match_operand:SF 0 "register_operand" "=x")
13408         (match_operator:SF 1 "sse_comparison_operator"
13409           [(match_operand:SF 2 "register_operand" "0")
13410            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13411   "TARGET_SSE"
13412   "cmp%D1ss\t{%3, %0|%0, %3}"
13413   [(set_attr "type" "ssecmp")
13414    (set_attr "mode" "SF")])
13415
13416 (define_insn "*sse_setccdf"
13417   [(set (match_operand:DF 0 "register_operand" "=Y")
13418         (match_operator:DF 1 "sse_comparison_operator"
13419           [(match_operand:DF 2 "register_operand" "0")
13420            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13421   "TARGET_SSE2"
13422   "cmp%D1sd\t{%3, %0|%0, %3}"
13423   [(set_attr "type" "ssecmp")
13424    (set_attr "mode" "DF")])
13425 \f
13426 ;; Basic conditional jump instructions.
13427 ;; We ignore the overflow flag for signed branch instructions.
13428
13429 ;; For all bCOND expanders, also expand the compare or test insn that
13430 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13431
13432 (define_expand "beq"
13433   [(set (pc)
13434         (if_then_else (match_dup 1)
13435                       (label_ref (match_operand 0 "" ""))
13436                       (pc)))]
13437   ""
13438   "ix86_expand_branch (EQ, operands[0]); DONE;")
13439
13440 (define_expand "bne"
13441   [(set (pc)
13442         (if_then_else (match_dup 1)
13443                       (label_ref (match_operand 0 "" ""))
13444                       (pc)))]
13445   ""
13446   "ix86_expand_branch (NE, operands[0]); DONE;")
13447
13448 (define_expand "bgt"
13449   [(set (pc)
13450         (if_then_else (match_dup 1)
13451                       (label_ref (match_operand 0 "" ""))
13452                       (pc)))]
13453   ""
13454   "ix86_expand_branch (GT, operands[0]); DONE;")
13455
13456 (define_expand "bgtu"
13457   [(set (pc)
13458         (if_then_else (match_dup 1)
13459                       (label_ref (match_operand 0 "" ""))
13460                       (pc)))]
13461   ""
13462   "ix86_expand_branch (GTU, operands[0]); DONE;")
13463
13464 (define_expand "blt"
13465   [(set (pc)
13466         (if_then_else (match_dup 1)
13467                       (label_ref (match_operand 0 "" ""))
13468                       (pc)))]
13469   ""
13470   "ix86_expand_branch (LT, operands[0]); DONE;")
13471
13472 (define_expand "bltu"
13473   [(set (pc)
13474         (if_then_else (match_dup 1)
13475                       (label_ref (match_operand 0 "" ""))
13476                       (pc)))]
13477   ""
13478   "ix86_expand_branch (LTU, operands[0]); DONE;")
13479
13480 (define_expand "bge"
13481   [(set (pc)
13482         (if_then_else (match_dup 1)
13483                       (label_ref (match_operand 0 "" ""))
13484                       (pc)))]
13485   ""
13486   "ix86_expand_branch (GE, operands[0]); DONE;")
13487
13488 (define_expand "bgeu"
13489   [(set (pc)
13490         (if_then_else (match_dup 1)
13491                       (label_ref (match_operand 0 "" ""))
13492                       (pc)))]
13493   ""
13494   "ix86_expand_branch (GEU, operands[0]); DONE;")
13495
13496 (define_expand "ble"
13497   [(set (pc)
13498         (if_then_else (match_dup 1)
13499                       (label_ref (match_operand 0 "" ""))
13500                       (pc)))]
13501   ""
13502   "ix86_expand_branch (LE, operands[0]); DONE;")
13503
13504 (define_expand "bleu"
13505   [(set (pc)
13506         (if_then_else (match_dup 1)
13507                       (label_ref (match_operand 0 "" ""))
13508                       (pc)))]
13509   ""
13510   "ix86_expand_branch (LEU, operands[0]); DONE;")
13511
13512 (define_expand "bunordered"
13513   [(set (pc)
13514         (if_then_else (match_dup 1)
13515                       (label_ref (match_operand 0 "" ""))
13516                       (pc)))]
13517   "TARGET_80387 || TARGET_SSE_MATH"
13518   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13519
13520 (define_expand "bordered"
13521   [(set (pc)
13522         (if_then_else (match_dup 1)
13523                       (label_ref (match_operand 0 "" ""))
13524                       (pc)))]
13525   "TARGET_80387 || TARGET_SSE_MATH"
13526   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13527
13528 (define_expand "buneq"
13529   [(set (pc)
13530         (if_then_else (match_dup 1)
13531                       (label_ref (match_operand 0 "" ""))
13532                       (pc)))]
13533   "TARGET_80387 || TARGET_SSE_MATH"
13534   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13535
13536 (define_expand "bunge"
13537   [(set (pc)
13538         (if_then_else (match_dup 1)
13539                       (label_ref (match_operand 0 "" ""))
13540                       (pc)))]
13541   "TARGET_80387 || TARGET_SSE_MATH"
13542   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13543
13544 (define_expand "bungt"
13545   [(set (pc)
13546         (if_then_else (match_dup 1)
13547                       (label_ref (match_operand 0 "" ""))
13548                       (pc)))]
13549   "TARGET_80387 || TARGET_SSE_MATH"
13550   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13551
13552 (define_expand "bunle"
13553   [(set (pc)
13554         (if_then_else (match_dup 1)
13555                       (label_ref (match_operand 0 "" ""))
13556                       (pc)))]
13557   "TARGET_80387 || TARGET_SSE_MATH"
13558   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13559
13560 (define_expand "bunlt"
13561   [(set (pc)
13562         (if_then_else (match_dup 1)
13563                       (label_ref (match_operand 0 "" ""))
13564                       (pc)))]
13565   "TARGET_80387 || TARGET_SSE_MATH"
13566   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13567
13568 (define_expand "bltgt"
13569   [(set (pc)
13570         (if_then_else (match_dup 1)
13571                       (label_ref (match_operand 0 "" ""))
13572                       (pc)))]
13573   "TARGET_80387 || TARGET_SSE_MATH"
13574   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13575
13576 (define_insn "*jcc_1"
13577   [(set (pc)
13578         (if_then_else (match_operator 1 "ix86_comparison_operator"
13579                                       [(reg FLAGS_REG) (const_int 0)])
13580                       (label_ref (match_operand 0 "" ""))
13581                       (pc)))]
13582   ""
13583   "%+j%C1\t%l0"
13584   [(set_attr "type" "ibr")
13585    (set_attr "modrm" "0")
13586    (set (attr "length")
13587            (if_then_else (and (ge (minus (match_dup 0) (pc))
13588                                   (const_int -126))
13589                               (lt (minus (match_dup 0) (pc))
13590                                   (const_int 128)))
13591              (const_int 2)
13592              (const_int 6)))])
13593
13594 (define_insn "*jcc_2"
13595   [(set (pc)
13596         (if_then_else (match_operator 1 "ix86_comparison_operator"
13597                                       [(reg FLAGS_REG) (const_int 0)])
13598                       (pc)
13599                       (label_ref (match_operand 0 "" ""))))]
13600   ""
13601   "%+j%c1\t%l0"
13602   [(set_attr "type" "ibr")
13603    (set_attr "modrm" "0")
13604    (set (attr "length")
13605            (if_then_else (and (ge (minus (match_dup 0) (pc))
13606                                   (const_int -126))
13607                               (lt (minus (match_dup 0) (pc))
13608                                   (const_int 128)))
13609              (const_int 2)
13610              (const_int 6)))])
13611
13612 ;; In general it is not safe to assume too much about CCmode registers,
13613 ;; so simplify-rtx stops when it sees a second one.  Under certain
13614 ;; conditions this is safe on x86, so help combine not create
13615 ;;
13616 ;;      seta    %al
13617 ;;      testb   %al, %al
13618 ;;      je      Lfoo
13619
13620 (define_split
13621   [(set (pc)
13622         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13623                                       [(reg FLAGS_REG) (const_int 0)])
13624                           (const_int 0))
13625                       (label_ref (match_operand 1 "" ""))
13626                       (pc)))]
13627   ""
13628   [(set (pc)
13629         (if_then_else (match_dup 0)
13630                       (label_ref (match_dup 1))
13631                       (pc)))]
13632 {
13633   PUT_MODE (operands[0], VOIDmode);
13634 })
13635
13636 (define_split
13637   [(set (pc)
13638         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13639                                       [(reg FLAGS_REG) (const_int 0)])
13640                           (const_int 0))
13641                       (label_ref (match_operand 1 "" ""))
13642                       (pc)))]
13643   ""
13644   [(set (pc)
13645         (if_then_else (match_dup 0)
13646                       (label_ref (match_dup 1))
13647                       (pc)))]
13648 {
13649   rtx new_op0 = copy_rtx (operands[0]);
13650   operands[0] = new_op0;
13651   PUT_MODE (new_op0, VOIDmode);
13652   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13653                                              GET_MODE (XEXP (new_op0, 0))));
13654
13655   /* Make sure that (a) the CCmode we have for the flags is strong
13656      enough for the reversed compare or (b) we have a valid FP compare.  */
13657   if (! ix86_comparison_operator (new_op0, VOIDmode))
13658     FAIL;
13659 })
13660
13661 ;; Define combination compare-and-branch fp compare instructions to use
13662 ;; during early optimization.  Splitting the operation apart early makes
13663 ;; for bad code when we want to reverse the operation.
13664
13665 (define_insn "*fp_jcc_1_mixed"
13666   [(set (pc)
13667         (if_then_else (match_operator 0 "comparison_operator"
13668                         [(match_operand 1 "register_operand" "f,x")
13669                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13670           (label_ref (match_operand 3 "" ""))
13671           (pc)))
13672    (clobber (reg:CCFP FPSR_REG))
13673    (clobber (reg:CCFP FLAGS_REG))]
13674   "TARGET_MIX_SSE_I387
13675    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13676    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13677    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13678   "#")
13679
13680 (define_insn "*fp_jcc_1_sse"
13681   [(set (pc)
13682         (if_then_else (match_operator 0 "comparison_operator"
13683                         [(match_operand 1 "register_operand" "x")
13684                          (match_operand 2 "nonimmediate_operand" "xm")])
13685           (label_ref (match_operand 3 "" ""))
13686           (pc)))
13687    (clobber (reg:CCFP FPSR_REG))
13688    (clobber (reg:CCFP FLAGS_REG))]
13689   "TARGET_SSE_MATH
13690    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13691    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13692    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13693   "#")
13694
13695 (define_insn "*fp_jcc_1_387"
13696   [(set (pc)
13697         (if_then_else (match_operator 0 "comparison_operator"
13698                         [(match_operand 1 "register_operand" "f")
13699                          (match_operand 2 "register_operand" "f")])
13700           (label_ref (match_operand 3 "" ""))
13701           (pc)))
13702    (clobber (reg:CCFP FPSR_REG))
13703    (clobber (reg:CCFP FLAGS_REG))]
13704   "TARGET_CMOVE && TARGET_80387
13705    && FLOAT_MODE_P (GET_MODE (operands[1]))
13706    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13707    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13708   "#")
13709
13710 (define_insn "*fp_jcc_2_mixed"
13711   [(set (pc)
13712         (if_then_else (match_operator 0 "comparison_operator"
13713                         [(match_operand 1 "register_operand" "f,x")
13714                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13715           (pc)
13716           (label_ref (match_operand 3 "" ""))))
13717    (clobber (reg:CCFP FPSR_REG))
13718    (clobber (reg:CCFP FLAGS_REG))]
13719   "TARGET_MIX_SSE_I387
13720    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13721    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13722    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13723   "#")
13724
13725 (define_insn "*fp_jcc_2_sse"
13726   [(set (pc)
13727         (if_then_else (match_operator 0 "comparison_operator"
13728                         [(match_operand 1 "register_operand" "x")
13729                          (match_operand 2 "nonimmediate_operand" "xm")])
13730           (pc)
13731           (label_ref (match_operand 3 "" ""))))
13732    (clobber (reg:CCFP FPSR_REG))
13733    (clobber (reg:CCFP FLAGS_REG))]
13734   "TARGET_SSE_MATH
13735    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13736    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13737    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13738   "#")
13739
13740 (define_insn "*fp_jcc_2_387"
13741   [(set (pc)
13742         (if_then_else (match_operator 0 "comparison_operator"
13743                         [(match_operand 1 "register_operand" "f")
13744                          (match_operand 2 "register_operand" "f")])
13745           (pc)
13746           (label_ref (match_operand 3 "" ""))))
13747    (clobber (reg:CCFP FPSR_REG))
13748    (clobber (reg:CCFP FLAGS_REG))]
13749   "TARGET_CMOVE && TARGET_80387
13750    && FLOAT_MODE_P (GET_MODE (operands[1]))
13751    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13752    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13753   "#")
13754
13755 (define_insn "*fp_jcc_3_387"
13756   [(set (pc)
13757         (if_then_else (match_operator 0 "comparison_operator"
13758                         [(match_operand 1 "register_operand" "f")
13759                          (match_operand 2 "nonimmediate_operand" "fm")])
13760           (label_ref (match_operand 3 "" ""))
13761           (pc)))
13762    (clobber (reg:CCFP FPSR_REG))
13763    (clobber (reg:CCFP FLAGS_REG))
13764    (clobber (match_scratch:HI 4 "=a"))]
13765   "TARGET_80387
13766    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13767    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13768    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13769    && SELECT_CC_MODE (GET_CODE (operands[0]),
13770                       operands[1], operands[2]) == CCFPmode
13771    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13772   "#")
13773
13774 (define_insn "*fp_jcc_4_387"
13775   [(set (pc)
13776         (if_then_else (match_operator 0 "comparison_operator"
13777                         [(match_operand 1 "register_operand" "f")
13778                          (match_operand 2 "nonimmediate_operand" "fm")])
13779           (pc)
13780           (label_ref (match_operand 3 "" ""))))
13781    (clobber (reg:CCFP FPSR_REG))
13782    (clobber (reg:CCFP FLAGS_REG))
13783    (clobber (match_scratch:HI 4 "=a"))]
13784   "TARGET_80387
13785    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13786    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13787    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13788    && SELECT_CC_MODE (GET_CODE (operands[0]),
13789                       operands[1], operands[2]) == CCFPmode
13790    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13791   "#")
13792
13793 (define_insn "*fp_jcc_5_387"
13794   [(set (pc)
13795         (if_then_else (match_operator 0 "comparison_operator"
13796                         [(match_operand 1 "register_operand" "f")
13797                          (match_operand 2 "register_operand" "f")])
13798           (label_ref (match_operand 3 "" ""))
13799           (pc)))
13800    (clobber (reg:CCFP FPSR_REG))
13801    (clobber (reg:CCFP FLAGS_REG))
13802    (clobber (match_scratch:HI 4 "=a"))]
13803   "TARGET_80387
13804    && FLOAT_MODE_P (GET_MODE (operands[1]))
13805    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13806    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13807   "#")
13808
13809 (define_insn "*fp_jcc_6_387"
13810   [(set (pc)
13811         (if_then_else (match_operator 0 "comparison_operator"
13812                         [(match_operand 1 "register_operand" "f")
13813                          (match_operand 2 "register_operand" "f")])
13814           (pc)
13815           (label_ref (match_operand 3 "" ""))))
13816    (clobber (reg:CCFP FPSR_REG))
13817    (clobber (reg:CCFP FLAGS_REG))
13818    (clobber (match_scratch:HI 4 "=a"))]
13819   "TARGET_80387
13820    && FLOAT_MODE_P (GET_MODE (operands[1]))
13821    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13822    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13823   "#")
13824
13825 (define_insn "*fp_jcc_7_387"
13826   [(set (pc)
13827         (if_then_else (match_operator 0 "comparison_operator"
13828                         [(match_operand 1 "register_operand" "f")
13829                          (match_operand 2 "const0_operand" "X")])
13830           (label_ref (match_operand 3 "" ""))
13831           (pc)))
13832    (clobber (reg:CCFP FPSR_REG))
13833    (clobber (reg:CCFP FLAGS_REG))
13834    (clobber (match_scratch:HI 4 "=a"))]
13835   "TARGET_80387
13836    && FLOAT_MODE_P (GET_MODE (operands[1]))
13837    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13838    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13839    && SELECT_CC_MODE (GET_CODE (operands[0]),
13840                       operands[1], operands[2]) == CCFPmode
13841    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13842   "#")
13843
13844 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13845 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13846 ;; with a precedence over other operators and is always put in the first
13847 ;; place. Swap condition and operands to match ficom instruction.
13848
13849 (define_insn "*fp_jcc_8<mode>_387"
13850   [(set (pc)
13851         (if_then_else (match_operator 0 "comparison_operator"
13852                         [(match_operator 1 "float_operator"
13853                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13854                            (match_operand 3 "register_operand" "f,f")])
13855           (label_ref (match_operand 4 "" ""))
13856           (pc)))
13857    (clobber (reg:CCFP FPSR_REG))
13858    (clobber (reg:CCFP FLAGS_REG))
13859    (clobber (match_scratch:HI 5 "=a,a"))]
13860   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13861    && FLOAT_MODE_P (GET_MODE (operands[3]))
13862    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13863    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13864    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13865    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13866   "#")
13867
13868 (define_split
13869   [(set (pc)
13870         (if_then_else (match_operator 0 "comparison_operator"
13871                         [(match_operand 1 "register_operand" "")
13872                          (match_operand 2 "nonimmediate_operand" "")])
13873           (match_operand 3 "" "")
13874           (match_operand 4 "" "")))
13875    (clobber (reg:CCFP FPSR_REG))
13876    (clobber (reg:CCFP FLAGS_REG))]
13877   "reload_completed"
13878   [(const_int 0)]
13879 {
13880   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13881                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13882   DONE;
13883 })
13884
13885 (define_split
13886   [(set (pc)
13887         (if_then_else (match_operator 0 "comparison_operator"
13888                         [(match_operand 1 "register_operand" "")
13889                          (match_operand 2 "general_operand" "")])
13890           (match_operand 3 "" "")
13891           (match_operand 4 "" "")))
13892    (clobber (reg:CCFP FPSR_REG))
13893    (clobber (reg:CCFP FLAGS_REG))
13894    (clobber (match_scratch:HI 5 "=a"))]
13895   "reload_completed"
13896   [(const_int 0)]
13897 {
13898   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13899                         operands[3], operands[4], operands[5], NULL_RTX);
13900   DONE;
13901 })
13902
13903 (define_split
13904   [(set (pc)
13905         (if_then_else (match_operator 0 "comparison_operator"
13906                         [(match_operator 1 "float_operator"
13907                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13908                            (match_operand 3 "register_operand" "")])
13909           (match_operand 4 "" "")
13910           (match_operand 5 "" "")))
13911    (clobber (reg:CCFP FPSR_REG))
13912    (clobber (reg:CCFP FLAGS_REG))
13913    (clobber (match_scratch:HI 6 "=a"))]
13914   "reload_completed"
13915   [(const_int 0)]
13916 {
13917   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13918   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13919                         operands[3], operands[7],
13920                         operands[4], operands[5], operands[6], NULL_RTX);
13921   DONE;
13922 })
13923
13924 ;; %%% Kill this when reload knows how to do it.
13925 (define_split
13926   [(set (pc)
13927         (if_then_else (match_operator 0 "comparison_operator"
13928                         [(match_operator 1 "float_operator"
13929                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13930                            (match_operand 3 "register_operand" "")])
13931           (match_operand 4 "" "")
13932           (match_operand 5 "" "")))
13933    (clobber (reg:CCFP FPSR_REG))
13934    (clobber (reg:CCFP FLAGS_REG))
13935    (clobber (match_scratch:HI 6 "=a"))]
13936   "reload_completed"
13937   [(const_int 0)]
13938 {
13939   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13940   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13941   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13942                         operands[3], operands[7],
13943                         operands[4], operands[5], operands[6], operands[2]);
13944   DONE;
13945 })
13946 \f
13947 ;; Unconditional and other jump instructions
13948
13949 (define_insn "jump"
13950   [(set (pc)
13951         (label_ref (match_operand 0 "" "")))]
13952   ""
13953   "jmp\t%l0"
13954   [(set_attr "type" "ibr")
13955    (set (attr "length")
13956            (if_then_else (and (ge (minus (match_dup 0) (pc))
13957                                   (const_int -126))
13958                               (lt (minus (match_dup 0) (pc))
13959                                   (const_int 128)))
13960              (const_int 2)
13961              (const_int 5)))
13962    (set_attr "modrm" "0")])
13963
13964 (define_expand "indirect_jump"
13965   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13966   ""
13967   "")
13968
13969 (define_insn "*indirect_jump"
13970   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13971   "!TARGET_64BIT"
13972   "jmp\t%A0"
13973   [(set_attr "type" "ibr")
13974    (set_attr "length_immediate" "0")])
13975
13976 (define_insn "*indirect_jump_rtx64"
13977   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13978   "TARGET_64BIT"
13979   "jmp\t%A0"
13980   [(set_attr "type" "ibr")
13981    (set_attr "length_immediate" "0")])
13982
13983 (define_expand "tablejump"
13984   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13985               (use (label_ref (match_operand 1 "" "")))])]
13986   ""
13987 {
13988   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13989      relative.  Convert the relative address to an absolute address.  */
13990   if (flag_pic)
13991     {
13992       rtx op0, op1;
13993       enum rtx_code code;
13994
13995       if (TARGET_64BIT)
13996         {
13997           code = PLUS;
13998           op0 = operands[0];
13999           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14000         }
14001       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14002         {
14003           code = PLUS;
14004           op0 = operands[0];
14005           op1 = pic_offset_table_rtx;
14006         }
14007       else
14008         {
14009           code = MINUS;
14010           op0 = pic_offset_table_rtx;
14011           op1 = operands[0];
14012         }
14013
14014       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14015                                          OPTAB_DIRECT);
14016     }
14017 })
14018
14019 (define_insn "*tablejump_1"
14020   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14021    (use (label_ref (match_operand 1 "" "")))]
14022   "!TARGET_64BIT"
14023   "jmp\t%A0"
14024   [(set_attr "type" "ibr")
14025    (set_attr "length_immediate" "0")])
14026
14027 (define_insn "*tablejump_1_rtx64"
14028   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14029    (use (label_ref (match_operand 1 "" "")))]
14030   "TARGET_64BIT"
14031   "jmp\t%A0"
14032   [(set_attr "type" "ibr")
14033    (set_attr "length_immediate" "0")])
14034 \f
14035 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14036
14037 (define_peephole2
14038   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14039    (set (match_operand:QI 1 "register_operand" "")
14040         (match_operator:QI 2 "ix86_comparison_operator"
14041           [(reg FLAGS_REG) (const_int 0)]))
14042    (set (match_operand 3 "q_regs_operand" "")
14043         (zero_extend (match_dup 1)))]
14044   "(peep2_reg_dead_p (3, operands[1])
14045     || operands_match_p (operands[1], operands[3]))
14046    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14047   [(set (match_dup 4) (match_dup 0))
14048    (set (strict_low_part (match_dup 5))
14049         (match_dup 2))]
14050 {
14051   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14052   operands[5] = gen_lowpart (QImode, operands[3]);
14053   ix86_expand_clear (operands[3]);
14054 })
14055
14056 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14057
14058 (define_peephole2
14059   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14060    (set (match_operand:QI 1 "register_operand" "")
14061         (match_operator:QI 2 "ix86_comparison_operator"
14062           [(reg FLAGS_REG) (const_int 0)]))
14063    (parallel [(set (match_operand 3 "q_regs_operand" "")
14064                    (zero_extend (match_dup 1)))
14065               (clobber (reg:CC FLAGS_REG))])]
14066   "(peep2_reg_dead_p (3, operands[1])
14067     || operands_match_p (operands[1], operands[3]))
14068    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14069   [(set (match_dup 4) (match_dup 0))
14070    (set (strict_low_part (match_dup 5))
14071         (match_dup 2))]
14072 {
14073   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14074   operands[5] = gen_lowpart (QImode, operands[3]);
14075   ix86_expand_clear (operands[3]);
14076 })
14077 \f
14078 ;; Call instructions.
14079
14080 ;; The predicates normally associated with named expanders are not properly
14081 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14082 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14083
14084 ;; Call subroutine returning no value.
14085
14086 (define_expand "call_pop"
14087   [(parallel [(call (match_operand:QI 0 "" "")
14088                     (match_operand:SI 1 "" ""))
14089               (set (reg:SI SP_REG)
14090                    (plus:SI (reg:SI SP_REG)
14091                             (match_operand:SI 3 "" "")))])]
14092   "!TARGET_64BIT"
14093 {
14094   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14095   DONE;
14096 })
14097
14098 (define_insn "*call_pop_0"
14099   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14100          (match_operand:SI 1 "" ""))
14101    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14102                             (match_operand:SI 2 "immediate_operand" "")))]
14103   "!TARGET_64BIT"
14104 {
14105   if (SIBLING_CALL_P (insn))
14106     return "jmp\t%P0";
14107   else
14108     return "call\t%P0";
14109 }
14110   [(set_attr "type" "call")])
14111
14112 (define_insn "*call_pop_1"
14113   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14114          (match_operand:SI 1 "" ""))
14115    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14116                             (match_operand:SI 2 "immediate_operand" "i")))]
14117   "!TARGET_64BIT"
14118 {
14119   if (constant_call_address_operand (operands[0], Pmode))
14120     {
14121       if (SIBLING_CALL_P (insn))
14122         return "jmp\t%P0";
14123       else
14124         return "call\t%P0";
14125     }
14126   if (SIBLING_CALL_P (insn))
14127     return "jmp\t%A0";
14128   else
14129     return "call\t%A0";
14130 }
14131   [(set_attr "type" "call")])
14132
14133 (define_expand "call"
14134   [(call (match_operand:QI 0 "" "")
14135          (match_operand 1 "" ""))
14136    (use (match_operand 2 "" ""))]
14137   ""
14138 {
14139   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14140   DONE;
14141 })
14142
14143 (define_expand "sibcall"
14144   [(call (match_operand:QI 0 "" "")
14145          (match_operand 1 "" ""))
14146    (use (match_operand 2 "" ""))]
14147   ""
14148 {
14149   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14150   DONE;
14151 })
14152
14153 (define_insn "*call_0"
14154   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14155          (match_operand 1 "" ""))]
14156   ""
14157 {
14158   if (SIBLING_CALL_P (insn))
14159     return "jmp\t%P0";
14160   else
14161     return "call\t%P0";
14162 }
14163   [(set_attr "type" "call")])
14164
14165 (define_insn "*call_1"
14166   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14167          (match_operand 1 "" ""))]
14168   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14169 {
14170   if (constant_call_address_operand (operands[0], Pmode))
14171     return "call\t%P0";
14172   return "call\t%A0";
14173 }
14174   [(set_attr "type" "call")])
14175
14176 (define_insn "*sibcall_1"
14177   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14178          (match_operand 1 "" ""))]
14179   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14180 {
14181   if (constant_call_address_operand (operands[0], Pmode))
14182     return "jmp\t%P0";
14183   return "jmp\t%A0";
14184 }
14185   [(set_attr "type" "call")])
14186
14187 (define_insn "*call_1_rex64"
14188   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14189          (match_operand 1 "" ""))]
14190   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14191 {
14192   if (constant_call_address_operand (operands[0], Pmode))
14193     return "call\t%P0";
14194   return "call\t%A0";
14195 }
14196   [(set_attr "type" "call")])
14197
14198 (define_insn "*sibcall_1_rex64"
14199   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14200          (match_operand 1 "" ""))]
14201   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14202   "jmp\t%P0"
14203   [(set_attr "type" "call")])
14204
14205 (define_insn "*sibcall_1_rex64_v"
14206   [(call (mem:QI (reg:DI R11_REG))
14207          (match_operand 0 "" ""))]
14208   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14209   "jmp\t*%%r11"
14210   [(set_attr "type" "call")])
14211
14212
14213 ;; Call subroutine, returning value in operand 0
14214
14215 (define_expand "call_value_pop"
14216   [(parallel [(set (match_operand 0 "" "")
14217                    (call (match_operand:QI 1 "" "")
14218                          (match_operand:SI 2 "" "")))
14219               (set (reg:SI SP_REG)
14220                    (plus:SI (reg:SI SP_REG)
14221                             (match_operand:SI 4 "" "")))])]
14222   "!TARGET_64BIT"
14223 {
14224   ix86_expand_call (operands[0], operands[1], operands[2],
14225                     operands[3], operands[4], 0);
14226   DONE;
14227 })
14228
14229 (define_expand "call_value"
14230   [(set (match_operand 0 "" "")
14231         (call (match_operand:QI 1 "" "")
14232               (match_operand:SI 2 "" "")))
14233    (use (match_operand:SI 3 "" ""))]
14234   ;; Operand 2 not used on the i386.
14235   ""
14236 {
14237   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14238   DONE;
14239 })
14240
14241 (define_expand "sibcall_value"
14242   [(set (match_operand 0 "" "")
14243         (call (match_operand:QI 1 "" "")
14244               (match_operand:SI 2 "" "")))
14245    (use (match_operand:SI 3 "" ""))]
14246   ;; Operand 2 not used on the i386.
14247   ""
14248 {
14249   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14250   DONE;
14251 })
14252
14253 ;; Call subroutine returning any type.
14254
14255 (define_expand "untyped_call"
14256   [(parallel [(call (match_operand 0 "" "")
14257                     (const_int 0))
14258               (match_operand 1 "" "")
14259               (match_operand 2 "" "")])]
14260   ""
14261 {
14262   int i;
14263
14264   /* In order to give reg-stack an easier job in validating two
14265      coprocessor registers as containing a possible return value,
14266      simply pretend the untyped call returns a complex long double
14267      value.  */
14268
14269   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14270                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14271                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14272                     NULL, 0);
14273
14274   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14275     {
14276       rtx set = XVECEXP (operands[2], 0, i);
14277       emit_move_insn (SET_DEST (set), SET_SRC (set));
14278     }
14279
14280   /* The optimizer does not know that the call sets the function value
14281      registers we stored in the result block.  We avoid problems by
14282      claiming that all hard registers are used and clobbered at this
14283      point.  */
14284   emit_insn (gen_blockage (const0_rtx));
14285
14286   DONE;
14287 })
14288 \f
14289 ;; Prologue and epilogue instructions
14290
14291 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14292 ;; all of memory.  This blocks insns from being moved across this point.
14293
14294 (define_insn "blockage"
14295   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14296   ""
14297   ""
14298   [(set_attr "length" "0")])
14299
14300 ;; Insn emitted into the body of a function to return from a function.
14301 ;; This is only done if the function's epilogue is known to be simple.
14302 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14303
14304 (define_expand "return"
14305   [(return)]
14306   "ix86_can_use_return_insn_p ()"
14307 {
14308   if (current_function_pops_args)
14309     {
14310       rtx popc = GEN_INT (current_function_pops_args);
14311       emit_jump_insn (gen_return_pop_internal (popc));
14312       DONE;
14313     }
14314 })
14315
14316 (define_insn "return_internal"
14317   [(return)]
14318   "reload_completed"
14319   "ret"
14320   [(set_attr "length" "1")
14321    (set_attr "length_immediate" "0")
14322    (set_attr "modrm" "0")])
14323
14324 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14325 ;; instruction Athlon and K8 have.
14326
14327 (define_insn "return_internal_long"
14328   [(return)
14329    (unspec [(const_int 0)] UNSPEC_REP)]
14330   "reload_completed"
14331   "rep {;} ret"
14332   [(set_attr "length" "1")
14333    (set_attr "length_immediate" "0")
14334    (set_attr "prefix_rep" "1")
14335    (set_attr "modrm" "0")])
14336
14337 (define_insn "return_pop_internal"
14338   [(return)
14339    (use (match_operand:SI 0 "const_int_operand" ""))]
14340   "reload_completed"
14341   "ret\t%0"
14342   [(set_attr "length" "3")
14343    (set_attr "length_immediate" "2")
14344    (set_attr "modrm" "0")])
14345
14346 (define_insn "return_indirect_internal"
14347   [(return)
14348    (use (match_operand:SI 0 "register_operand" "r"))]
14349   "reload_completed"
14350   "jmp\t%A0"
14351   [(set_attr "type" "ibr")
14352    (set_attr "length_immediate" "0")])
14353
14354 (define_insn "nop"
14355   [(const_int 0)]
14356   ""
14357   "nop"
14358   [(set_attr "length" "1")
14359    (set_attr "length_immediate" "0")
14360    (set_attr "modrm" "0")])
14361
14362 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14363 ;; branch prediction penalty for the third jump in a 16-byte
14364 ;; block on K8.
14365
14366 (define_insn "align"
14367   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14368   ""
14369 {
14370 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14371   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14372 #else
14373   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14374      The align insn is used to avoid 3 jump instructions in the row to improve
14375      branch prediction and the benefits hardly outweigh the cost of extra 8
14376      nops on the average inserted by full alignment pseudo operation.  */
14377 #endif
14378   return "";
14379 }
14380   [(set_attr "length" "16")])
14381
14382 (define_expand "prologue"
14383   [(const_int 1)]
14384   ""
14385   "ix86_expand_prologue (); DONE;")
14386
14387 (define_insn "set_got"
14388   [(set (match_operand:SI 0 "register_operand" "=r")
14389         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14390    (clobber (reg:CC FLAGS_REG))]
14391   "!TARGET_64BIT"
14392   { return output_set_got (operands[0], NULL_RTX); }
14393   [(set_attr "type" "multi")
14394    (set_attr "length" "12")])
14395
14396 (define_insn "set_got_labelled"
14397   [(set (match_operand:SI 0 "register_operand" "=r")
14398         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14399          UNSPEC_SET_GOT))
14400    (clobber (reg:CC FLAGS_REG))]
14401   "!TARGET_64BIT"
14402   { return output_set_got (operands[0], operands[1]); }
14403   [(set_attr "type" "multi")
14404    (set_attr "length" "12")])
14405
14406 (define_insn "set_got_rex64"
14407   [(set (match_operand:DI 0 "register_operand" "=r")
14408         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14409   "TARGET_64BIT"
14410   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14411   [(set_attr "type" "lea")
14412    (set_attr "length" "6")])
14413
14414 (define_expand "epilogue"
14415   [(const_int 1)]
14416   ""
14417   "ix86_expand_epilogue (1); DONE;")
14418
14419 (define_expand "sibcall_epilogue"
14420   [(const_int 1)]
14421   ""
14422   "ix86_expand_epilogue (0); DONE;")
14423
14424 (define_expand "eh_return"
14425   [(use (match_operand 0 "register_operand" ""))]
14426   ""
14427 {
14428   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14429
14430   /* Tricky bit: we write the address of the handler to which we will
14431      be returning into someone else's stack frame, one word below the
14432      stack address we wish to restore.  */
14433   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14434   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14435   tmp = gen_rtx_MEM (Pmode, tmp);
14436   emit_move_insn (tmp, ra);
14437
14438   if (Pmode == SImode)
14439     emit_jump_insn (gen_eh_return_si (sa));
14440   else
14441     emit_jump_insn (gen_eh_return_di (sa));
14442   emit_barrier ();
14443   DONE;
14444 })
14445
14446 (define_insn_and_split "eh_return_si"
14447   [(set (pc)
14448         (unspec [(match_operand:SI 0 "register_operand" "c")]
14449                  UNSPEC_EH_RETURN))]
14450   "!TARGET_64BIT"
14451   "#"
14452   "reload_completed"
14453   [(const_int 1)]
14454   "ix86_expand_epilogue (2); DONE;")
14455
14456 (define_insn_and_split "eh_return_di"
14457   [(set (pc)
14458         (unspec [(match_operand:DI 0 "register_operand" "c")]
14459                  UNSPEC_EH_RETURN))]
14460   "TARGET_64BIT"
14461   "#"
14462   "reload_completed"
14463   [(const_int 1)]
14464   "ix86_expand_epilogue (2); DONE;")
14465
14466 (define_insn "leave"
14467   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14468    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14469    (clobber (mem:BLK (scratch)))]
14470   "!TARGET_64BIT"
14471   "leave"
14472   [(set_attr "type" "leave")])
14473
14474 (define_insn "leave_rex64"
14475   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14476    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14477    (clobber (mem:BLK (scratch)))]
14478   "TARGET_64BIT"
14479   "leave"
14480   [(set_attr "type" "leave")])
14481 \f
14482 (define_expand "ffssi2"
14483   [(parallel
14484      [(set (match_operand:SI 0 "register_operand" "")
14485            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14486       (clobber (match_scratch:SI 2 ""))
14487       (clobber (reg:CC FLAGS_REG))])]
14488   ""
14489   "")
14490
14491 (define_insn_and_split "*ffs_cmove"
14492   [(set (match_operand:SI 0 "register_operand" "=r")
14493         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14494    (clobber (match_scratch:SI 2 "=&r"))
14495    (clobber (reg:CC FLAGS_REG))]
14496   "TARGET_CMOVE"
14497   "#"
14498   "&& reload_completed"
14499   [(set (match_dup 2) (const_int -1))
14500    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14501               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14502    (set (match_dup 0) (if_then_else:SI
14503                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14504                         (match_dup 2)
14505                         (match_dup 0)))
14506    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14507               (clobber (reg:CC FLAGS_REG))])]
14508   "")
14509
14510 (define_insn_and_split "*ffs_no_cmove"
14511   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14512         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14513    (clobber (match_scratch:SI 2 "=&q"))
14514    (clobber (reg:CC FLAGS_REG))]
14515   ""
14516   "#"
14517   "reload_completed"
14518   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14519               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14520    (set (strict_low_part (match_dup 3))
14521         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14522    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14523               (clobber (reg:CC FLAGS_REG))])
14524    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14525               (clobber (reg:CC FLAGS_REG))])
14526    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14527               (clobber (reg:CC FLAGS_REG))])]
14528 {
14529   operands[3] = gen_lowpart (QImode, operands[2]);
14530   ix86_expand_clear (operands[2]);
14531 })
14532
14533 (define_insn "*ffssi_1"
14534   [(set (reg:CCZ FLAGS_REG)
14535         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14536                      (const_int 0)))
14537    (set (match_operand:SI 0 "register_operand" "=r")
14538         (ctz:SI (match_dup 1)))]
14539   ""
14540   "bsf{l}\t{%1, %0|%0, %1}"
14541   [(set_attr "prefix_0f" "1")])
14542
14543 (define_expand "ffsdi2"
14544   [(parallel
14545      [(set (match_operand:DI 0 "register_operand" "")
14546            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14547       (clobber (match_scratch:DI 2 ""))
14548       (clobber (reg:CC FLAGS_REG))])]
14549   "TARGET_64BIT && TARGET_CMOVE"
14550   "")
14551
14552 (define_insn_and_split "*ffs_rex64"
14553   [(set (match_operand:DI 0 "register_operand" "=r")
14554         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14555    (clobber (match_scratch:DI 2 "=&r"))
14556    (clobber (reg:CC FLAGS_REG))]
14557   "TARGET_64BIT && TARGET_CMOVE"
14558   "#"
14559   "&& reload_completed"
14560   [(set (match_dup 2) (const_int -1))
14561    (parallel [(set (reg:CCZ FLAGS_REG)
14562                    (compare:CCZ (match_dup 1) (const_int 0)))
14563               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14564    (set (match_dup 0) (if_then_else:DI
14565                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14566                         (match_dup 2)
14567                         (match_dup 0)))
14568    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14569               (clobber (reg:CC FLAGS_REG))])]
14570   "")
14571
14572 (define_insn "*ffsdi_1"
14573   [(set (reg:CCZ FLAGS_REG)
14574         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14575                      (const_int 0)))
14576    (set (match_operand:DI 0 "register_operand" "=r")
14577         (ctz:DI (match_dup 1)))]
14578   "TARGET_64BIT"
14579   "bsf{q}\t{%1, %0|%0, %1}"
14580   [(set_attr "prefix_0f" "1")])
14581
14582 (define_insn "ctzsi2"
14583   [(set (match_operand:SI 0 "register_operand" "=r")
14584         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14585    (clobber (reg:CC FLAGS_REG))]
14586   ""
14587   "bsf{l}\t{%1, %0|%0, %1}"
14588   [(set_attr "prefix_0f" "1")])
14589
14590 (define_insn "ctzdi2"
14591   [(set (match_operand:DI 0 "register_operand" "=r")
14592         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14593    (clobber (reg:CC FLAGS_REG))]
14594   "TARGET_64BIT"
14595   "bsf{q}\t{%1, %0|%0, %1}"
14596   [(set_attr "prefix_0f" "1")])
14597
14598 (define_expand "clzsi2"
14599   [(parallel
14600      [(set (match_operand:SI 0 "register_operand" "")
14601            (minus:SI (const_int 31)
14602                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14603       (clobber (reg:CC FLAGS_REG))])
14604    (parallel
14605      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14606       (clobber (reg:CC FLAGS_REG))])]
14607   ""
14608   "")
14609
14610 (define_insn "*bsr"
14611   [(set (match_operand:SI 0 "register_operand" "=r")
14612         (minus:SI (const_int 31)
14613                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14614    (clobber (reg:CC FLAGS_REG))]
14615   ""
14616   "bsr{l}\t{%1, %0|%0, %1}"
14617   [(set_attr "prefix_0f" "1")])
14618
14619 (define_insn "bswapsi2"
14620   [(set (match_operand:SI 0 "register_operand" "=r")
14621         (bswap:SI (match_operand:SI 1 "register_operand" "0")))
14622    (clobber (reg:CC FLAGS_REG))]
14623   "TARGET_BSWAP"
14624   "bswap\t%k0"
14625   [(set_attr "prefix_0f" "1")
14626    (set_attr "length" "2")])
14627
14628 (define_insn "bswapdi2"
14629   [(set (match_operand:DI 0 "register_operand" "=r")
14630         (bswap:DI (match_operand:DI 1 "register_operand" "0")))
14631    (clobber (reg:CC FLAGS_REG))]
14632   "TARGET_64BIT && TARGET_BSWAP"
14633   "bswap\t%0"
14634   [(set_attr "prefix_0f" "1")
14635    (set_attr "length" "3")])
14636
14637 (define_expand "clzdi2"
14638   [(parallel
14639      [(set (match_operand:DI 0 "register_operand" "")
14640            (minus:DI (const_int 63)
14641                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14642       (clobber (reg:CC FLAGS_REG))])
14643    (parallel
14644      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14645       (clobber (reg:CC FLAGS_REG))])]
14646   "TARGET_64BIT"
14647   "")
14648
14649 (define_insn "*bsr_rex64"
14650   [(set (match_operand:DI 0 "register_operand" "=r")
14651         (minus:DI (const_int 63)
14652                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14653    (clobber (reg:CC FLAGS_REG))]
14654   "TARGET_64BIT"
14655   "bsr{q}\t{%1, %0|%0, %1}"
14656   [(set_attr "prefix_0f" "1")])
14657 \f
14658 ;; Thread-local storage patterns for ELF.
14659 ;;
14660 ;; Note that these code sequences must appear exactly as shown
14661 ;; in order to allow linker relaxation.
14662
14663 (define_insn "*tls_global_dynamic_32_gnu"
14664   [(set (match_operand:SI 0 "register_operand" "=a")
14665         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14666                     (match_operand:SI 2 "tls_symbolic_operand" "")
14667                     (match_operand:SI 3 "call_insn_operand" "")]
14668                     UNSPEC_TLS_GD))
14669    (clobber (match_scratch:SI 4 "=d"))
14670    (clobber (match_scratch:SI 5 "=c"))
14671    (clobber (reg:CC FLAGS_REG))]
14672   "!TARGET_64BIT && TARGET_GNU_TLS"
14673   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14674   [(set_attr "type" "multi")
14675    (set_attr "length" "12")])
14676
14677 (define_insn "*tls_global_dynamic_32_sun"
14678   [(set (match_operand:SI 0 "register_operand" "=a")
14679         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14680                     (match_operand:SI 2 "tls_symbolic_operand" "")
14681                     (match_operand:SI 3 "call_insn_operand" "")]
14682                     UNSPEC_TLS_GD))
14683    (clobber (match_scratch:SI 4 "=d"))
14684    (clobber (match_scratch:SI 5 "=c"))
14685    (clobber (reg:CC FLAGS_REG))]
14686   "!TARGET_64BIT && TARGET_SUN_TLS"
14687   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14688         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14689   [(set_attr "type" "multi")
14690    (set_attr "length" "14")])
14691
14692 (define_expand "tls_global_dynamic_32"
14693   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14694                    (unspec:SI
14695                     [(match_dup 2)
14696                      (match_operand:SI 1 "tls_symbolic_operand" "")
14697                      (match_dup 3)]
14698                     UNSPEC_TLS_GD))
14699               (clobber (match_scratch:SI 4 ""))
14700               (clobber (match_scratch:SI 5 ""))
14701               (clobber (reg:CC FLAGS_REG))])]
14702   ""
14703 {
14704   if (flag_pic)
14705     operands[2] = pic_offset_table_rtx;
14706   else
14707     {
14708       operands[2] = gen_reg_rtx (Pmode);
14709       emit_insn (gen_set_got (operands[2]));
14710     }
14711   if (TARGET_GNU2_TLS)
14712     {
14713        emit_insn (gen_tls_dynamic_gnu2_32
14714                   (operands[0], operands[1], operands[2]));
14715        DONE;
14716     }
14717   operands[3] = ix86_tls_get_addr ();
14718 })
14719
14720 (define_insn "*tls_global_dynamic_64"
14721   [(set (match_operand:DI 0 "register_operand" "=a")
14722         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14723                  (match_operand:DI 3 "" "")))
14724    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14725               UNSPEC_TLS_GD)]
14726   "TARGET_64BIT"
14727   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14728   [(set_attr "type" "multi")
14729    (set_attr "length" "16")])
14730
14731 (define_expand "tls_global_dynamic_64"
14732   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14733                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14734               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14735                          UNSPEC_TLS_GD)])]
14736   ""
14737 {
14738   if (TARGET_GNU2_TLS)
14739     {
14740        emit_insn (gen_tls_dynamic_gnu2_64
14741                   (operands[0], operands[1]));
14742        DONE;
14743     }
14744   operands[2] = ix86_tls_get_addr ();
14745 })
14746
14747 (define_insn "*tls_local_dynamic_base_32_gnu"
14748   [(set (match_operand:SI 0 "register_operand" "=a")
14749         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14750                     (match_operand:SI 2 "call_insn_operand" "")]
14751                    UNSPEC_TLS_LD_BASE))
14752    (clobber (match_scratch:SI 3 "=d"))
14753    (clobber (match_scratch:SI 4 "=c"))
14754    (clobber (reg:CC FLAGS_REG))]
14755   "!TARGET_64BIT && TARGET_GNU_TLS"
14756   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14757   [(set_attr "type" "multi")
14758    (set_attr "length" "11")])
14759
14760 (define_insn "*tls_local_dynamic_base_32_sun"
14761   [(set (match_operand:SI 0 "register_operand" "=a")
14762         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14763                     (match_operand:SI 2 "call_insn_operand" "")]
14764                    UNSPEC_TLS_LD_BASE))
14765    (clobber (match_scratch:SI 3 "=d"))
14766    (clobber (match_scratch:SI 4 "=c"))
14767    (clobber (reg:CC FLAGS_REG))]
14768   "!TARGET_64BIT && TARGET_SUN_TLS"
14769   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14770         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14771   [(set_attr "type" "multi")
14772    (set_attr "length" "13")])
14773
14774 (define_expand "tls_local_dynamic_base_32"
14775   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14776                    (unspec:SI [(match_dup 1) (match_dup 2)]
14777                               UNSPEC_TLS_LD_BASE))
14778               (clobber (match_scratch:SI 3 ""))
14779               (clobber (match_scratch:SI 4 ""))
14780               (clobber (reg:CC FLAGS_REG))])]
14781   ""
14782 {
14783   if (flag_pic)
14784     operands[1] = pic_offset_table_rtx;
14785   else
14786     {
14787       operands[1] = gen_reg_rtx (Pmode);
14788       emit_insn (gen_set_got (operands[1]));
14789     }
14790   if (TARGET_GNU2_TLS)
14791     {
14792        emit_insn (gen_tls_dynamic_gnu2_32
14793                   (operands[0], ix86_tls_module_base (), operands[1]));
14794        DONE;
14795     }
14796   operands[2] = ix86_tls_get_addr ();
14797 })
14798
14799 (define_insn "*tls_local_dynamic_base_64"
14800   [(set (match_operand:DI 0 "register_operand" "=a")
14801         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14802                  (match_operand:DI 2 "" "")))
14803    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14804   "TARGET_64BIT"
14805   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14806   [(set_attr "type" "multi")
14807    (set_attr "length" "12")])
14808
14809 (define_expand "tls_local_dynamic_base_64"
14810   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14811                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14812               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14813   ""
14814 {
14815   if (TARGET_GNU2_TLS)
14816     {
14817        emit_insn (gen_tls_dynamic_gnu2_64
14818                   (operands[0], ix86_tls_module_base ()));
14819        DONE;
14820     }
14821   operands[1] = ix86_tls_get_addr ();
14822 })
14823
14824 ;; Local dynamic of a single variable is a lose.  Show combine how
14825 ;; to convert that back to global dynamic.
14826
14827 (define_insn_and_split "*tls_local_dynamic_32_once"
14828   [(set (match_operand:SI 0 "register_operand" "=a")
14829         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14830                              (match_operand:SI 2 "call_insn_operand" "")]
14831                             UNSPEC_TLS_LD_BASE)
14832                  (const:SI (unspec:SI
14833                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14834                             UNSPEC_DTPOFF))))
14835    (clobber (match_scratch:SI 4 "=d"))
14836    (clobber (match_scratch:SI 5 "=c"))
14837    (clobber (reg:CC FLAGS_REG))]
14838   ""
14839   "#"
14840   ""
14841   [(parallel [(set (match_dup 0)
14842                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14843                               UNSPEC_TLS_GD))
14844               (clobber (match_dup 4))
14845               (clobber (match_dup 5))
14846               (clobber (reg:CC FLAGS_REG))])]
14847   "")
14848
14849 ;; Load and add the thread base pointer from %gs:0.
14850
14851 (define_insn "*load_tp_si"
14852   [(set (match_operand:SI 0 "register_operand" "=r")
14853         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14854   "!TARGET_64BIT"
14855   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14856   [(set_attr "type" "imov")
14857    (set_attr "modrm" "0")
14858    (set_attr "length" "7")
14859    (set_attr "memory" "load")
14860    (set_attr "imm_disp" "false")])
14861
14862 (define_insn "*add_tp_si"
14863   [(set (match_operand:SI 0 "register_operand" "=r")
14864         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14865                  (match_operand:SI 1 "register_operand" "0")))
14866    (clobber (reg:CC FLAGS_REG))]
14867   "!TARGET_64BIT"
14868   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14869   [(set_attr "type" "alu")
14870    (set_attr "modrm" "0")
14871    (set_attr "length" "7")
14872    (set_attr "memory" "load")
14873    (set_attr "imm_disp" "false")])
14874
14875 (define_insn "*load_tp_di"
14876   [(set (match_operand:DI 0 "register_operand" "=r")
14877         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14878   "TARGET_64BIT"
14879   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14880   [(set_attr "type" "imov")
14881    (set_attr "modrm" "0")
14882    (set_attr "length" "7")
14883    (set_attr "memory" "load")
14884    (set_attr "imm_disp" "false")])
14885
14886 (define_insn "*add_tp_di"
14887   [(set (match_operand:DI 0 "register_operand" "=r")
14888         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14889                  (match_operand:DI 1 "register_operand" "0")))
14890    (clobber (reg:CC FLAGS_REG))]
14891   "TARGET_64BIT"
14892   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14893   [(set_attr "type" "alu")
14894    (set_attr "modrm" "0")
14895    (set_attr "length" "7")
14896    (set_attr "memory" "load")
14897    (set_attr "imm_disp" "false")])
14898
14899 ;; GNU2 TLS patterns can be split.
14900
14901 (define_expand "tls_dynamic_gnu2_32"
14902   [(set (match_dup 3)
14903         (plus:SI (match_operand:SI 2 "register_operand" "")
14904                  (const:SI
14905                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14906                              UNSPEC_TLSDESC))))
14907    (parallel
14908     [(set (match_operand:SI 0 "register_operand" "")
14909           (unspec:SI [(match_dup 1) (match_dup 3)
14910                       (match_dup 2) (reg:SI SP_REG)]
14911                       UNSPEC_TLSDESC))
14912      (clobber (reg:CC FLAGS_REG))])]
14913   "!TARGET_64BIT && TARGET_GNU2_TLS"
14914 {
14915   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14916   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14917 })
14918
14919 (define_insn "*tls_dynamic_lea_32"
14920   [(set (match_operand:SI 0 "register_operand" "=r")
14921         (plus:SI (match_operand:SI 1 "register_operand" "b")
14922                  (const:SI
14923                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14924                               UNSPEC_TLSDESC))))]
14925   "!TARGET_64BIT && TARGET_GNU2_TLS"
14926   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14927   [(set_attr "type" "lea")
14928    (set_attr "mode" "SI")
14929    (set_attr "length" "6")
14930    (set_attr "length_address" "4")])
14931
14932 (define_insn "*tls_dynamic_call_32"
14933   [(set (match_operand:SI 0 "register_operand" "=a")
14934         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14935                     (match_operand:SI 2 "register_operand" "0")
14936                     ;; we have to make sure %ebx still points to the GOT
14937                     (match_operand:SI 3 "register_operand" "b")
14938                     (reg:SI SP_REG)]
14939                    UNSPEC_TLSDESC))
14940    (clobber (reg:CC FLAGS_REG))]
14941   "!TARGET_64BIT && TARGET_GNU2_TLS"
14942   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14943   [(set_attr "type" "call")
14944    (set_attr "length" "2")
14945    (set_attr "length_address" "0")])
14946
14947 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14948   [(set (match_operand:SI 0 "register_operand" "=&a")
14949         (plus:SI
14950          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14951                      (match_operand:SI 4 "" "")
14952                      (match_operand:SI 2 "register_operand" "b")
14953                      (reg:SI SP_REG)]
14954                     UNSPEC_TLSDESC)
14955          (const:SI (unspec:SI
14956                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
14957                     UNSPEC_DTPOFF))))
14958    (clobber (reg:CC FLAGS_REG))]
14959   "!TARGET_64BIT && TARGET_GNU2_TLS"
14960   "#"
14961   ""
14962   [(set (match_dup 0) (match_dup 5))]
14963 {
14964   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14965   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14966 })
14967
14968 (define_expand "tls_dynamic_gnu2_64"
14969   [(set (match_dup 2)
14970         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14971                    UNSPEC_TLSDESC))
14972    (parallel
14973     [(set (match_operand:DI 0 "register_operand" "")
14974           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14975                      UNSPEC_TLSDESC))
14976      (clobber (reg:CC FLAGS_REG))])]
14977   "TARGET_64BIT && TARGET_GNU2_TLS"
14978 {
14979   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14980   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14981 })
14982
14983 (define_insn "*tls_dynamic_lea_64"
14984   [(set (match_operand:DI 0 "register_operand" "=r")
14985         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14986                    UNSPEC_TLSDESC))]
14987   "TARGET_64BIT && TARGET_GNU2_TLS"
14988   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14989   [(set_attr "type" "lea")
14990    (set_attr "mode" "DI")
14991    (set_attr "length" "7")
14992    (set_attr "length_address" "4")])
14993
14994 (define_insn "*tls_dynamic_call_64"
14995   [(set (match_operand:DI 0 "register_operand" "=a")
14996         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14997                     (match_operand:DI 2 "register_operand" "0")
14998                     (reg:DI SP_REG)]
14999                    UNSPEC_TLSDESC))
15000    (clobber (reg:CC FLAGS_REG))]
15001   "TARGET_64BIT && TARGET_GNU2_TLS"
15002   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15003   [(set_attr "type" "call")
15004    (set_attr "length" "2")
15005    (set_attr "length_address" "0")])
15006
15007 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15008   [(set (match_operand:DI 0 "register_operand" "=&a")
15009         (plus:DI
15010          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15011                      (match_operand:DI 3 "" "")
15012                      (reg:DI SP_REG)]
15013                     UNSPEC_TLSDESC)
15014          (const:DI (unspec:DI
15015                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15016                     UNSPEC_DTPOFF))))
15017    (clobber (reg:CC FLAGS_REG))]
15018   "TARGET_64BIT && TARGET_GNU2_TLS"
15019   "#"
15020   ""
15021   [(set (match_dup 0) (match_dup 4))]
15022 {
15023   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15024   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15025 })
15026
15027 ;;
15028 \f
15029 ;; These patterns match the binary 387 instructions for addM3, subM3,
15030 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15031 ;; SFmode.  The first is the normal insn, the second the same insn but
15032 ;; with one operand a conversion, and the third the same insn but with
15033 ;; the other operand a conversion.  The conversion may be SFmode or
15034 ;; SImode if the target mode DFmode, but only SImode if the target mode
15035 ;; is SFmode.
15036
15037 ;; Gcc is slightly more smart about handling normal two address instructions
15038 ;; so use special patterns for add and mull.
15039
15040 (define_insn "*fop_sf_comm_mixed"
15041   [(set (match_operand:SF 0 "register_operand" "=f,x")
15042         (match_operator:SF 3 "binary_fp_operator"
15043                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15044                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15045   "TARGET_MIX_SSE_I387
15046    && COMMUTATIVE_ARITH_P (operands[3])
15047    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15048   "* return output_387_binary_op (insn, operands);"
15049   [(set (attr "type")
15050         (if_then_else (eq_attr "alternative" "1")
15051            (if_then_else (match_operand:SF 3 "mult_operator" "")
15052               (const_string "ssemul")
15053               (const_string "sseadd"))
15054            (if_then_else (match_operand:SF 3 "mult_operator" "")
15055               (const_string "fmul")
15056               (const_string "fop"))))
15057    (set_attr "mode" "SF")])
15058
15059 (define_insn "*fop_sf_comm_sse"
15060   [(set (match_operand:SF 0 "register_operand" "=x")
15061         (match_operator:SF 3 "binary_fp_operator"
15062                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15063                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15064   "TARGET_SSE_MATH
15065    && COMMUTATIVE_ARITH_P (operands[3])
15066    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15067   "* return output_387_binary_op (insn, operands);"
15068   [(set (attr "type")
15069         (if_then_else (match_operand:SF 3 "mult_operator" "")
15070            (const_string "ssemul")
15071            (const_string "sseadd")))
15072    (set_attr "mode" "SF")])
15073
15074 (define_insn "*fop_sf_comm_i387"
15075   [(set (match_operand:SF 0 "register_operand" "=f")
15076         (match_operator:SF 3 "binary_fp_operator"
15077                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15078                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15079   "TARGET_80387
15080    && COMMUTATIVE_ARITH_P (operands[3])
15081    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15082   "* return output_387_binary_op (insn, operands);"
15083   [(set (attr "type")
15084         (if_then_else (match_operand:SF 3 "mult_operator" "")
15085            (const_string "fmul")
15086            (const_string "fop")))
15087    (set_attr "mode" "SF")])
15088
15089 (define_insn "*fop_sf_1_mixed"
15090   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15091         (match_operator:SF 3 "binary_fp_operator"
15092                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15093                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15094   "TARGET_MIX_SSE_I387
15095    && !COMMUTATIVE_ARITH_P (operands[3])
15096    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15097   "* return output_387_binary_op (insn, operands);"
15098   [(set (attr "type")
15099         (cond [(and (eq_attr "alternative" "2")
15100                     (match_operand:SF 3 "mult_operator" ""))
15101                  (const_string "ssemul")
15102                (and (eq_attr "alternative" "2")
15103                     (match_operand:SF 3 "div_operator" ""))
15104                  (const_string "ssediv")
15105                (eq_attr "alternative" "2")
15106                  (const_string "sseadd")
15107                (match_operand:SF 3 "mult_operator" "")
15108                  (const_string "fmul")
15109                (match_operand:SF 3 "div_operator" "")
15110                  (const_string "fdiv")
15111               ]
15112               (const_string "fop")))
15113    (set_attr "mode" "SF")])
15114
15115 (define_insn "*fop_sf_1_sse"
15116   [(set (match_operand:SF 0 "register_operand" "=x")
15117         (match_operator:SF 3 "binary_fp_operator"
15118                         [(match_operand:SF 1 "register_operand" "0")
15119                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15120   "TARGET_SSE_MATH
15121    && !COMMUTATIVE_ARITH_P (operands[3])"
15122   "* return output_387_binary_op (insn, operands);"
15123   [(set (attr "type")
15124         (cond [(match_operand:SF 3 "mult_operator" "")
15125                  (const_string "ssemul")
15126                (match_operand:SF 3 "div_operator" "")
15127                  (const_string "ssediv")
15128               ]
15129               (const_string "sseadd")))
15130    (set_attr "mode" "SF")])
15131
15132 ;; This pattern is not fully shadowed by the pattern above.
15133 (define_insn "*fop_sf_1_i387"
15134   [(set (match_operand:SF 0 "register_operand" "=f,f")
15135         (match_operator:SF 3 "binary_fp_operator"
15136                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15137                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15138   "TARGET_80387 && !TARGET_SSE_MATH
15139    && !COMMUTATIVE_ARITH_P (operands[3])
15140    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15141   "* return output_387_binary_op (insn, operands);"
15142   [(set (attr "type")
15143         (cond [(match_operand:SF 3 "mult_operator" "")
15144                  (const_string "fmul")
15145                (match_operand:SF 3 "div_operator" "")
15146                  (const_string "fdiv")
15147               ]
15148               (const_string "fop")))
15149    (set_attr "mode" "SF")])
15150
15151 ;; ??? Add SSE splitters for these!
15152 (define_insn "*fop_sf_2<mode>_i387"
15153   [(set (match_operand:SF 0 "register_operand" "=f,f")
15154         (match_operator:SF 3 "binary_fp_operator"
15155           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15156            (match_operand:SF 2 "register_operand" "0,0")]))]
15157   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15158   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15159   [(set (attr "type")
15160         (cond [(match_operand:SF 3 "mult_operator" "")
15161                  (const_string "fmul")
15162                (match_operand:SF 3 "div_operator" "")
15163                  (const_string "fdiv")
15164               ]
15165               (const_string "fop")))
15166    (set_attr "fp_int_src" "true")
15167    (set_attr "mode" "<MODE>")])
15168
15169 (define_insn "*fop_sf_3<mode>_i387"
15170   [(set (match_operand:SF 0 "register_operand" "=f,f")
15171         (match_operator:SF 3 "binary_fp_operator"
15172           [(match_operand:SF 1 "register_operand" "0,0")
15173            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15174   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15175   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15176   [(set (attr "type")
15177         (cond [(match_operand:SF 3 "mult_operator" "")
15178                  (const_string "fmul")
15179                (match_operand:SF 3 "div_operator" "")
15180                  (const_string "fdiv")
15181               ]
15182               (const_string "fop")))
15183    (set_attr "fp_int_src" "true")
15184    (set_attr "mode" "<MODE>")])
15185
15186 (define_insn "*fop_df_comm_mixed"
15187   [(set (match_operand:DF 0 "register_operand" "=f,Y")
15188         (match_operator:DF 3 "binary_fp_operator"
15189                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15190                          (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15191   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15192    && COMMUTATIVE_ARITH_P (operands[3])
15193    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15194   "* return output_387_binary_op (insn, operands);"
15195   [(set (attr "type")
15196         (if_then_else (eq_attr "alternative" "1")
15197            (if_then_else (match_operand:DF 3 "mult_operator" "")
15198               (const_string "ssemul")
15199               (const_string "sseadd"))
15200            (if_then_else (match_operand:DF 3 "mult_operator" "")
15201               (const_string "fmul")
15202               (const_string "fop"))))
15203    (set_attr "mode" "DF")])
15204
15205 (define_insn "*fop_df_comm_sse"
15206   [(set (match_operand:DF 0 "register_operand" "=Y")
15207         (match_operator:DF 3 "binary_fp_operator"
15208                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15209                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15210   "TARGET_SSE2 && TARGET_SSE_MATH
15211    && COMMUTATIVE_ARITH_P (operands[3])
15212    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15213   "* return output_387_binary_op (insn, operands);"
15214   [(set (attr "type")
15215         (if_then_else (match_operand:DF 3 "mult_operator" "")
15216            (const_string "ssemul")
15217            (const_string "sseadd")))
15218    (set_attr "mode" "DF")])
15219
15220 (define_insn "*fop_df_comm_i387"
15221   [(set (match_operand:DF 0 "register_operand" "=f")
15222         (match_operator:DF 3 "binary_fp_operator"
15223                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15224                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15225   "TARGET_80387
15226    && COMMUTATIVE_ARITH_P (operands[3])
15227    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15228   "* return output_387_binary_op (insn, operands);"
15229   [(set (attr "type")
15230         (if_then_else (match_operand:DF 3 "mult_operator" "")
15231            (const_string "fmul")
15232            (const_string "fop")))
15233    (set_attr "mode" "DF")])
15234
15235 (define_insn "*fop_df_1_mixed"
15236   [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15237         (match_operator:DF 3 "binary_fp_operator"
15238                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15239                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15240   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15241    && !COMMUTATIVE_ARITH_P (operands[3])
15242    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15243   "* return output_387_binary_op (insn, operands);"
15244   [(set (attr "type")
15245         (cond [(and (eq_attr "alternative" "2")
15246                     (match_operand:DF 3 "mult_operator" ""))
15247                  (const_string "ssemul")
15248                (and (eq_attr "alternative" "2")
15249                     (match_operand:DF 3 "div_operator" ""))
15250                  (const_string "ssediv")
15251                (eq_attr "alternative" "2")
15252                  (const_string "sseadd")
15253                (match_operand:DF 3 "mult_operator" "")
15254                  (const_string "fmul")
15255                (match_operand:DF 3 "div_operator" "")
15256                  (const_string "fdiv")
15257               ]
15258               (const_string "fop")))
15259    (set_attr "mode" "DF")])
15260
15261 (define_insn "*fop_df_1_sse"
15262   [(set (match_operand:DF 0 "register_operand" "=Y")
15263         (match_operator:DF 3 "binary_fp_operator"
15264                         [(match_operand:DF 1 "register_operand" "0")
15265                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15266   "TARGET_SSE2 && TARGET_SSE_MATH
15267    && !COMMUTATIVE_ARITH_P (operands[3])"
15268   "* return output_387_binary_op (insn, operands);"
15269   [(set_attr "mode" "DF")
15270    (set (attr "type")
15271         (cond [(match_operand:DF 3 "mult_operator" "")
15272                  (const_string "ssemul")
15273                (match_operand:DF 3 "div_operator" "")
15274                  (const_string "ssediv")
15275               ]
15276               (const_string "sseadd")))])
15277
15278 ;; This pattern is not fully shadowed by the pattern above.
15279 (define_insn "*fop_df_1_i387"
15280   [(set (match_operand:DF 0 "register_operand" "=f,f")
15281         (match_operator:DF 3 "binary_fp_operator"
15282                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15283                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15284   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15285    && !COMMUTATIVE_ARITH_P (operands[3])
15286    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15287   "* return output_387_binary_op (insn, operands);"
15288   [(set (attr "type")
15289         (cond [(match_operand:DF 3 "mult_operator" "")
15290                  (const_string "fmul")
15291                (match_operand:DF 3 "div_operator" "")
15292                  (const_string "fdiv")
15293               ]
15294               (const_string "fop")))
15295    (set_attr "mode" "DF")])
15296
15297 ;; ??? Add SSE splitters for these!
15298 (define_insn "*fop_df_2<mode>_i387"
15299   [(set (match_operand:DF 0 "register_operand" "=f,f")
15300         (match_operator:DF 3 "binary_fp_operator"
15301            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15302             (match_operand:DF 2 "register_operand" "0,0")]))]
15303   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15304    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15305   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15306   [(set (attr "type")
15307         (cond [(match_operand:DF 3 "mult_operator" "")
15308                  (const_string "fmul")
15309                (match_operand:DF 3 "div_operator" "")
15310                  (const_string "fdiv")
15311               ]
15312               (const_string "fop")))
15313    (set_attr "fp_int_src" "true")
15314    (set_attr "mode" "<MODE>")])
15315
15316 (define_insn "*fop_df_3<mode>_i387"
15317   [(set (match_operand:DF 0 "register_operand" "=f,f")
15318         (match_operator:DF 3 "binary_fp_operator"
15319            [(match_operand:DF 1 "register_operand" "0,0")
15320             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15321   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15322    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15323   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15324   [(set (attr "type")
15325         (cond [(match_operand:DF 3 "mult_operator" "")
15326                  (const_string "fmul")
15327                (match_operand:DF 3 "div_operator" "")
15328                  (const_string "fdiv")
15329               ]
15330               (const_string "fop")))
15331    (set_attr "fp_int_src" "true")
15332    (set_attr "mode" "<MODE>")])
15333
15334 (define_insn "*fop_df_4_i387"
15335   [(set (match_operand:DF 0 "register_operand" "=f,f")
15336         (match_operator:DF 3 "binary_fp_operator"
15337            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15338             (match_operand:DF 2 "register_operand" "0,f")]))]
15339   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15340    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15341   "* return output_387_binary_op (insn, operands);"
15342   [(set (attr "type")
15343         (cond [(match_operand:DF 3 "mult_operator" "")
15344                  (const_string "fmul")
15345                (match_operand:DF 3 "div_operator" "")
15346                  (const_string "fdiv")
15347               ]
15348               (const_string "fop")))
15349    (set_attr "mode" "SF")])
15350
15351 (define_insn "*fop_df_5_i387"
15352   [(set (match_operand:DF 0 "register_operand" "=f,f")
15353         (match_operator:DF 3 "binary_fp_operator"
15354           [(match_operand:DF 1 "register_operand" "0,f")
15355            (float_extend:DF
15356             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15357   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15358   "* return output_387_binary_op (insn, operands);"
15359   [(set (attr "type")
15360         (cond [(match_operand:DF 3 "mult_operator" "")
15361                  (const_string "fmul")
15362                (match_operand:DF 3 "div_operator" "")
15363                  (const_string "fdiv")
15364               ]
15365               (const_string "fop")))
15366    (set_attr "mode" "SF")])
15367
15368 (define_insn "*fop_df_6_i387"
15369   [(set (match_operand:DF 0 "register_operand" "=f,f")
15370         (match_operator:DF 3 "binary_fp_operator"
15371           [(float_extend:DF
15372             (match_operand:SF 1 "register_operand" "0,f"))
15373            (float_extend:DF
15374             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15375   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15376   "* return output_387_binary_op (insn, operands);"
15377   [(set (attr "type")
15378         (cond [(match_operand:DF 3 "mult_operator" "")
15379                  (const_string "fmul")
15380                (match_operand:DF 3 "div_operator" "")
15381                  (const_string "fdiv")
15382               ]
15383               (const_string "fop")))
15384    (set_attr "mode" "SF")])
15385
15386 (define_insn "*fop_xf_comm_i387"
15387   [(set (match_operand:XF 0 "register_operand" "=f")
15388         (match_operator:XF 3 "binary_fp_operator"
15389                         [(match_operand:XF 1 "register_operand" "%0")
15390                          (match_operand:XF 2 "register_operand" "f")]))]
15391   "TARGET_80387
15392    && COMMUTATIVE_ARITH_P (operands[3])"
15393   "* return output_387_binary_op (insn, operands);"
15394   [(set (attr "type")
15395         (if_then_else (match_operand:XF 3 "mult_operator" "")
15396            (const_string "fmul")
15397            (const_string "fop")))
15398    (set_attr "mode" "XF")])
15399
15400 (define_insn "*fop_xf_1_i387"
15401   [(set (match_operand:XF 0 "register_operand" "=f,f")
15402         (match_operator:XF 3 "binary_fp_operator"
15403                         [(match_operand:XF 1 "register_operand" "0,f")
15404                          (match_operand:XF 2 "register_operand" "f,0")]))]
15405   "TARGET_80387
15406    && !COMMUTATIVE_ARITH_P (operands[3])"
15407   "* return output_387_binary_op (insn, operands);"
15408   [(set (attr "type")
15409         (cond [(match_operand:XF 3 "mult_operator" "")
15410                  (const_string "fmul")
15411                (match_operand:XF 3 "div_operator" "")
15412                  (const_string "fdiv")
15413               ]
15414               (const_string "fop")))
15415    (set_attr "mode" "XF")])
15416
15417 (define_insn "*fop_xf_2<mode>_i387"
15418   [(set (match_operand:XF 0 "register_operand" "=f,f")
15419         (match_operator:XF 3 "binary_fp_operator"
15420            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15421             (match_operand:XF 2 "register_operand" "0,0")]))]
15422   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15423   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15424   [(set (attr "type")
15425         (cond [(match_operand:XF 3 "mult_operator" "")
15426                  (const_string "fmul")
15427                (match_operand:XF 3 "div_operator" "")
15428                  (const_string "fdiv")
15429               ]
15430               (const_string "fop")))
15431    (set_attr "fp_int_src" "true")
15432    (set_attr "mode" "<MODE>")])
15433
15434 (define_insn "*fop_xf_3<mode>_i387"
15435   [(set (match_operand:XF 0 "register_operand" "=f,f")
15436         (match_operator:XF 3 "binary_fp_operator"
15437           [(match_operand:XF 1 "register_operand" "0,0")
15438            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15439   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15440   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15441   [(set (attr "type")
15442         (cond [(match_operand:XF 3 "mult_operator" "")
15443                  (const_string "fmul")
15444                (match_operand:XF 3 "div_operator" "")
15445                  (const_string "fdiv")
15446               ]
15447               (const_string "fop")))
15448    (set_attr "fp_int_src" "true")
15449    (set_attr "mode" "<MODE>")])
15450
15451 (define_insn "*fop_xf_4_i387"
15452   [(set (match_operand:XF 0 "register_operand" "=f,f")
15453         (match_operator:XF 3 "binary_fp_operator"
15454            [(float_extend:XF
15455               (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
15456             (match_operand:XF 2 "register_operand" "0,f")]))]
15457   "TARGET_80387"
15458   "* return output_387_binary_op (insn, operands);"
15459   [(set (attr "type")
15460         (cond [(match_operand:XF 3 "mult_operator" "")
15461                  (const_string "fmul")
15462                (match_operand:XF 3 "div_operator" "")
15463                  (const_string "fdiv")
15464               ]
15465               (const_string "fop")))
15466    (set_attr "mode" "SF")])
15467
15468 (define_insn "*fop_xf_5_i387"
15469   [(set (match_operand:XF 0 "register_operand" "=f,f")
15470         (match_operator:XF 3 "binary_fp_operator"
15471           [(match_operand:XF 1 "register_operand" "0,f")
15472            (float_extend:XF
15473              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15474   "TARGET_80387"
15475   "* return output_387_binary_op (insn, operands);"
15476   [(set (attr "type")
15477         (cond [(match_operand:XF 3 "mult_operator" "")
15478                  (const_string "fmul")
15479                (match_operand:XF 3 "div_operator" "")
15480                  (const_string "fdiv")
15481               ]
15482               (const_string "fop")))
15483    (set_attr "mode" "SF")])
15484
15485 (define_insn "*fop_xf_6_i387"
15486   [(set (match_operand:XF 0 "register_operand" "=f,f")
15487         (match_operator:XF 3 "binary_fp_operator"
15488           [(float_extend:XF
15489              (match_operand:X87MODEF12 1 "register_operand" "0,f"))
15490            (float_extend:XF
15491              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15492   "TARGET_80387"
15493   "* return output_387_binary_op (insn, operands);"
15494   [(set (attr "type")
15495         (cond [(match_operand:XF 3 "mult_operator" "")
15496                  (const_string "fmul")
15497                (match_operand:XF 3 "div_operator" "")
15498                  (const_string "fdiv")
15499               ]
15500               (const_string "fop")))
15501    (set_attr "mode" "SF")])
15502
15503 (define_split
15504   [(set (match_operand 0 "register_operand" "")
15505         (match_operator 3 "binary_fp_operator"
15506            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15507             (match_operand 2 "register_operand" "")]))]
15508   "TARGET_80387 && reload_completed
15509    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15510   [(const_int 0)]
15511 {
15512   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15513   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15514   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15515                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15516                                           GET_MODE (operands[3]),
15517                                           operands[4],
15518                                           operands[2])));
15519   ix86_free_from_memory (GET_MODE (operands[1]));
15520   DONE;
15521 })
15522
15523 (define_split
15524   [(set (match_operand 0 "register_operand" "")
15525         (match_operator 3 "binary_fp_operator"
15526            [(match_operand 1 "register_operand" "")
15527             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15528   "TARGET_80387 && reload_completed
15529    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15530   [(const_int 0)]
15531 {
15532   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15533   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15534   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15535                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15536                                           GET_MODE (operands[3]),
15537                                           operands[1],
15538                                           operands[4])));
15539   ix86_free_from_memory (GET_MODE (operands[2]));
15540   DONE;
15541 })
15542 \f
15543 ;; FPU special functions.
15544
15545 ;; This pattern implements a no-op XFmode truncation for
15546 ;; all fancy i386 XFmode math functions.
15547
15548 (define_insn "truncxf<mode>2_i387_noop_unspec"
15549   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15550         (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
15551         UNSPEC_TRUNC_NOOP))]
15552   "TARGET_USE_FANCY_MATH_387"
15553   "* return output_387_reg_move (insn, operands);"
15554   [(set_attr "type" "fmov")
15555    (set_attr "mode" "<MODE>")])
15556
15557 (define_insn "sqrtxf2"
15558   [(set (match_operand:XF 0 "register_operand" "=f")
15559         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15560   "TARGET_USE_FANCY_MATH_387"
15561   "fsqrt"
15562   [(set_attr "type" "fpspc")
15563    (set_attr "mode" "XF")
15564    (set_attr "athlon_decode" "direct")])
15565
15566 (define_insn "sqrt_extend<mode>xf2_i387"
15567   [(set (match_operand:XF 0 "register_operand" "=f")
15568         (sqrt:XF
15569           (float_extend:XF
15570             (match_operand:X87MODEF12 1 "register_operand" "0"))))]
15571   "TARGET_USE_FANCY_MATH_387"
15572   "fsqrt"
15573   [(set_attr "type" "fpspc")
15574    (set_attr "mode" "XF")
15575    (set_attr "athlon_decode" "direct")])
15576
15577 (define_insn "*sqrt<mode>2_sse"
15578   [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
15579         (sqrt:SSEMODEF
15580           (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
15581   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15582   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
15583   [(set_attr "type" "sse")
15584    (set_attr "mode" "<MODE>")
15585    (set_attr "athlon_decode" "*")])
15586
15587 (define_expand "sqrt<mode>2"
15588   [(set (match_operand:X87MODEF12 0 "register_operand" "")
15589         (sqrt:X87MODEF12
15590           (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
15591   "TARGET_USE_FANCY_MATH_387
15592    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15593 {
15594   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15595     {
15596       rtx op0 = gen_reg_rtx (XFmode);
15597       rtx op1 = force_reg (<MODE>mode, operands[1]);
15598
15599       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15600       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15601       DONE;
15602    }
15603 })
15604
15605 (define_insn "fpremxf4_i387"
15606   [(set (match_operand:XF 0 "register_operand" "=f")
15607         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15608                     (match_operand:XF 3 "register_operand" "1")]
15609                    UNSPEC_FPREM_F))
15610    (set (match_operand:XF 1 "register_operand" "=u")
15611         (unspec:XF [(match_dup 2) (match_dup 3)]
15612                    UNSPEC_FPREM_U))
15613    (set (reg:CCFP FPSR_REG)
15614         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15615   "TARGET_USE_FANCY_MATH_387"
15616   "fprem"
15617   [(set_attr "type" "fpspc")
15618    (set_attr "mode" "XF")])
15619
15620 (define_expand "fmodxf3"
15621   [(use (match_operand:XF 0 "register_operand" ""))
15622    (use (match_operand:XF 1 "register_operand" ""))
15623    (use (match_operand:XF 2 "register_operand" ""))]
15624   "TARGET_USE_FANCY_MATH_387"
15625 {
15626   rtx label = gen_label_rtx ();
15627
15628   emit_label (label);
15629
15630   emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
15631                                 operands[1], operands[2]));
15632   ix86_emit_fp_unordered_jump (label);
15633
15634   emit_move_insn (operands[0], operands[1]);
15635   DONE;
15636 })
15637
15638 (define_expand "fmod<mode>3"
15639   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15640    (use (match_operand:X87MODEF12 1 "general_operand" ""))
15641    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
15642   "TARGET_USE_FANCY_MATH_387"
15643 {
15644   rtx label = gen_label_rtx ();
15645
15646   rtx op1 = gen_reg_rtx (XFmode);
15647   rtx op2 = gen_reg_rtx (XFmode);
15648
15649   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15650   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15651
15652   emit_label (label);
15653   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15654   ix86_emit_fp_unordered_jump (label);
15655
15656   /* Truncate the result properly for strict SSE math.  */
15657   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15658       && !TARGET_MIX_SSE_I387)
15659     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15660   else
15661     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15662
15663   DONE;
15664 })
15665
15666 (define_insn "fprem1xf4_i387"
15667   [(set (match_operand:XF 0 "register_operand" "=f")
15668         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15669                     (match_operand:XF 3 "register_operand" "1")]
15670                    UNSPEC_FPREM1_F))
15671    (set (match_operand:XF 1 "register_operand" "=u")
15672         (unspec:XF [(match_dup 2) (match_dup 3)]
15673                    UNSPEC_FPREM1_U))
15674    (set (reg:CCFP FPSR_REG)
15675         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15676   "TARGET_USE_FANCY_MATH_387"
15677   "fprem1"
15678   [(set_attr "type" "fpspc")
15679    (set_attr "mode" "XF")])
15680
15681 (define_expand "remainderxf3"
15682   [(use (match_operand:XF 0 "register_operand" ""))
15683    (use (match_operand:XF 1 "register_operand" ""))
15684    (use (match_operand:XF 2 "register_operand" ""))]
15685   "TARGET_USE_FANCY_MATH_387"
15686 {
15687   rtx label = gen_label_rtx ();
15688
15689   emit_label (label);
15690
15691   emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
15692                                  operands[1], operands[2]));
15693   ix86_emit_fp_unordered_jump (label);
15694
15695   emit_move_insn (operands[0], operands[1]);
15696   DONE;
15697 })
15698
15699 (define_expand "remainder<mode>3"
15700   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15701    (use (match_operand:X87MODEF12 1 "general_operand" ""))
15702    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
15703   "TARGET_USE_FANCY_MATH_387"
15704 {
15705   rtx label = gen_label_rtx ();
15706
15707   rtx op1 = gen_reg_rtx (XFmode);
15708   rtx op2 = gen_reg_rtx (XFmode);
15709
15710   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15711   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15712
15713   emit_label (label);
15714
15715   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15716   ix86_emit_fp_unordered_jump (label);
15717
15718   /* Truncate the result properly for strict SSE math.  */
15719   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15720       && !TARGET_MIX_SSE_I387)
15721     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15722   else
15723     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15724
15725   DONE;
15726 })
15727
15728 (define_insn "*sinxf2_i387"
15729   [(set (match_operand:XF 0 "register_operand" "=f")
15730         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15731   "TARGET_USE_FANCY_MATH_387
15732    && flag_unsafe_math_optimizations"
15733   "fsin"
15734   [(set_attr "type" "fpspc")
15735    (set_attr "mode" "XF")])
15736
15737 (define_insn "*sin_extend<mode>xf2_i387"
15738   [(set (match_operand:XF 0 "register_operand" "=f")
15739         (unspec:XF [(float_extend:XF
15740                       (match_operand:X87MODEF12 1 "register_operand" "0"))]
15741                    UNSPEC_SIN))]
15742   "TARGET_USE_FANCY_MATH_387
15743    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15744        || TARGET_MIX_SSE_I387)
15745    && flag_unsafe_math_optimizations"
15746   "fsin"
15747   [(set_attr "type" "fpspc")
15748    (set_attr "mode" "XF")])
15749
15750 (define_insn "*cosxf2_i387"
15751   [(set (match_operand:XF 0 "register_operand" "=f")
15752         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15753   "TARGET_USE_FANCY_MATH_387
15754    && flag_unsafe_math_optimizations"
15755   "fcos"
15756   [(set_attr "type" "fpspc")
15757    (set_attr "mode" "XF")])
15758
15759 (define_insn "*cos_extend<mode>xf2_i387"
15760   [(set (match_operand:XF 0 "register_operand" "=f")
15761         (unspec:XF [(float_extend:XF
15762                       (match_operand:X87MODEF12 1 "register_operand" "0"))]
15763                    UNSPEC_COS))]
15764   "TARGET_USE_FANCY_MATH_387
15765    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15766        || TARGET_MIX_SSE_I387)
15767    && flag_unsafe_math_optimizations"
15768   "fcos"
15769   [(set_attr "type" "fpspc")
15770    (set_attr "mode" "XF")])
15771
15772 ;; When sincos pattern is defined, sin and cos builtin functions will be
15773 ;; expanded to sincos pattern with one of its outputs left unused.
15774 ;; CSE pass will figure out if two sincos patterns can be combined,
15775 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15776 ;; depending on the unused output.
15777
15778 (define_insn "sincosxf3"
15779   [(set (match_operand:XF 0 "register_operand" "=f")
15780         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15781                    UNSPEC_SINCOS_COS))
15782    (set (match_operand:XF 1 "register_operand" "=u")
15783         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15784   "TARGET_USE_FANCY_MATH_387
15785    && flag_unsafe_math_optimizations"
15786   "fsincos"
15787   [(set_attr "type" "fpspc")
15788    (set_attr "mode" "XF")])
15789
15790 (define_split
15791   [(set (match_operand:XF 0 "register_operand" "")
15792         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15793                    UNSPEC_SINCOS_COS))
15794    (set (match_operand:XF 1 "register_operand" "")
15795         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15796   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15797    && !reload_completed && !reload_in_progress"
15798   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15799   "")
15800
15801 (define_split
15802   [(set (match_operand:XF 0 "register_operand" "")
15803         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15804                    UNSPEC_SINCOS_COS))
15805    (set (match_operand:XF 1 "register_operand" "")
15806         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15807   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15808    && !reload_completed && !reload_in_progress"
15809   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15810   "")
15811
15812 (define_insn "sincos_extend<mode>xf3_i387"
15813   [(set (match_operand:XF 0 "register_operand" "=f")
15814         (unspec:XF [(float_extend:XF
15815                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
15816                    UNSPEC_SINCOS_COS))
15817    (set (match_operand:XF 1 "register_operand" "=u")
15818         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15819   "TARGET_USE_FANCY_MATH_387
15820    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15821        || TARGET_MIX_SSE_I387)
15822    && flag_unsafe_math_optimizations"
15823   "fsincos"
15824   [(set_attr "type" "fpspc")
15825    (set_attr "mode" "XF")])
15826
15827 (define_split
15828   [(set (match_operand:XF 0 "register_operand" "")
15829         (unspec:XF [(float_extend:XF
15830                       (match_operand:X87MODEF12 2 "register_operand" ""))]
15831                    UNSPEC_SINCOS_COS))
15832    (set (match_operand:XF 1 "register_operand" "")
15833         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15834   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15835    && !reload_completed && !reload_in_progress"
15836   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
15837   "")
15838
15839 (define_split
15840   [(set (match_operand:XF 0 "register_operand" "")
15841         (unspec:XF [(float_extend:XF
15842                       (match_operand:X87MODEF12 2 "register_operand" ""))]
15843                    UNSPEC_SINCOS_COS))
15844    (set (match_operand:XF 1 "register_operand" "")
15845         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15846   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15847    && !reload_completed && !reload_in_progress"
15848   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
15849   "")
15850
15851 (define_expand "sincos<mode>3"
15852   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15853    (use (match_operand:X87MODEF12 1 "register_operand" ""))
15854    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
15855   "TARGET_USE_FANCY_MATH_387
15856    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15857        || TARGET_MIX_SSE_I387)
15858    && flag_unsafe_math_optimizations"
15859 {
15860   rtx op0 = gen_reg_rtx (XFmode);
15861   rtx op1 = gen_reg_rtx (XFmode);
15862
15863   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
15864   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15865   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
15866   DONE;
15867 })
15868
15869 (define_insn "fptanxf4_i387"
15870   [(set (match_operand:XF 0 "register_operand" "=f")
15871         (match_operand:XF 3 "const_double_operand" "F"))
15872    (set (match_operand:XF 1 "register_operand" "=u")
15873         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15874                    UNSPEC_TAN))]
15875   "TARGET_USE_FANCY_MATH_387
15876    && flag_unsafe_math_optimizations
15877    && standard_80387_constant_p (operands[3]) == 2"
15878   "fptan"
15879   [(set_attr "type" "fpspc")
15880    (set_attr "mode" "XF")])
15881
15882 (define_insn "fptan_extend<mode>xf4_i387"
15883   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15884         (match_operand:X87MODEF12 3 "const_double_operand" "F"))
15885    (set (match_operand:XF 1 "register_operand" "=u")
15886         (unspec:XF [(float_extend:XF
15887                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
15888                    UNSPEC_TAN))]
15889   "TARGET_USE_FANCY_MATH_387
15890    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15891        || TARGET_MIX_SSE_I387)
15892    && flag_unsafe_math_optimizations
15893    && standard_80387_constant_p (operands[3]) == 2"
15894   "fptan"
15895   [(set_attr "type" "fpspc")
15896    (set_attr "mode" "XF")])
15897
15898 (define_expand "tanxf2"
15899   [(use (match_operand:XF 0 "register_operand" ""))
15900    (use (match_operand:XF 1 "register_operand" ""))]
15901   "TARGET_USE_FANCY_MATH_387
15902    && flag_unsafe_math_optimizations"
15903 {
15904   rtx one = gen_reg_rtx (XFmode);
15905   operands[2] = CONST1_RTX (XFmode); /* fld1 */
15906
15907   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], operands[2]));
15908   DONE;
15909 })
15910
15911 (define_expand "tan<mode>2"
15912   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15913    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
15914   "TARGET_USE_FANCY_MATH_387
15915    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15916        || TARGET_MIX_SSE_I387)
15917    && flag_unsafe_math_optimizations"
15918 {
15919   rtx op0 = gen_reg_rtx (XFmode);
15920
15921   rtx one = gen_reg_rtx (<MODE>mode);
15922   operands[2] = CONST1_RTX (<MODE>mode); /* fld1 */
15923
15924   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
15925                                              operands[1], operands[2]));
15926   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15927   DONE;
15928 })
15929
15930 (define_insn "*fpatanxf3_i387"
15931   [(set (match_operand:XF 0 "register_operand" "=f")
15932         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15933                     (match_operand:XF 2 "register_operand" "u")]
15934                    UNSPEC_FPATAN))
15935    (clobber (match_scratch:XF 3 "=2"))]
15936   "TARGET_USE_FANCY_MATH_387
15937    && flag_unsafe_math_optimizations"
15938   "fpatan"
15939   [(set_attr "type" "fpspc")
15940    (set_attr "mode" "XF")])
15941
15942 (define_insn "fpatan_extend<mode>xf3_i387"
15943   [(set (match_operand:XF 0 "register_operand" "=f")
15944         (unspec:XF [(float_extend:XF
15945                       (match_operand:X87MODEF12 1 "register_operand" "0"))
15946                     (float_extend:XF
15947                       (match_operand:X87MODEF12 2 "register_operand" "u"))]
15948                    UNSPEC_FPATAN))
15949    (clobber (match_scratch:XF 3 "=2"))]
15950   "TARGET_USE_FANCY_MATH_387
15951    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15952        || TARGET_MIX_SSE_I387)
15953    && flag_unsafe_math_optimizations"
15954   "fpatan"
15955   [(set_attr "type" "fpspc")
15956    (set_attr "mode" "XF")])
15957
15958 (define_expand "atan2xf3"
15959   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15960                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
15961                                (match_operand:XF 1 "register_operand" "")]
15962                               UNSPEC_FPATAN))
15963               (clobber (match_scratch:XF 3 ""))])]
15964   "TARGET_USE_FANCY_MATH_387
15965    && flag_unsafe_math_optimizations"
15966   "")
15967
15968 (define_expand "atan2<mode>3"
15969   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15970    (use (match_operand:X87MODEF12 1 "register_operand" ""))
15971    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
15972   "TARGET_USE_FANCY_MATH_387
15973    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15974        || TARGET_MIX_SSE_I387)
15975    && flag_unsafe_math_optimizations"
15976 {
15977   rtx op0 = gen_reg_rtx (XFmode);
15978
15979   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
15980   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15981   DONE;
15982 })
15983
15984 (define_expand "atanxf2"
15985   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15986                    (unspec:XF [(match_dup 2)
15987                                (match_operand:XF 1 "register_operand" "")]
15988                               UNSPEC_FPATAN))
15989               (clobber (match_scratch:XF 3 ""))])]
15990   "TARGET_USE_FANCY_MATH_387
15991    && flag_unsafe_math_optimizations"
15992 {
15993   operands[2] = gen_reg_rtx (XFmode);
15994   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15995 })
15996
15997 (define_expand "atan<mode>2"
15998   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15999    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16000   "TARGET_USE_FANCY_MATH_387
16001    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16002        || TARGET_MIX_SSE_I387)
16003    && flag_unsafe_math_optimizations"
16004 {
16005   rtx op0 = gen_reg_rtx (XFmode);
16006
16007   operands[2] = gen_reg_rtx (<MODE>mode);
16008   emit_move_insn (operands[2], CONST1_RTX (<MODE>mode));  /* fld1 */
16009
16010   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16011   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16012   DONE;
16013 })
16014
16015 (define_expand "asindf2"
16016   [(set (match_dup 2)
16017         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16018    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16019    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16020    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16021    (parallel [(set (match_dup 7)
16022                    (unspec:XF [(match_dup 6) (match_dup 2)]
16023                               UNSPEC_FPATAN))
16024               (clobber (match_scratch:XF 8 ""))])
16025    (set (match_operand:DF 0 "register_operand" "")
16026         (float_truncate:DF (match_dup 7)))]
16027   "TARGET_USE_FANCY_MATH_387
16028    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16029    && flag_unsafe_math_optimizations && !optimize_size"
16030 {
16031   int i;
16032
16033   for (i=2; i<8; i++)
16034     operands[i] = gen_reg_rtx (XFmode);
16035
16036   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16037 })
16038
16039 (define_expand "asinsf2"
16040   [(set (match_dup 2)
16041         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16042    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16043    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16044    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16045    (parallel [(set (match_dup 7)
16046                    (unspec:XF [(match_dup 6) (match_dup 2)]
16047                               UNSPEC_FPATAN))
16048               (clobber (match_scratch:XF 8 ""))])
16049    (set (match_operand:SF 0 "register_operand" "")
16050         (float_truncate:SF (match_dup 7)))]
16051   "TARGET_USE_FANCY_MATH_387
16052    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16053    && flag_unsafe_math_optimizations && !optimize_size"
16054 {
16055   int i;
16056
16057   for (i=2; i<8; i++)
16058     operands[i] = gen_reg_rtx (XFmode);
16059
16060   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16061 })
16062
16063 (define_expand "asinxf2"
16064   [(set (match_dup 2)
16065         (mult:XF (match_operand:XF 1 "register_operand" "")
16066                  (match_dup 1)))
16067    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16068    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16069    (parallel [(set (match_operand:XF 0 "register_operand" "")
16070                    (unspec:XF [(match_dup 5) (match_dup 1)]
16071                               UNSPEC_FPATAN))
16072               (clobber (match_scratch:XF 6 ""))])]
16073   "TARGET_USE_FANCY_MATH_387
16074    && flag_unsafe_math_optimizations && !optimize_size"
16075 {
16076   int i;
16077
16078   for (i=2; i<6; i++)
16079     operands[i] = gen_reg_rtx (XFmode);
16080
16081   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16082 })
16083
16084 (define_expand "acosdf2"
16085   [(set (match_dup 2)
16086         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16087    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16088    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16089    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16090    (parallel [(set (match_dup 7)
16091                    (unspec:XF [(match_dup 2) (match_dup 6)]
16092                               UNSPEC_FPATAN))
16093               (clobber (match_scratch:XF 8 ""))])
16094    (set (match_operand:DF 0 "register_operand" "")
16095         (float_truncate:DF (match_dup 7)))]
16096   "TARGET_USE_FANCY_MATH_387
16097    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16098    && flag_unsafe_math_optimizations && !optimize_size"
16099 {
16100   int i;
16101
16102   for (i=2; i<8; i++)
16103     operands[i] = gen_reg_rtx (XFmode);
16104
16105   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16106 })
16107
16108 (define_expand "acossf2"
16109   [(set (match_dup 2)
16110         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16111    (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16112    (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16113    (set (match_dup 6) (sqrt:XF (match_dup 5)))
16114    (parallel [(set (match_dup 7)
16115                    (unspec:XF [(match_dup 2) (match_dup 6)]
16116                               UNSPEC_FPATAN))
16117               (clobber (match_scratch:XF 8 ""))])
16118    (set (match_operand:SF 0 "register_operand" "")
16119         (float_truncate:SF (match_dup 7)))]
16120   "TARGET_USE_FANCY_MATH_387
16121    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16122    && flag_unsafe_math_optimizations && !optimize_size"
16123 {
16124   int i;
16125
16126   for (i=2; i<8; i++)
16127     operands[i] = gen_reg_rtx (XFmode);
16128
16129   emit_move_insn (operands[4], CONST1_RTX (XFmode));  /* fld1 */
16130 })
16131
16132 (define_expand "acosxf2"
16133   [(set (match_dup 2)
16134         (mult:XF (match_operand:XF 1 "register_operand" "")
16135                  (match_dup 1)))
16136    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16137    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16138    (parallel [(set (match_operand:XF 0 "register_operand" "")
16139                    (unspec:XF [(match_dup 1) (match_dup 5)]
16140                               UNSPEC_FPATAN))
16141               (clobber (match_scratch:XF 6 ""))])]
16142   "TARGET_USE_FANCY_MATH_387
16143    && flag_unsafe_math_optimizations && !optimize_size"
16144 {
16145   int i;
16146
16147   for (i=2; i<6; i++)
16148     operands[i] = gen_reg_rtx (XFmode);
16149
16150   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16151 })
16152
16153 (define_insn "fyl2xxf3_i387"
16154   [(set (match_operand:XF 0 "register_operand" "=f")
16155         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16156                     (match_operand:XF 2 "register_operand" "u")]
16157                    UNSPEC_FYL2X))
16158    (clobber (match_scratch:XF 3 "=2"))]
16159   "TARGET_USE_FANCY_MATH_387
16160    && flag_unsafe_math_optimizations"
16161   "fyl2x"
16162   [(set_attr "type" "fpspc")
16163    (set_attr "mode" "XF")])
16164
16165 (define_insn "fyl2x_extend<mode>xf3_i387"
16166   [(set (match_operand:XF 0 "register_operand" "=f")
16167         (unspec:XF [(float_extend:XF
16168                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16169                     (match_operand:XF 2 "register_operand" "u")]
16170                    UNSPEC_FYL2X))
16171    (clobber (match_scratch:XF 3 "=2"))]
16172   "TARGET_USE_FANCY_MATH_387
16173    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16174        || TARGET_MIX_SSE_I387)
16175    && flag_unsafe_math_optimizations"
16176   "fyl2x"
16177   [(set_attr "type" "fpspc")
16178    (set_attr "mode" "XF")])
16179
16180 (define_expand "logxf2"
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], standard_80387_constant_rtx (4)); /* fldln2 */
16190 })
16191
16192 (define_expand "log<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], standard_80387_constant_rtx (4)); /* fldln2 */
16204
16205   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], operands[2]));
16206   emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16207   DONE;
16208 })
16209
16210 (define_expand "log10xf2"
16211   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16212                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16213                                (match_dup 2)] UNSPEC_FYL2X))
16214               (clobber (match_scratch:XF 3 ""))])]
16215   "TARGET_USE_FANCY_MATH_387
16216    && flag_unsafe_math_optimizations"
16217 {
16218   operands[2] = gen_reg_rtx (XFmode);
16219   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16220 })
16221
16222 (define_expand "log10<mode>2"
16223   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16224    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16225   "TARGET_USE_FANCY_MATH_387
16226    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16227        || TARGET_MIX_SSE_I387)
16228    && flag_unsafe_math_optimizations"
16229 {
16230   rtx op0 = gen_reg_rtx (XFmode);
16231
16232   operands[2] = gen_reg_rtx (XFmode);
16233   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16234
16235   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], operands[2]));
16236   emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16237   DONE;
16238 })
16239
16240 (define_expand "log2xf2"
16241   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16242                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16243                                (match_dup 2)] UNSPEC_FYL2X))
16244               (clobber (match_scratch:XF 3 ""))])]
16245   "TARGET_USE_FANCY_MATH_387
16246    && flag_unsafe_math_optimizations"
16247 {
16248   operands[2] = gen_reg_rtx (XFmode);
16249   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16250 })
16251
16252 (define_expand "log2<mode>2"
16253   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16254    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16255   "TARGET_USE_FANCY_MATH_387
16256    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16257        || TARGET_MIX_SSE_I387)
16258    && flag_unsafe_math_optimizations"
16259 {
16260   rtx op0 = gen_reg_rtx (XFmode);
16261
16262   operands[2] = gen_reg_rtx (XFmode);
16263   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16264
16265   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], operands[2]));
16266   emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16267   DONE;
16268 })
16269
16270 (define_insn "fyl2xp1xf3_i387"
16271   [(set (match_operand:XF 0 "register_operand" "=f")
16272         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16273                     (match_operand:XF 2 "register_operand" "u")]
16274                    UNSPEC_FYL2XP1))
16275    (clobber (match_scratch:XF 3 "=2"))]
16276   "TARGET_USE_FANCY_MATH_387
16277    && flag_unsafe_math_optimizations"
16278   "fyl2xp1"
16279   [(set_attr "type" "fpspc")
16280    (set_attr "mode" "XF")])
16281
16282 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16283   [(set (match_operand:XF 0 "register_operand" "=f")
16284         (unspec:XF [(float_extend:XF
16285                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16286                     (match_operand:XF 2 "register_operand" "u")]
16287                    UNSPEC_FYL2XP1))
16288    (clobber (match_scratch:XF 3 "=2"))]
16289   "TARGET_USE_FANCY_MATH_387
16290    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16291        || TARGET_MIX_SSE_I387)
16292    && flag_unsafe_math_optimizations"
16293   "fyl2xp1"
16294   [(set_attr "type" "fpspc")
16295    (set_attr "mode" "XF")])
16296
16297 (define_expand "log1pxf2"
16298   [(use (match_operand:XF 0 "register_operand" ""))
16299    (use (match_operand:XF 1 "register_operand" ""))]
16300   "TARGET_USE_FANCY_MATH_387
16301    && flag_unsafe_math_optimizations && !optimize_size"
16302 {
16303   ix86_emit_i387_log1p (operands[0], operands[1]);
16304   DONE;
16305 })
16306
16307 (define_expand "log1p<mode>2"
16308   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16309    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16310   "TARGET_USE_FANCY_MATH_387
16311    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16312        || TARGET_MIX_SSE_I387)
16313    && flag_unsafe_math_optimizations && !optimize_size"
16314 {
16315   rtx op0 = gen_reg_rtx (XFmode);
16316
16317   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16318
16319   ix86_emit_i387_log1p (op0, operands[1]);
16320   emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16321   DONE;
16322 })
16323
16324 (define_insn "*fxtractxf3_i387"
16325   [(set (match_operand:XF 0 "register_operand" "=f")
16326         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16327                    UNSPEC_XTRACT_FRACT))
16328    (set (match_operand:XF 1 "register_operand" "=u")
16329         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16330   "TARGET_USE_FANCY_MATH_387
16331    && flag_unsafe_math_optimizations"
16332   "fxtract"
16333   [(set_attr "type" "fpspc")
16334    (set_attr "mode" "XF")])
16335
16336 (define_insn "fxtract_extend<mode>xf3_i387"
16337   [(set (match_operand:XF 0 "register_operand" "=f")
16338         (unspec:XF [(float_extend:XF
16339                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16340                    UNSPEC_XTRACT_FRACT))
16341    (set (match_operand:XF 1 "register_operand" "=u")
16342         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16343   "TARGET_USE_FANCY_MATH_387
16344    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16345        || TARGET_MIX_SSE_I387)
16346    && flag_unsafe_math_optimizations"
16347   "fxtract"
16348   [(set_attr "type" "fpspc")
16349    (set_attr "mode" "XF")])
16350
16351 (define_expand "logbxf2"
16352   [(parallel [(set (match_dup 2)
16353                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16354                               UNSPEC_XTRACT_FRACT))
16355               (set (match_operand:XF 0 "register_operand" "")
16356                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16357   "TARGET_USE_FANCY_MATH_387
16358    && flag_unsafe_math_optimizations"
16359 {
16360   operands[2] = gen_reg_rtx (XFmode);
16361 })
16362
16363 (define_expand "logb<mode>2"
16364   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16365    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16366   "TARGET_USE_FANCY_MATH_387
16367    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16368        || TARGET_MIX_SSE_I387)
16369    && flag_unsafe_math_optimizations"
16370 {
16371   rtx op0 = gen_reg_rtx (XFmode);
16372   rtx op1 = gen_reg_rtx (XFmode);
16373
16374   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16375   emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16376   DONE;
16377 })
16378
16379 (define_expand "ilogbsi2"
16380   [(parallel [(set (match_dup 2)
16381                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16382                               UNSPEC_XTRACT_FRACT))
16383               (set (match_dup 3)
16384                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16385    (parallel [(set (match_operand:SI 0 "register_operand" "")
16386                    (fix:SI (match_dup 3)))
16387               (clobber (reg:CC FLAGS_REG))])]
16388   "TARGET_USE_FANCY_MATH_387
16389    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16390    && flag_unsafe_math_optimizations && !optimize_size"
16391 {
16392   operands[2] = gen_reg_rtx (XFmode);
16393   operands[3] = gen_reg_rtx (XFmode);
16394 })
16395
16396 (define_insn "*f2xm1xf2"
16397   [(set (match_operand:XF 0 "register_operand" "=f")
16398         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16399          UNSPEC_F2XM1))]
16400   "TARGET_USE_FANCY_MATH_387
16401    && flag_unsafe_math_optimizations"
16402   "f2xm1"
16403   [(set_attr "type" "fpspc")
16404    (set_attr "mode" "XF")])
16405
16406 (define_insn "*fscalexf4"
16407   [(set (match_operand:XF 0 "register_operand" "=f")
16408         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16409                     (match_operand:XF 3 "register_operand" "1")]
16410                    UNSPEC_FSCALE_FRACT))
16411    (set (match_operand:XF 1 "register_operand" "=u")
16412         (unspec:XF [(match_dup 2) (match_dup 3)]
16413                    UNSPEC_FSCALE_EXP))]
16414   "TARGET_USE_FANCY_MATH_387
16415    && flag_unsafe_math_optimizations"
16416   "fscale"
16417   [(set_attr "type" "fpspc")
16418    (set_attr "mode" "XF")])
16419
16420 (define_expand "expsf2"
16421   [(set (match_dup 2)
16422         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16423    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16424    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16425    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16426    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16427    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16428    (parallel [(set (match_dup 10)
16429                    (unspec:XF [(match_dup 9) (match_dup 5)]
16430                               UNSPEC_FSCALE_FRACT))
16431               (set (match_dup 11)
16432                    (unspec:XF [(match_dup 9) (match_dup 5)]
16433                               UNSPEC_FSCALE_EXP))])
16434    (set (match_operand:SF 0 "register_operand" "")
16435         (float_truncate:SF (match_dup 10)))]
16436   "TARGET_USE_FANCY_MATH_387
16437    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16438    && flag_unsafe_math_optimizations && !optimize_size"
16439 {
16440   rtx temp;
16441   int i;
16442
16443   for (i=2; i<12; i++)
16444     operands[i] = gen_reg_rtx (XFmode);
16445   temp = standard_80387_constant_rtx (5); /* fldl2e */
16446   emit_move_insn (operands[3], temp);
16447   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16448 })
16449
16450 (define_expand "expdf2"
16451   [(set (match_dup 2)
16452         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16453    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16454    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16455    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16456    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16457    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16458    (parallel [(set (match_dup 10)
16459                    (unspec:XF [(match_dup 9) (match_dup 5)]
16460                               UNSPEC_FSCALE_FRACT))
16461               (set (match_dup 11)
16462                    (unspec:XF [(match_dup 9) (match_dup 5)]
16463                               UNSPEC_FSCALE_EXP))])
16464    (set (match_operand:DF 0 "register_operand" "")
16465         (float_truncate:DF (match_dup 10)))]
16466   "TARGET_USE_FANCY_MATH_387
16467    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16468    && flag_unsafe_math_optimizations && !optimize_size"
16469 {
16470   rtx temp;
16471   int i;
16472
16473   for (i=2; i<12; i++)
16474     operands[i] = gen_reg_rtx (XFmode);
16475   temp = standard_80387_constant_rtx (5); /* fldl2e */
16476   emit_move_insn (operands[3], temp);
16477   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16478 })
16479
16480 (define_expand "expxf2"
16481   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16482                                (match_dup 2)))
16483    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16484    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16485    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16486    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16487    (parallel [(set (match_operand:XF 0 "register_operand" "")
16488                    (unspec:XF [(match_dup 8) (match_dup 4)]
16489                               UNSPEC_FSCALE_FRACT))
16490               (set (match_dup 9)
16491                    (unspec:XF [(match_dup 8) (match_dup 4)]
16492                               UNSPEC_FSCALE_EXP))])]
16493   "TARGET_USE_FANCY_MATH_387
16494    && flag_unsafe_math_optimizations && !optimize_size"
16495 {
16496   rtx temp;
16497   int i;
16498
16499   for (i=2; i<10; i++)
16500     operands[i] = gen_reg_rtx (XFmode);
16501   temp = standard_80387_constant_rtx (5); /* fldl2e */
16502   emit_move_insn (operands[2], temp);
16503   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16504 })
16505
16506 (define_expand "exp10sf2"
16507   [(set (match_dup 2)
16508         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16509    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16510    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16511    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16512    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16513    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16514    (parallel [(set (match_dup 10)
16515                    (unspec:XF [(match_dup 9) (match_dup 5)]
16516                               UNSPEC_FSCALE_FRACT))
16517               (set (match_dup 11)
16518                    (unspec:XF [(match_dup 9) (match_dup 5)]
16519                               UNSPEC_FSCALE_EXP))])
16520    (set (match_operand:SF 0 "register_operand" "")
16521         (float_truncate:SF (match_dup 10)))]
16522   "TARGET_USE_FANCY_MATH_387
16523    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16524    && flag_unsafe_math_optimizations && !optimize_size"
16525 {
16526   rtx temp;
16527   int i;
16528
16529   for (i=2; i<12; i++)
16530     operands[i] = gen_reg_rtx (XFmode);
16531   temp = standard_80387_constant_rtx (6); /* fldl2t */
16532   emit_move_insn (operands[3], temp);
16533   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16534 })
16535
16536 (define_expand "exp10df2"
16537   [(set (match_dup 2)
16538         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16539    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16540    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16541    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16542    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16543    (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16544    (parallel [(set (match_dup 10)
16545                    (unspec:XF [(match_dup 9) (match_dup 5)]
16546                               UNSPEC_FSCALE_FRACT))
16547               (set (match_dup 11)
16548                    (unspec:XF [(match_dup 9) (match_dup 5)]
16549                               UNSPEC_FSCALE_EXP))])
16550    (set (match_operand:DF 0 "register_operand" "")
16551         (float_truncate:DF (match_dup 10)))]
16552   "TARGET_USE_FANCY_MATH_387
16553    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16554    && flag_unsafe_math_optimizations && !optimize_size"
16555 {
16556   rtx temp;
16557   int i;
16558
16559   for (i=2; i<12; i++)
16560     operands[i] = gen_reg_rtx (XFmode);
16561   temp = standard_80387_constant_rtx (6); /* fldl2t */
16562   emit_move_insn (operands[3], temp);
16563   emit_move_insn (operands[8], CONST1_RTX (XFmode));  /* fld1 */
16564 })
16565
16566 (define_expand "exp10xf2"
16567   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16568                                (match_dup 2)))
16569    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16570    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16571    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16572    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16573    (parallel [(set (match_operand:XF 0 "register_operand" "")
16574                    (unspec:XF [(match_dup 8) (match_dup 4)]
16575                               UNSPEC_FSCALE_FRACT))
16576               (set (match_dup 9)
16577                    (unspec:XF [(match_dup 8) (match_dup 4)]
16578                               UNSPEC_FSCALE_EXP))])]
16579   "TARGET_USE_FANCY_MATH_387
16580    && flag_unsafe_math_optimizations && !optimize_size"
16581 {
16582   rtx temp;
16583   int i;
16584
16585   for (i=2; i<10; i++)
16586     operands[i] = gen_reg_rtx (XFmode);
16587   temp = standard_80387_constant_rtx (6); /* fldl2t */
16588   emit_move_insn (operands[2], temp);
16589   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16590 })
16591
16592 (define_expand "exp2sf2"
16593   [(set (match_dup 2)
16594         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16595    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16596    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16597    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16598    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16599    (parallel [(set (match_dup 8)
16600                    (unspec:XF [(match_dup 7) (match_dup 3)]
16601                               UNSPEC_FSCALE_FRACT))
16602               (set (match_dup 9)
16603                    (unspec:XF [(match_dup 7) (match_dup 3)]
16604                               UNSPEC_FSCALE_EXP))])
16605    (set (match_operand:SF 0 "register_operand" "")
16606         (float_truncate:SF (match_dup 8)))]
16607   "TARGET_USE_FANCY_MATH_387
16608    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16609    && flag_unsafe_math_optimizations && !optimize_size"
16610 {
16611   int i;
16612
16613   for (i=2; i<10; i++)
16614     operands[i] = gen_reg_rtx (XFmode);
16615   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16616 })
16617
16618 (define_expand "exp2df2"
16619   [(set (match_dup 2)
16620         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16621    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16622    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16623    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16624    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16625    (parallel [(set (match_dup 8)
16626                    (unspec:XF [(match_dup 7) (match_dup 3)]
16627                               UNSPEC_FSCALE_FRACT))
16628               (set (match_dup 9)
16629                    (unspec:XF [(match_dup 7) (match_dup 3)]
16630                               UNSPEC_FSCALE_EXP))])
16631    (set (match_operand:DF 0 "register_operand" "")
16632         (float_truncate:DF (match_dup 8)))]
16633   "TARGET_USE_FANCY_MATH_387
16634    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16635    && flag_unsafe_math_optimizations && !optimize_size"
16636 {
16637   int i;
16638
16639   for (i=2; i<10; i++)
16640     operands[i] = gen_reg_rtx (XFmode);
16641   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16642 })
16643
16644 (define_expand "exp2xf2"
16645   [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16646    (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16647    (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16648    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16649    (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16650    (parallel [(set (match_operand:XF 0 "register_operand" "")
16651                    (unspec:XF [(match_dup 7) (match_dup 3)]
16652                               UNSPEC_FSCALE_FRACT))
16653               (set (match_dup 8)
16654                    (unspec:XF [(match_dup 7) (match_dup 3)]
16655                               UNSPEC_FSCALE_EXP))])]
16656   "TARGET_USE_FANCY_MATH_387
16657    && flag_unsafe_math_optimizations && !optimize_size"
16658 {
16659   int i;
16660
16661   for (i=2; i<9; i++)
16662     operands[i] = gen_reg_rtx (XFmode);
16663   emit_move_insn (operands[6], CONST1_RTX (XFmode));  /* fld1 */
16664 })
16665
16666 (define_expand "expm1df2"
16667   [(set (match_dup 2)
16668         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16669    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16670    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16671    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16672    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16673    (parallel [(set (match_dup 8)
16674                    (unspec:XF [(match_dup 7) (match_dup 5)]
16675                               UNSPEC_FSCALE_FRACT))
16676                    (set (match_dup 9)
16677                    (unspec:XF [(match_dup 7) (match_dup 5)]
16678                               UNSPEC_FSCALE_EXP))])
16679    (parallel [(set (match_dup 11)
16680                    (unspec:XF [(match_dup 10) (match_dup 9)]
16681                               UNSPEC_FSCALE_FRACT))
16682               (set (match_dup 12)
16683                    (unspec:XF [(match_dup 10) (match_dup 9)]
16684                               UNSPEC_FSCALE_EXP))])
16685    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16686    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16687    (set (match_operand:DF 0 "register_operand" "")
16688         (float_truncate:DF (match_dup 14)))]
16689   "TARGET_USE_FANCY_MATH_387
16690    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16691    && flag_unsafe_math_optimizations && !optimize_size"
16692 {
16693   rtx temp;
16694   int i;
16695
16696   for (i=2; i<15; i++)
16697     operands[i] = gen_reg_rtx (XFmode);
16698   temp = standard_80387_constant_rtx (5); /* fldl2e */
16699   emit_move_insn (operands[3], temp);
16700   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16701 })
16702
16703 (define_expand "expm1sf2"
16704   [(set (match_dup 2)
16705         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16706    (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16707    (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16708    (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16709    (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16710    (parallel [(set (match_dup 8)
16711                    (unspec:XF [(match_dup 7) (match_dup 5)]
16712                               UNSPEC_FSCALE_FRACT))
16713                    (set (match_dup 9)
16714                    (unspec:XF [(match_dup 7) (match_dup 5)]
16715                               UNSPEC_FSCALE_EXP))])
16716    (parallel [(set (match_dup 11)
16717                    (unspec:XF [(match_dup 10) (match_dup 9)]
16718                               UNSPEC_FSCALE_FRACT))
16719               (set (match_dup 12)
16720                    (unspec:XF [(match_dup 10) (match_dup 9)]
16721                               UNSPEC_FSCALE_EXP))])
16722    (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16723    (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16724    (set (match_operand:SF 0 "register_operand" "")
16725         (float_truncate:SF (match_dup 14)))]
16726   "TARGET_USE_FANCY_MATH_387
16727    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16728    && flag_unsafe_math_optimizations && !optimize_size"
16729 {
16730   rtx temp;
16731   int i;
16732
16733   for (i=2; i<15; i++)
16734     operands[i] = gen_reg_rtx (XFmode);
16735   temp = standard_80387_constant_rtx (5); /* fldl2e */
16736   emit_move_insn (operands[3], temp);
16737   emit_move_insn (operands[10], CONST1_RTX (XFmode));  /* fld1 */
16738 })
16739
16740 (define_expand "expm1xf2"
16741   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16742                                (match_dup 2)))
16743    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16744    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16745    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16746    (parallel [(set (match_dup 7)
16747                    (unspec:XF [(match_dup 6) (match_dup 4)]
16748                               UNSPEC_FSCALE_FRACT))
16749                    (set (match_dup 8)
16750                    (unspec:XF [(match_dup 6) (match_dup 4)]
16751                               UNSPEC_FSCALE_EXP))])
16752    (parallel [(set (match_dup 10)
16753                    (unspec:XF [(match_dup 9) (match_dup 8)]
16754                               UNSPEC_FSCALE_FRACT))
16755               (set (match_dup 11)
16756                    (unspec:XF [(match_dup 9) (match_dup 8)]
16757                               UNSPEC_FSCALE_EXP))])
16758    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16759    (set (match_operand:XF 0 "register_operand" "")
16760         (plus:XF (match_dup 12) (match_dup 7)))]
16761   "TARGET_USE_FANCY_MATH_387
16762    && flag_unsafe_math_optimizations && !optimize_size"
16763 {
16764   rtx temp;
16765   int i;
16766
16767   for (i=2; i<13; i++)
16768     operands[i] = gen_reg_rtx (XFmode);
16769   temp = standard_80387_constant_rtx (5); /* fldl2e */
16770   emit_move_insn (operands[2], temp);
16771   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16772 })
16773
16774 (define_expand "ldexpdf3"
16775   [(set (match_dup 3)
16776         (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16777    (set (match_dup 4)
16778         (float:XF (match_operand:SI 2 "register_operand" "")))
16779    (parallel [(set (match_dup 5)
16780                    (unspec:XF [(match_dup 3) (match_dup 4)]
16781                               UNSPEC_FSCALE_FRACT))
16782               (set (match_dup 6)
16783                    (unspec:XF [(match_dup 3) (match_dup 4)]
16784                               UNSPEC_FSCALE_EXP))])
16785    (set (match_operand:DF 0 "register_operand" "")
16786         (float_truncate:DF (match_dup 5)))]
16787   "TARGET_USE_FANCY_MATH_387
16788    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16789    && flag_unsafe_math_optimizations && !optimize_size"
16790 {
16791   int i;
16792
16793   for (i=3; i<7; i++)
16794     operands[i] = gen_reg_rtx (XFmode);
16795 })
16796
16797 (define_expand "ldexpsf3"
16798   [(set (match_dup 3)
16799         (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16800    (set (match_dup 4)
16801         (float:XF (match_operand:SI 2 "register_operand" "")))
16802    (parallel [(set (match_dup 5)
16803                    (unspec:XF [(match_dup 3) (match_dup 4)]
16804                               UNSPEC_FSCALE_FRACT))
16805               (set (match_dup 6)
16806                    (unspec:XF [(match_dup 3) (match_dup 4)]
16807                               UNSPEC_FSCALE_EXP))])
16808    (set (match_operand:SF 0 "register_operand" "")
16809         (float_truncate:SF (match_dup 5)))]
16810   "TARGET_USE_FANCY_MATH_387
16811    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16812    && flag_unsafe_math_optimizations && !optimize_size"
16813 {
16814   int i;
16815
16816   for (i=3; i<7; i++)
16817     operands[i] = gen_reg_rtx (XFmode);
16818 })
16819
16820 (define_expand "ldexpxf3"
16821   [(set (match_dup 3)
16822         (float:XF (match_operand:SI 2 "register_operand" "")))
16823    (parallel [(set (match_operand:XF 0 " register_operand" "")
16824                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16825                                (match_dup 3)]
16826                               UNSPEC_FSCALE_FRACT))
16827               (set (match_dup 4)
16828                    (unspec:XF [(match_dup 1) (match_dup 3)]
16829                               UNSPEC_FSCALE_EXP))])]
16830   "TARGET_USE_FANCY_MATH_387
16831    && flag_unsafe_math_optimizations && !optimize_size"
16832 {
16833   int i;
16834
16835   for (i=3; i<5; i++)
16836     operands[i] = gen_reg_rtx (XFmode);
16837 })
16838 \f
16839
16840 (define_insn "frndintxf2"
16841   [(set (match_operand:XF 0 "register_operand" "=f")
16842         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16843          UNSPEC_FRNDINT))]
16844   "TARGET_USE_FANCY_MATH_387
16845    && flag_unsafe_math_optimizations"
16846   "frndint"
16847   [(set_attr "type" "fpspc")
16848    (set_attr "mode" "XF")])
16849
16850 (define_expand "rintdf2"
16851   [(use (match_operand:DF 0 "register_operand" ""))
16852    (use (match_operand:DF 1 "register_operand" ""))]
16853   "(TARGET_USE_FANCY_MATH_387
16854     && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16855     && flag_unsafe_math_optimizations)
16856    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16857        && !flag_trapping_math
16858        && !optimize_size)"
16859 {
16860   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16861       && !flag_trapping_math
16862       && !optimize_size)
16863     ix86_expand_rint (operand0, operand1);
16864   else
16865     {
16866       rtx op0 = gen_reg_rtx (XFmode);
16867       rtx op1 = gen_reg_rtx (XFmode);
16868
16869       emit_insn (gen_extenddfxf2 (op1, operands[1]));
16870       emit_insn (gen_frndintxf2 (op0, op1));
16871
16872       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16873     }
16874   DONE;
16875 })
16876
16877 (define_expand "rintsf2"
16878   [(use (match_operand:SF 0 "register_operand" ""))
16879    (use (match_operand:SF 1 "register_operand" ""))]
16880   "(TARGET_USE_FANCY_MATH_387
16881     && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16882     && flag_unsafe_math_optimizations)
16883    || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16884        && !flag_trapping_math
16885        && !optimize_size)"
16886 {
16887   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16888       && !flag_trapping_math
16889       && !optimize_size)
16890     ix86_expand_rint (operand0, operand1);
16891   else
16892     {
16893       rtx op0 = gen_reg_rtx (XFmode);
16894       rtx op1 = gen_reg_rtx (XFmode);
16895
16896       emit_insn (gen_extendsfxf2 (op1, operands[1]));
16897       emit_insn (gen_frndintxf2 (op0, op1));
16898
16899       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16900     }
16901   DONE;
16902 })
16903
16904 (define_expand "rintxf2"
16905   [(use (match_operand:XF 0 "register_operand" ""))
16906    (use (match_operand:XF 1 "register_operand" ""))]
16907   "TARGET_USE_FANCY_MATH_387
16908    && flag_unsafe_math_optimizations && !optimize_size"
16909 {
16910   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16911   DONE;
16912 })
16913
16914 (define_expand "roundsf2"
16915   [(match_operand:SF 0 "register_operand" "")
16916    (match_operand:SF 1 "nonimmediate_operand" "")]
16917   "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16918    && !flag_trapping_math && !flag_rounding_math
16919    && !optimize_size"
16920 {
16921   ix86_expand_round (operand0, operand1);
16922   DONE;
16923 })
16924
16925 (define_expand "rounddf2"
16926   [(match_operand:DF 0 "register_operand" "")
16927    (match_operand:DF 1 "nonimmediate_operand" "")]
16928   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16929    && !flag_trapping_math && !flag_rounding_math
16930    && !optimize_size"
16931 {
16932   if (TARGET_64BIT)
16933     ix86_expand_round (operand0, operand1);
16934   else
16935     ix86_expand_rounddf_32 (operand0, operand1);
16936   DONE;
16937 })
16938
16939 (define_insn_and_split "*fistdi2_1"
16940   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16941         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16942          UNSPEC_FIST))]
16943   "TARGET_USE_FANCY_MATH_387
16944    && !(reload_completed || reload_in_progress)"
16945   "#"
16946   "&& 1"
16947   [(const_int 0)]
16948 {
16949   if (memory_operand (operands[0], VOIDmode))
16950     emit_insn (gen_fistdi2 (operands[0], operands[1]));
16951   else
16952     {
16953       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16954       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16955                                          operands[2]));
16956     }
16957   DONE;
16958 }
16959   [(set_attr "type" "fpspc")
16960    (set_attr "mode" "DI")])
16961
16962 (define_insn "fistdi2"
16963   [(set (match_operand:DI 0 "memory_operand" "=m")
16964         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16965          UNSPEC_FIST))
16966    (clobber (match_scratch:XF 2 "=&1f"))]
16967   "TARGET_USE_FANCY_MATH_387"
16968   "* return output_fix_trunc (insn, operands, 0);"
16969   [(set_attr "type" "fpspc")
16970    (set_attr "mode" "DI")])
16971
16972 (define_insn "fistdi2_with_temp"
16973   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16974         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16975          UNSPEC_FIST))
16976    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16977    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16978   "TARGET_USE_FANCY_MATH_387"
16979   "#"
16980   [(set_attr "type" "fpspc")
16981    (set_attr "mode" "DI")])
16982
16983 (define_split
16984   [(set (match_operand:DI 0 "register_operand" "")
16985         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16986          UNSPEC_FIST))
16987    (clobber (match_operand:DI 2 "memory_operand" ""))
16988    (clobber (match_scratch 3 ""))]
16989   "reload_completed"
16990   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16991               (clobber (match_dup 3))])
16992    (set (match_dup 0) (match_dup 2))]
16993   "")
16994
16995 (define_split
16996   [(set (match_operand:DI 0 "memory_operand" "")
16997         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16998          UNSPEC_FIST))
16999    (clobber (match_operand:DI 2 "memory_operand" ""))
17000    (clobber (match_scratch 3 ""))]
17001   "reload_completed"
17002   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17003               (clobber (match_dup 3))])]
17004   "")
17005
17006 (define_insn_and_split "*fist<mode>2_1"
17007   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17008         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17009          UNSPEC_FIST))]
17010   "TARGET_USE_FANCY_MATH_387
17011    && !(reload_completed || reload_in_progress)"
17012   "#"
17013   "&& 1"
17014   [(const_int 0)]
17015 {
17016   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17017   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17018                                         operands[2]));
17019   DONE;
17020 }
17021   [(set_attr "type" "fpspc")
17022    (set_attr "mode" "<MODE>")])
17023
17024 (define_insn "fist<mode>2"
17025   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17026         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17027          UNSPEC_FIST))]
17028   "TARGET_USE_FANCY_MATH_387"
17029   "* return output_fix_trunc (insn, operands, 0);"
17030   [(set_attr "type" "fpspc")
17031    (set_attr "mode" "<MODE>")])
17032
17033 (define_insn "fist<mode>2_with_temp"
17034   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17035         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17036          UNSPEC_FIST))
17037    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17038   "TARGET_USE_FANCY_MATH_387"
17039   "#"
17040   [(set_attr "type" "fpspc")
17041    (set_attr "mode" "<MODE>")])
17042
17043 (define_split
17044   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17045         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17046          UNSPEC_FIST))
17047    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17048   "reload_completed"
17049   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17050                        UNSPEC_FIST))
17051    (set (match_dup 0) (match_dup 2))]
17052   "")
17053
17054 (define_split
17055   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17056         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17057          UNSPEC_FIST))
17058    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17059   "reload_completed"
17060   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17061                        UNSPEC_FIST))]
17062   "")
17063
17064 (define_expand "lrintxf<mode>2"
17065   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17066      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17067       UNSPEC_FIST))]
17068   "TARGET_USE_FANCY_MATH_387"
17069   "")
17070
17071 (define_expand "lrint<mode>di2"
17072   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17073      (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
17074       UNSPEC_FIX_NOTRUNC))]
17075   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
17076   "")
17077
17078 (define_expand "lrint<mode>si2"
17079   [(set (match_operand:SI 0 "nonimmediate_operand" "")
17080      (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
17081       UNSPEC_FIX_NOTRUNC))]
17082   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17083   "")
17084
17085 (define_expand "lround<mode>di2"
17086   [(match_operand:DI 0 "nonimmediate_operand" "")
17087    (match_operand:SSEMODEF 1 "register_operand" "")]
17088   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17089    && !flag_trapping_math && !flag_rounding_math
17090    && !optimize_size"
17091 {
17092   ix86_expand_lround (operand0, operand1);
17093   DONE;
17094 })
17095
17096 (define_expand "lround<mode>si2"
17097   [(match_operand:SI 0 "nonimmediate_operand" "")
17098    (match_operand:SSEMODEF 1 "register_operand" "")]
17099   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17100    && !flag_trapping_math && !flag_rounding_math
17101    && !optimize_size"
17102 {
17103   ix86_expand_lround (operand0, operand1);
17104   DONE;
17105 })
17106
17107 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17108 (define_insn_and_split "frndintxf2_floor"
17109   [(set (match_operand:XF 0 "register_operand" "=f")
17110         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17111          UNSPEC_FRNDINT_FLOOR))
17112    (clobber (reg:CC FLAGS_REG))]
17113   "TARGET_USE_FANCY_MATH_387
17114    && flag_unsafe_math_optimizations
17115    && !(reload_completed || reload_in_progress)"
17116   "#"
17117   "&& 1"
17118   [(const_int 0)]
17119 {
17120   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17121
17122   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17123   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17124
17125   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17126                                         operands[2], operands[3]));
17127   DONE;
17128 }
17129   [(set_attr "type" "frndint")
17130    (set_attr "i387_cw" "floor")
17131    (set_attr "mode" "XF")])
17132
17133 (define_insn "frndintxf2_floor_i387"
17134   [(set (match_operand:XF 0 "register_operand" "=f")
17135         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17136          UNSPEC_FRNDINT_FLOOR))
17137    (use (match_operand:HI 2 "memory_operand" "m"))
17138    (use (match_operand:HI 3 "memory_operand" "m"))]
17139   "TARGET_USE_FANCY_MATH_387
17140    && flag_unsafe_math_optimizations"
17141   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17142   [(set_attr "type" "frndint")
17143    (set_attr "i387_cw" "floor")
17144    (set_attr "mode" "XF")])
17145
17146 (define_expand "floorxf2"
17147   [(use (match_operand:XF 0 "register_operand" ""))
17148    (use (match_operand:XF 1 "register_operand" ""))]
17149   "TARGET_USE_FANCY_MATH_387
17150    && flag_unsafe_math_optimizations && !optimize_size"
17151 {
17152   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17153   DONE;
17154 })
17155
17156 (define_expand "floordf2"
17157   [(use (match_operand:DF 0 "register_operand" ""))
17158    (use (match_operand:DF 1 "register_operand" ""))]
17159   "((TARGET_USE_FANCY_MATH_387
17160      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17161      && flag_unsafe_math_optimizations)
17162     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17163         && !flag_trapping_math))
17164    && !optimize_size"
17165 {
17166   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17167       && !flag_trapping_math)
17168     {
17169       if (TARGET_64BIT)
17170         ix86_expand_floorceil (operand0, operand1, true);
17171       else
17172         ix86_expand_floorceildf_32 (operand0, operand1, true);
17173     }
17174   else
17175     {
17176       rtx op0 = gen_reg_rtx (XFmode);
17177       rtx op1 = gen_reg_rtx (XFmode);
17178
17179       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17180       emit_insn (gen_frndintxf2_floor (op0, op1));
17181
17182       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17183     }
17184   DONE;
17185 })
17186
17187 (define_expand "floorsf2"
17188   [(use (match_operand:SF 0 "register_operand" ""))
17189    (use (match_operand:SF 1 "register_operand" ""))]
17190   "((TARGET_USE_FANCY_MATH_387
17191      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17192      && flag_unsafe_math_optimizations)
17193     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17194         && !flag_trapping_math))
17195    && !optimize_size"
17196 {
17197   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17198       && !flag_trapping_math)
17199     ix86_expand_floorceil (operand0, operand1, true);
17200   else
17201     {
17202       rtx op0 = gen_reg_rtx (XFmode);
17203       rtx op1 = gen_reg_rtx (XFmode);
17204
17205       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17206       emit_insn (gen_frndintxf2_floor (op0, op1));
17207
17208       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17209     }
17210   DONE;
17211 })
17212
17213 (define_insn_and_split "*fist<mode>2_floor_1"
17214   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17215         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17216          UNSPEC_FIST_FLOOR))
17217    (clobber (reg:CC FLAGS_REG))]
17218   "TARGET_USE_FANCY_MATH_387
17219    && flag_unsafe_math_optimizations
17220    && !(reload_completed || reload_in_progress)"
17221   "#"
17222   "&& 1"
17223   [(const_int 0)]
17224 {
17225   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17226
17227   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17228   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17229   if (memory_operand (operands[0], VOIDmode))
17230     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17231                                       operands[2], operands[3]));
17232   else
17233     {
17234       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17235       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17236                                                   operands[2], operands[3],
17237                                                   operands[4]));
17238     }
17239   DONE;
17240 }
17241   [(set_attr "type" "fistp")
17242    (set_attr "i387_cw" "floor")
17243    (set_attr "mode" "<MODE>")])
17244
17245 (define_insn "fistdi2_floor"
17246   [(set (match_operand:DI 0 "memory_operand" "=m")
17247         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17248          UNSPEC_FIST_FLOOR))
17249    (use (match_operand:HI 2 "memory_operand" "m"))
17250    (use (match_operand:HI 3 "memory_operand" "m"))
17251    (clobber (match_scratch:XF 4 "=&1f"))]
17252   "TARGET_USE_FANCY_MATH_387
17253    && flag_unsafe_math_optimizations"
17254   "* return output_fix_trunc (insn, operands, 0);"
17255   [(set_attr "type" "fistp")
17256    (set_attr "i387_cw" "floor")
17257    (set_attr "mode" "DI")])
17258
17259 (define_insn "fistdi2_floor_with_temp"
17260   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17261         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17262          UNSPEC_FIST_FLOOR))
17263    (use (match_operand:HI 2 "memory_operand" "m,m"))
17264    (use (match_operand:HI 3 "memory_operand" "m,m"))
17265    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17266    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17267   "TARGET_USE_FANCY_MATH_387
17268    && flag_unsafe_math_optimizations"
17269   "#"
17270   [(set_attr "type" "fistp")
17271    (set_attr "i387_cw" "floor")
17272    (set_attr "mode" "DI")])
17273
17274 (define_split
17275   [(set (match_operand:DI 0 "register_operand" "")
17276         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17277          UNSPEC_FIST_FLOOR))
17278    (use (match_operand:HI 2 "memory_operand" ""))
17279    (use (match_operand:HI 3 "memory_operand" ""))
17280    (clobber (match_operand:DI 4 "memory_operand" ""))
17281    (clobber (match_scratch 5 ""))]
17282   "reload_completed"
17283   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17284               (use (match_dup 2))
17285               (use (match_dup 3))
17286               (clobber (match_dup 5))])
17287    (set (match_dup 0) (match_dup 4))]
17288   "")
17289
17290 (define_split
17291   [(set (match_operand:DI 0 "memory_operand" "")
17292         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17293          UNSPEC_FIST_FLOOR))
17294    (use (match_operand:HI 2 "memory_operand" ""))
17295    (use (match_operand:HI 3 "memory_operand" ""))
17296    (clobber (match_operand:DI 4 "memory_operand" ""))
17297    (clobber (match_scratch 5 ""))]
17298   "reload_completed"
17299   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17300               (use (match_dup 2))
17301               (use (match_dup 3))
17302               (clobber (match_dup 5))])]
17303   "")
17304
17305 (define_insn "fist<mode>2_floor"
17306   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17307         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17308          UNSPEC_FIST_FLOOR))
17309    (use (match_operand:HI 2 "memory_operand" "m"))
17310    (use (match_operand:HI 3 "memory_operand" "m"))]
17311   "TARGET_USE_FANCY_MATH_387
17312    && flag_unsafe_math_optimizations"
17313   "* return output_fix_trunc (insn, operands, 0);"
17314   [(set_attr "type" "fistp")
17315    (set_attr "i387_cw" "floor")
17316    (set_attr "mode" "<MODE>")])
17317
17318 (define_insn "fist<mode>2_floor_with_temp"
17319   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17320         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17321          UNSPEC_FIST_FLOOR))
17322    (use (match_operand:HI 2 "memory_operand" "m,m"))
17323    (use (match_operand:HI 3 "memory_operand" "m,m"))
17324    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17325   "TARGET_USE_FANCY_MATH_387
17326    && flag_unsafe_math_optimizations"
17327   "#"
17328   [(set_attr "type" "fistp")
17329    (set_attr "i387_cw" "floor")
17330    (set_attr "mode" "<MODE>")])
17331
17332 (define_split
17333   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17334         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17335          UNSPEC_FIST_FLOOR))
17336    (use (match_operand:HI 2 "memory_operand" ""))
17337    (use (match_operand:HI 3 "memory_operand" ""))
17338    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17339   "reload_completed"
17340   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17341                                   UNSPEC_FIST_FLOOR))
17342               (use (match_dup 2))
17343               (use (match_dup 3))])
17344    (set (match_dup 0) (match_dup 4))]
17345   "")
17346
17347 (define_split
17348   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17349         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17350          UNSPEC_FIST_FLOOR))
17351    (use (match_operand:HI 2 "memory_operand" ""))
17352    (use (match_operand:HI 3 "memory_operand" ""))
17353    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17354   "reload_completed"
17355   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17356                                   UNSPEC_FIST_FLOOR))
17357               (use (match_dup 2))
17358               (use (match_dup 3))])]
17359   "")
17360
17361 (define_expand "lfloorxf<mode>2"
17362   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17363                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17364                     UNSPEC_FIST_FLOOR))
17365               (clobber (reg:CC FLAGS_REG))])]
17366   "TARGET_USE_FANCY_MATH_387
17367    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17368    && flag_unsafe_math_optimizations"
17369   "")
17370
17371 (define_expand "lfloor<mode>di2"
17372   [(match_operand:DI 0 "nonimmediate_operand" "")
17373    (match_operand:SSEMODEF 1 "register_operand" "")]
17374   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17375    && !flag_trapping_math
17376    && !optimize_size"
17377 {
17378   ix86_expand_lfloorceil (operand0, operand1, true);
17379   DONE;
17380 })
17381
17382 (define_expand "lfloor<mode>si2"
17383   [(match_operand:SI 0 "nonimmediate_operand" "")
17384    (match_operand:SSEMODEF 1 "register_operand" "")]
17385   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17386    && !flag_trapping_math
17387    && (!optimize_size || !TARGET_64BIT)"
17388 {
17389   ix86_expand_lfloorceil (operand0, operand1, true);
17390   DONE;
17391 })
17392
17393 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17394 (define_insn_and_split "frndintxf2_ceil"
17395   [(set (match_operand:XF 0 "register_operand" "=f")
17396         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17397          UNSPEC_FRNDINT_CEIL))
17398    (clobber (reg:CC FLAGS_REG))]
17399   "TARGET_USE_FANCY_MATH_387
17400    && flag_unsafe_math_optimizations
17401    && !(reload_completed || reload_in_progress)"
17402   "#"
17403   "&& 1"
17404   [(const_int 0)]
17405 {
17406   ix86_optimize_mode_switching[I387_CEIL] = 1;
17407
17408   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17409   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17410
17411   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17412                                        operands[2], operands[3]));
17413   DONE;
17414 }
17415   [(set_attr "type" "frndint")
17416    (set_attr "i387_cw" "ceil")
17417    (set_attr "mode" "XF")])
17418
17419 (define_insn "frndintxf2_ceil_i387"
17420   [(set (match_operand:XF 0 "register_operand" "=f")
17421         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17422          UNSPEC_FRNDINT_CEIL))
17423    (use (match_operand:HI 2 "memory_operand" "m"))
17424    (use (match_operand:HI 3 "memory_operand" "m"))]
17425   "TARGET_USE_FANCY_MATH_387
17426    && flag_unsafe_math_optimizations"
17427   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17428   [(set_attr "type" "frndint")
17429    (set_attr "i387_cw" "ceil")
17430    (set_attr "mode" "XF")])
17431
17432 (define_expand "ceilxf2"
17433   [(use (match_operand:XF 0 "register_operand" ""))
17434    (use (match_operand:XF 1 "register_operand" ""))]
17435   "TARGET_USE_FANCY_MATH_387
17436    && flag_unsafe_math_optimizations && !optimize_size"
17437 {
17438   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17439   DONE;
17440 })
17441
17442 (define_expand "ceildf2"
17443   [(use (match_operand:DF 0 "register_operand" ""))
17444    (use (match_operand:DF 1 "register_operand" ""))]
17445   "((TARGET_USE_FANCY_MATH_387
17446      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17447      && flag_unsafe_math_optimizations)
17448     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17449         && !flag_trapping_math))
17450    && !optimize_size"
17451 {
17452   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17453       && !flag_trapping_math)
17454     {
17455       if (TARGET_64BIT)
17456         ix86_expand_floorceil (operand0, operand1, false);
17457       else
17458         ix86_expand_floorceildf_32 (operand0, operand1, false);
17459     }
17460   else
17461     {
17462       rtx op0 = gen_reg_rtx (XFmode);
17463       rtx op1 = gen_reg_rtx (XFmode);
17464
17465       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17466       emit_insn (gen_frndintxf2_ceil (op0, op1));
17467
17468       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17469     }
17470   DONE;
17471 })
17472
17473 (define_expand "ceilsf2"
17474   [(use (match_operand:SF 0 "register_operand" ""))
17475    (use (match_operand:SF 1 "register_operand" ""))]
17476   "((TARGET_USE_FANCY_MATH_387
17477      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17478      && flag_unsafe_math_optimizations)
17479     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17480         && !flag_trapping_math))
17481    && !optimize_size"
17482 {
17483   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17484       && !flag_trapping_math)
17485     ix86_expand_floorceil (operand0, operand1, false);
17486   else
17487     {
17488       rtx op0 = gen_reg_rtx (XFmode);
17489       rtx op1 = gen_reg_rtx (XFmode);
17490
17491       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17492       emit_insn (gen_frndintxf2_ceil (op0, op1));
17493
17494       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17495     }
17496   DONE;
17497 })
17498
17499 (define_insn_and_split "*fist<mode>2_ceil_1"
17500   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17501         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17502          UNSPEC_FIST_CEIL))
17503    (clobber (reg:CC FLAGS_REG))]
17504   "TARGET_USE_FANCY_MATH_387
17505    && flag_unsafe_math_optimizations
17506    && !(reload_completed || reload_in_progress)"
17507   "#"
17508   "&& 1"
17509   [(const_int 0)]
17510 {
17511   ix86_optimize_mode_switching[I387_CEIL] = 1;
17512
17513   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17514   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17515   if (memory_operand (operands[0], VOIDmode))
17516     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17517                                      operands[2], operands[3]));
17518   else
17519     {
17520       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17521       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17522                                                  operands[2], operands[3],
17523                                                  operands[4]));
17524     }
17525   DONE;
17526 }
17527   [(set_attr "type" "fistp")
17528    (set_attr "i387_cw" "ceil")
17529    (set_attr "mode" "<MODE>")])
17530
17531 (define_insn "fistdi2_ceil"
17532   [(set (match_operand:DI 0 "memory_operand" "=m")
17533         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17534          UNSPEC_FIST_CEIL))
17535    (use (match_operand:HI 2 "memory_operand" "m"))
17536    (use (match_operand:HI 3 "memory_operand" "m"))
17537    (clobber (match_scratch:XF 4 "=&1f"))]
17538   "TARGET_USE_FANCY_MATH_387
17539    && flag_unsafe_math_optimizations"
17540   "* return output_fix_trunc (insn, operands, 0);"
17541   [(set_attr "type" "fistp")
17542    (set_attr "i387_cw" "ceil")
17543    (set_attr "mode" "DI")])
17544
17545 (define_insn "fistdi2_ceil_with_temp"
17546   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17547         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17548          UNSPEC_FIST_CEIL))
17549    (use (match_operand:HI 2 "memory_operand" "m,m"))
17550    (use (match_operand:HI 3 "memory_operand" "m,m"))
17551    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17552    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17553   "TARGET_USE_FANCY_MATH_387
17554    && flag_unsafe_math_optimizations"
17555   "#"
17556   [(set_attr "type" "fistp")
17557    (set_attr "i387_cw" "ceil")
17558    (set_attr "mode" "DI")])
17559
17560 (define_split
17561   [(set (match_operand:DI 0 "register_operand" "")
17562         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17563          UNSPEC_FIST_CEIL))
17564    (use (match_operand:HI 2 "memory_operand" ""))
17565    (use (match_operand:HI 3 "memory_operand" ""))
17566    (clobber (match_operand:DI 4 "memory_operand" ""))
17567    (clobber (match_scratch 5 ""))]
17568   "reload_completed"
17569   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17570               (use (match_dup 2))
17571               (use (match_dup 3))
17572               (clobber (match_dup 5))])
17573    (set (match_dup 0) (match_dup 4))]
17574   "")
17575
17576 (define_split
17577   [(set (match_operand:DI 0 "memory_operand" "")
17578         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17579          UNSPEC_FIST_CEIL))
17580    (use (match_operand:HI 2 "memory_operand" ""))
17581    (use (match_operand:HI 3 "memory_operand" ""))
17582    (clobber (match_operand:DI 4 "memory_operand" ""))
17583    (clobber (match_scratch 5 ""))]
17584   "reload_completed"
17585   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17586               (use (match_dup 2))
17587               (use (match_dup 3))
17588               (clobber (match_dup 5))])]
17589   "")
17590
17591 (define_insn "fist<mode>2_ceil"
17592   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17593         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17594          UNSPEC_FIST_CEIL))
17595    (use (match_operand:HI 2 "memory_operand" "m"))
17596    (use (match_operand:HI 3 "memory_operand" "m"))]
17597   "TARGET_USE_FANCY_MATH_387
17598    && flag_unsafe_math_optimizations"
17599   "* return output_fix_trunc (insn, operands, 0);"
17600   [(set_attr "type" "fistp")
17601    (set_attr "i387_cw" "ceil")
17602    (set_attr "mode" "<MODE>")])
17603
17604 (define_insn "fist<mode>2_ceil_with_temp"
17605   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17606         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17607          UNSPEC_FIST_CEIL))
17608    (use (match_operand:HI 2 "memory_operand" "m,m"))
17609    (use (match_operand:HI 3 "memory_operand" "m,m"))
17610    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17611   "TARGET_USE_FANCY_MATH_387
17612    && flag_unsafe_math_optimizations"
17613   "#"
17614   [(set_attr "type" "fistp")
17615    (set_attr "i387_cw" "ceil")
17616    (set_attr "mode" "<MODE>")])
17617
17618 (define_split
17619   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17620         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17621          UNSPEC_FIST_CEIL))
17622    (use (match_operand:HI 2 "memory_operand" ""))
17623    (use (match_operand:HI 3 "memory_operand" ""))
17624    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17625   "reload_completed"
17626   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17627                                   UNSPEC_FIST_CEIL))
17628               (use (match_dup 2))
17629               (use (match_dup 3))])
17630    (set (match_dup 0) (match_dup 4))]
17631   "")
17632
17633 (define_split
17634   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17635         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17636          UNSPEC_FIST_CEIL))
17637    (use (match_operand:HI 2 "memory_operand" ""))
17638    (use (match_operand:HI 3 "memory_operand" ""))
17639    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17640   "reload_completed"
17641   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17642                                   UNSPEC_FIST_CEIL))
17643               (use (match_dup 2))
17644               (use (match_dup 3))])]
17645   "")
17646
17647 (define_expand "lceilxf<mode>2"
17648   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17649                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17650                     UNSPEC_FIST_CEIL))
17651               (clobber (reg:CC FLAGS_REG))])]
17652   "TARGET_USE_FANCY_MATH_387
17653    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17654    && flag_unsafe_math_optimizations"
17655   "")
17656
17657 (define_expand "lceil<mode>di2"
17658   [(match_operand:DI 0 "nonimmediate_operand" "")
17659    (match_operand:SSEMODEF 1 "register_operand" "")]
17660   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17661    && !flag_trapping_math"
17662 {
17663   ix86_expand_lfloorceil (operand0, operand1, false);
17664   DONE;
17665 })
17666
17667 (define_expand "lceil<mode>si2"
17668   [(match_operand:SI 0 "nonimmediate_operand" "")
17669    (match_operand:SSEMODEF 1 "register_operand" "")]
17670   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17671    && !flag_trapping_math"
17672 {
17673   ix86_expand_lfloorceil (operand0, operand1, false);
17674   DONE;
17675 })
17676
17677 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17678 (define_insn_and_split "frndintxf2_trunc"
17679   [(set (match_operand:XF 0 "register_operand" "=f")
17680         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17681          UNSPEC_FRNDINT_TRUNC))
17682    (clobber (reg:CC FLAGS_REG))]
17683   "TARGET_USE_FANCY_MATH_387
17684    && flag_unsafe_math_optimizations
17685    && !(reload_completed || reload_in_progress)"
17686   "#"
17687   "&& 1"
17688   [(const_int 0)]
17689 {
17690   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17691
17692   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17693   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17694
17695   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17696                                         operands[2], operands[3]));
17697   DONE;
17698 }
17699   [(set_attr "type" "frndint")
17700    (set_attr "i387_cw" "trunc")
17701    (set_attr "mode" "XF")])
17702
17703 (define_insn "frndintxf2_trunc_i387"
17704   [(set (match_operand:XF 0 "register_operand" "=f")
17705         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17706          UNSPEC_FRNDINT_TRUNC))
17707    (use (match_operand:HI 2 "memory_operand" "m"))
17708    (use (match_operand:HI 3 "memory_operand" "m"))]
17709   "TARGET_USE_FANCY_MATH_387
17710    && flag_unsafe_math_optimizations"
17711   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17712   [(set_attr "type" "frndint")
17713    (set_attr "i387_cw" "trunc")
17714    (set_attr "mode" "XF")])
17715
17716 (define_expand "btruncxf2"
17717   [(use (match_operand:XF 0 "register_operand" ""))
17718    (use (match_operand:XF 1 "register_operand" ""))]
17719   "TARGET_USE_FANCY_MATH_387
17720    && flag_unsafe_math_optimizations && !optimize_size"
17721 {
17722   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17723   DONE;
17724 })
17725
17726 (define_expand "btruncdf2"
17727   [(use (match_operand:DF 0 "register_operand" ""))
17728    (use (match_operand:DF 1 "register_operand" ""))]
17729   "((TARGET_USE_FANCY_MATH_387
17730      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17731      && flag_unsafe_math_optimizations)
17732     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17733         && !flag_trapping_math))
17734    && !optimize_size"
17735 {
17736   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17737       && !flag_trapping_math)
17738     {
17739       if (TARGET_64BIT)
17740         ix86_expand_trunc (operand0, operand1);
17741       else
17742         ix86_expand_truncdf_32 (operand0, operand1);
17743     }
17744   else
17745     {
17746       rtx op0 = gen_reg_rtx (XFmode);
17747       rtx op1 = gen_reg_rtx (XFmode);
17748
17749       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17750       emit_insn (gen_frndintxf2_trunc (op0, op1));
17751
17752       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17753     }
17754   DONE;
17755 })
17756
17757 (define_expand "btruncsf2"
17758   [(use (match_operand:SF 0 "register_operand" ""))
17759    (use (match_operand:SF 1 "register_operand" ""))]
17760   "((TARGET_USE_FANCY_MATH_387
17761      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17762      && flag_unsafe_math_optimizations)
17763     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17764         && !flag_trapping_math))
17765    && !optimize_size"
17766 {
17767   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17768       && !flag_trapping_math)
17769     ix86_expand_trunc (operand0, operand1);
17770   else
17771     {
17772       rtx op0 = gen_reg_rtx (XFmode);
17773       rtx op1 = gen_reg_rtx (XFmode);
17774
17775       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17776       emit_insn (gen_frndintxf2_trunc (op0, op1));
17777
17778       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17779     }
17780   DONE;
17781 })
17782
17783 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17784 (define_insn_and_split "frndintxf2_mask_pm"
17785   [(set (match_operand:XF 0 "register_operand" "=f")
17786         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17787          UNSPEC_FRNDINT_MASK_PM))
17788    (clobber (reg:CC FLAGS_REG))]
17789   "TARGET_USE_FANCY_MATH_387
17790    && flag_unsafe_math_optimizations
17791    && !(reload_completed || reload_in_progress)"
17792   "#"
17793   "&& 1"
17794   [(const_int 0)]
17795 {
17796   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17797
17798   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17799   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17800
17801   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17802                                           operands[2], operands[3]));
17803   DONE;
17804 }
17805   [(set_attr "type" "frndint")
17806    (set_attr "i387_cw" "mask_pm")
17807    (set_attr "mode" "XF")])
17808
17809 (define_insn "frndintxf2_mask_pm_i387"
17810   [(set (match_operand:XF 0 "register_operand" "=f")
17811         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17812          UNSPEC_FRNDINT_MASK_PM))
17813    (use (match_operand:HI 2 "memory_operand" "m"))
17814    (use (match_operand:HI 3 "memory_operand" "m"))]
17815   "TARGET_USE_FANCY_MATH_387
17816    && flag_unsafe_math_optimizations"
17817   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17818   [(set_attr "type" "frndint")
17819    (set_attr "i387_cw" "mask_pm")
17820    (set_attr "mode" "XF")])
17821
17822 (define_expand "nearbyintxf2"
17823   [(use (match_operand:XF 0 "register_operand" ""))
17824    (use (match_operand:XF 1 "register_operand" ""))]
17825   "TARGET_USE_FANCY_MATH_387
17826    && flag_unsafe_math_optimizations"
17827 {
17828   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17829
17830   DONE;
17831 })
17832
17833 (define_expand "nearbyintdf2"
17834   [(use (match_operand:DF 0 "register_operand" ""))
17835    (use (match_operand:DF 1 "register_operand" ""))]
17836   "TARGET_USE_FANCY_MATH_387
17837    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17838    && flag_unsafe_math_optimizations"
17839 {
17840   rtx op0 = gen_reg_rtx (XFmode);
17841   rtx op1 = gen_reg_rtx (XFmode);
17842
17843   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17844   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17845
17846   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17847   DONE;
17848 })
17849
17850 (define_expand "nearbyintsf2"
17851   [(use (match_operand:SF 0 "register_operand" ""))
17852    (use (match_operand:SF 1 "register_operand" ""))]
17853   "TARGET_USE_FANCY_MATH_387
17854    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17855    && flag_unsafe_math_optimizations"
17856 {
17857   rtx op0 = gen_reg_rtx (XFmode);
17858   rtx op1 = gen_reg_rtx (XFmode);
17859
17860   emit_insn (gen_extendsfxf2 (op1, operands[1]));
17861   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17862
17863   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17864   DONE;
17865 })
17866
17867 \f
17868 ;; Block operation instructions
17869
17870 (define_expand "movmemsi"
17871   [(use (match_operand:BLK 0 "memory_operand" ""))
17872    (use (match_operand:BLK 1 "memory_operand" ""))
17873    (use (match_operand:SI 2 "nonmemory_operand" ""))
17874    (use (match_operand:SI 3 "const_int_operand" ""))]
17875   ""
17876 {
17877  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17878                          operands[3], constm1_rtx))
17879    DONE;
17880  else
17881    FAIL;
17882 })
17883
17884 (define_expand "movmemdi"
17885   [(use (match_operand:BLK 0 "memory_operand" ""))
17886    (use (match_operand:BLK 1 "memory_operand" ""))
17887    (use (match_operand:DI 2 "nonmemory_operand" ""))
17888    (use (match_operand:DI 3 "const_int_operand" ""))]
17889   "TARGET_64BIT"
17890 {
17891  if (ix86_expand_movmem (operands[0], operands[1], 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 "strmov"
17902   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17903    (set (match_operand 1 "memory_operand" "") (match_dup 4))
17904    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17905               (clobber (reg:CC FLAGS_REG))])
17906    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17907               (clobber (reg:CC FLAGS_REG))])]
17908   ""
17909 {
17910   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17911
17912   /* If .md ever supports :P for Pmode, these can be directly
17913      in the pattern above.  */
17914   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17915   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17916
17917   if (TARGET_SINGLE_STRINGOP || optimize_size)
17918     {
17919       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17920                                       operands[2], operands[3],
17921                                       operands[5], operands[6]));
17922       DONE;
17923     }
17924
17925   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17926 })
17927
17928 (define_expand "strmov_singleop"
17929   [(parallel [(set (match_operand 1 "memory_operand" "")
17930                    (match_operand 3 "memory_operand" ""))
17931               (set (match_operand 0 "register_operand" "")
17932                    (match_operand 4 "" ""))
17933               (set (match_operand 2 "register_operand" "")
17934                    (match_operand 5 "" ""))])]
17935   "TARGET_SINGLE_STRINGOP || optimize_size"
17936   "")
17937
17938 (define_insn "*strmovdi_rex_1"
17939   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17940         (mem:DI (match_operand:DI 3 "register_operand" "1")))
17941    (set (match_operand:DI 0 "register_operand" "=D")
17942         (plus:DI (match_dup 2)
17943                  (const_int 8)))
17944    (set (match_operand:DI 1 "register_operand" "=S")
17945         (plus:DI (match_dup 3)
17946                  (const_int 8)))]
17947   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17948   "movsq"
17949   [(set_attr "type" "str")
17950    (set_attr "mode" "DI")
17951    (set_attr "memory" "both")])
17952
17953 (define_insn "*strmovsi_1"
17954   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17955         (mem:SI (match_operand:SI 3 "register_operand" "1")))
17956    (set (match_operand:SI 0 "register_operand" "=D")
17957         (plus:SI (match_dup 2)
17958                  (const_int 4)))
17959    (set (match_operand:SI 1 "register_operand" "=S")
17960         (plus:SI (match_dup 3)
17961                  (const_int 4)))]
17962   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17963   "{movsl|movsd}"
17964   [(set_attr "type" "str")
17965    (set_attr "mode" "SI")
17966    (set_attr "memory" "both")])
17967
17968 (define_insn "*strmovsi_rex_1"
17969   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17970         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17971    (set (match_operand:DI 0 "register_operand" "=D")
17972         (plus:DI (match_dup 2)
17973                  (const_int 4)))
17974    (set (match_operand:DI 1 "register_operand" "=S")
17975         (plus:DI (match_dup 3)
17976                  (const_int 4)))]
17977   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17978   "{movsl|movsd}"
17979   [(set_attr "type" "str")
17980    (set_attr "mode" "SI")
17981    (set_attr "memory" "both")])
17982
17983 (define_insn "*strmovhi_1"
17984   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17985         (mem:HI (match_operand:SI 3 "register_operand" "1")))
17986    (set (match_operand:SI 0 "register_operand" "=D")
17987         (plus:SI (match_dup 2)
17988                  (const_int 2)))
17989    (set (match_operand:SI 1 "register_operand" "=S")
17990         (plus:SI (match_dup 3)
17991                  (const_int 2)))]
17992   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17993   "movsw"
17994   [(set_attr "type" "str")
17995    (set_attr "memory" "both")
17996    (set_attr "mode" "HI")])
17997
17998 (define_insn "*strmovhi_rex_1"
17999   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18000         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18001    (set (match_operand:DI 0 "register_operand" "=D")
18002         (plus:DI (match_dup 2)
18003                  (const_int 2)))
18004    (set (match_operand:DI 1 "register_operand" "=S")
18005         (plus:DI (match_dup 3)
18006                  (const_int 2)))]
18007   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18008   "movsw"
18009   [(set_attr "type" "str")
18010    (set_attr "memory" "both")
18011    (set_attr "mode" "HI")])
18012
18013 (define_insn "*strmovqi_1"
18014   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18015         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18016    (set (match_operand:SI 0 "register_operand" "=D")
18017         (plus:SI (match_dup 2)
18018                  (const_int 1)))
18019    (set (match_operand:SI 1 "register_operand" "=S")
18020         (plus:SI (match_dup 3)
18021                  (const_int 1)))]
18022   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18023   "movsb"
18024   [(set_attr "type" "str")
18025    (set_attr "memory" "both")
18026    (set_attr "mode" "QI")])
18027
18028 (define_insn "*strmovqi_rex_1"
18029   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18030         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18031    (set (match_operand:DI 0 "register_operand" "=D")
18032         (plus:DI (match_dup 2)
18033                  (const_int 1)))
18034    (set (match_operand:DI 1 "register_operand" "=S")
18035         (plus:DI (match_dup 3)
18036                  (const_int 1)))]
18037   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18038   "movsb"
18039   [(set_attr "type" "str")
18040    (set_attr "memory" "both")
18041    (set_attr "mode" "QI")])
18042
18043 (define_expand "rep_mov"
18044   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18045               (set (match_operand 0 "register_operand" "")
18046                    (match_operand 5 "" ""))
18047               (set (match_operand 2 "register_operand" "")
18048                    (match_operand 6 "" ""))
18049               (set (match_operand 1 "memory_operand" "")
18050                    (match_operand 3 "memory_operand" ""))
18051               (use (match_dup 4))])]
18052   ""
18053   "")
18054
18055 (define_insn "*rep_movdi_rex64"
18056   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18057    (set (match_operand:DI 0 "register_operand" "=D")
18058         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18059                             (const_int 3))
18060                  (match_operand:DI 3 "register_operand" "0")))
18061    (set (match_operand:DI 1 "register_operand" "=S")
18062         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18063                  (match_operand:DI 4 "register_operand" "1")))
18064    (set (mem:BLK (match_dup 3))
18065         (mem:BLK (match_dup 4)))
18066    (use (match_dup 5))]
18067   "TARGET_64BIT"
18068   "{rep\;movsq|rep movsq}"
18069   [(set_attr "type" "str")
18070    (set_attr "prefix_rep" "1")
18071    (set_attr "memory" "both")
18072    (set_attr "mode" "DI")])
18073
18074 (define_insn "*rep_movsi"
18075   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18076    (set (match_operand:SI 0 "register_operand" "=D")
18077         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18078                             (const_int 2))
18079                  (match_operand:SI 3 "register_operand" "0")))
18080    (set (match_operand:SI 1 "register_operand" "=S")
18081         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18082                  (match_operand:SI 4 "register_operand" "1")))
18083    (set (mem:BLK (match_dup 3))
18084         (mem:BLK (match_dup 4)))
18085    (use (match_dup 5))]
18086   "!TARGET_64BIT"
18087   "{rep\;movsl|rep movsd}"
18088   [(set_attr "type" "str")
18089    (set_attr "prefix_rep" "1")
18090    (set_attr "memory" "both")
18091    (set_attr "mode" "SI")])
18092
18093 (define_insn "*rep_movsi_rex64"
18094   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18095    (set (match_operand:DI 0 "register_operand" "=D")
18096         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18097                             (const_int 2))
18098                  (match_operand:DI 3 "register_operand" "0")))
18099    (set (match_operand:DI 1 "register_operand" "=S")
18100         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18101                  (match_operand:DI 4 "register_operand" "1")))
18102    (set (mem:BLK (match_dup 3))
18103         (mem:BLK (match_dup 4)))
18104    (use (match_dup 5))]
18105   "TARGET_64BIT"
18106   "{rep\;movsl|rep movsd}"
18107   [(set_attr "type" "str")
18108    (set_attr "prefix_rep" "1")
18109    (set_attr "memory" "both")
18110    (set_attr "mode" "SI")])
18111
18112 (define_insn "*rep_movqi"
18113   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18114    (set (match_operand:SI 0 "register_operand" "=D")
18115         (plus:SI (match_operand:SI 3 "register_operand" "0")
18116                  (match_operand:SI 5 "register_operand" "2")))
18117    (set (match_operand:SI 1 "register_operand" "=S")
18118         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18119    (set (mem:BLK (match_dup 3))
18120         (mem:BLK (match_dup 4)))
18121    (use (match_dup 5))]
18122   "!TARGET_64BIT"
18123   "{rep\;movsb|rep movsb}"
18124   [(set_attr "type" "str")
18125    (set_attr "prefix_rep" "1")
18126    (set_attr "memory" "both")
18127    (set_attr "mode" "SI")])
18128
18129 (define_insn "*rep_movqi_rex64"
18130   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18131    (set (match_operand:DI 0 "register_operand" "=D")
18132         (plus:DI (match_operand:DI 3 "register_operand" "0")
18133                  (match_operand:DI 5 "register_operand" "2")))
18134    (set (match_operand:DI 1 "register_operand" "=S")
18135         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18136    (set (mem:BLK (match_dup 3))
18137         (mem:BLK (match_dup 4)))
18138    (use (match_dup 5))]
18139   "TARGET_64BIT"
18140   "{rep\;movsb|rep movsb}"
18141   [(set_attr "type" "str")
18142    (set_attr "prefix_rep" "1")
18143    (set_attr "memory" "both")
18144    (set_attr "mode" "SI")])
18145
18146 (define_expand "setmemsi"
18147    [(use (match_operand:BLK 0 "memory_operand" ""))
18148     (use (match_operand:SI 1 "nonmemory_operand" ""))
18149     (use (match_operand 2 "const_int_operand" ""))
18150     (use (match_operand 3 "const_int_operand" ""))]
18151   ""
18152 {
18153  if (ix86_expand_setmem (operands[0], operands[1],
18154                          operands[2], operands[3],
18155                          operands[3], constm1_rtx))
18156    DONE;
18157  else
18158    FAIL;
18159 })
18160
18161 (define_expand "setmemdi"
18162    [(use (match_operand:BLK 0 "memory_operand" ""))
18163     (use (match_operand:DI 1 "nonmemory_operand" ""))
18164     (use (match_operand 2 "const_int_operand" ""))
18165     (use (match_operand 3 "const_int_operand" ""))
18166     (use (match_operand 4 "const_int_operand" ""))
18167     (use (match_operand 5 "const_int_operand" ""))]
18168   "TARGET_64BIT"
18169 {
18170  if (ix86_expand_setmem (operands[0], operands[1],
18171                          operands[2], operands[3],
18172                          operands[3], constm1_rtx))
18173    DONE;
18174  else
18175    FAIL;
18176 })
18177
18178 ;; Most CPUs don't like single string operations
18179 ;; Handle this case here to simplify previous expander.
18180
18181 (define_expand "strset"
18182   [(set (match_operand 1 "memory_operand" "")
18183         (match_operand 2 "register_operand" ""))
18184    (parallel [(set (match_operand 0 "register_operand" "")
18185                    (match_dup 3))
18186               (clobber (reg:CC FLAGS_REG))])]
18187   ""
18188 {
18189   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18190     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18191
18192   /* If .md ever supports :P for Pmode, this can be directly
18193      in the pattern above.  */
18194   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18195                               GEN_INT (GET_MODE_SIZE (GET_MODE
18196                                                       (operands[2]))));
18197   if (TARGET_SINGLE_STRINGOP || optimize_size)
18198     {
18199       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18200                                       operands[3]));
18201       DONE;
18202     }
18203 })
18204
18205 (define_expand "strset_singleop"
18206   [(parallel [(set (match_operand 1 "memory_operand" "")
18207                    (match_operand 2 "register_operand" ""))
18208               (set (match_operand 0 "register_operand" "")
18209                    (match_operand 3 "" ""))])]
18210   "TARGET_SINGLE_STRINGOP || optimize_size"
18211   "")
18212
18213 (define_insn "*strsetdi_rex_1"
18214   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18215         (match_operand:DI 2 "register_operand" "a"))
18216    (set (match_operand:DI 0 "register_operand" "=D")
18217         (plus:DI (match_dup 1)
18218                  (const_int 8)))]
18219   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18220   "stosq"
18221   [(set_attr "type" "str")
18222    (set_attr "memory" "store")
18223    (set_attr "mode" "DI")])
18224
18225 (define_insn "*strsetsi_1"
18226   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18227         (match_operand:SI 2 "register_operand" "a"))
18228    (set (match_operand:SI 0 "register_operand" "=D")
18229         (plus:SI (match_dup 1)
18230                  (const_int 4)))]
18231   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18232   "{stosl|stosd}"
18233   [(set_attr "type" "str")
18234    (set_attr "memory" "store")
18235    (set_attr "mode" "SI")])
18236
18237 (define_insn "*strsetsi_rex_1"
18238   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18239         (match_operand:SI 2 "register_operand" "a"))
18240    (set (match_operand:DI 0 "register_operand" "=D")
18241         (plus:DI (match_dup 1)
18242                  (const_int 4)))]
18243   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18244   "{stosl|stosd}"
18245   [(set_attr "type" "str")
18246    (set_attr "memory" "store")
18247    (set_attr "mode" "SI")])
18248
18249 (define_insn "*strsethi_1"
18250   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18251         (match_operand:HI 2 "register_operand" "a"))
18252    (set (match_operand:SI 0 "register_operand" "=D")
18253         (plus:SI (match_dup 1)
18254                  (const_int 2)))]
18255   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18256   "stosw"
18257   [(set_attr "type" "str")
18258    (set_attr "memory" "store")
18259    (set_attr "mode" "HI")])
18260
18261 (define_insn "*strsethi_rex_1"
18262   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18263         (match_operand:HI 2 "register_operand" "a"))
18264    (set (match_operand:DI 0 "register_operand" "=D")
18265         (plus:DI (match_dup 1)
18266                  (const_int 2)))]
18267   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18268   "stosw"
18269   [(set_attr "type" "str")
18270    (set_attr "memory" "store")
18271    (set_attr "mode" "HI")])
18272
18273 (define_insn "*strsetqi_1"
18274   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18275         (match_operand:QI 2 "register_operand" "a"))
18276    (set (match_operand:SI 0 "register_operand" "=D")
18277         (plus:SI (match_dup 1)
18278                  (const_int 1)))]
18279   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18280   "stosb"
18281   [(set_attr "type" "str")
18282    (set_attr "memory" "store")
18283    (set_attr "mode" "QI")])
18284
18285 (define_insn "*strsetqi_rex_1"
18286   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18287         (match_operand:QI 2 "register_operand" "a"))
18288    (set (match_operand:DI 0 "register_operand" "=D")
18289         (plus:DI (match_dup 1)
18290                  (const_int 1)))]
18291   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18292   "stosb"
18293   [(set_attr "type" "str")
18294    (set_attr "memory" "store")
18295    (set_attr "mode" "QI")])
18296
18297 (define_expand "rep_stos"
18298   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18299               (set (match_operand 0 "register_operand" "")
18300                    (match_operand 4 "" ""))
18301               (set (match_operand 2 "memory_operand" "") (const_int 0))
18302               (use (match_operand 3 "register_operand" ""))
18303               (use (match_dup 1))])]
18304   ""
18305   "")
18306
18307 (define_insn "*rep_stosdi_rex64"
18308   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18309    (set (match_operand:DI 0 "register_operand" "=D")
18310         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18311                             (const_int 3))
18312                  (match_operand:DI 3 "register_operand" "0")))
18313    (set (mem:BLK (match_dup 3))
18314         (const_int 0))
18315    (use (match_operand:DI 2 "register_operand" "a"))
18316    (use (match_dup 4))]
18317   "TARGET_64BIT"
18318   "{rep\;stosq|rep stosq}"
18319   [(set_attr "type" "str")
18320    (set_attr "prefix_rep" "1")
18321    (set_attr "memory" "store")
18322    (set_attr "mode" "DI")])
18323
18324 (define_insn "*rep_stossi"
18325   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18326    (set (match_operand:SI 0 "register_operand" "=D")
18327         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18328                             (const_int 2))
18329                  (match_operand:SI 3 "register_operand" "0")))
18330    (set (mem:BLK (match_dup 3))
18331         (const_int 0))
18332    (use (match_operand:SI 2 "register_operand" "a"))
18333    (use (match_dup 4))]
18334   "!TARGET_64BIT"
18335   "{rep\;stosl|rep stosd}"
18336   [(set_attr "type" "str")
18337    (set_attr "prefix_rep" "1")
18338    (set_attr "memory" "store")
18339    (set_attr "mode" "SI")])
18340
18341 (define_insn "*rep_stossi_rex64"
18342   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18343    (set (match_operand:DI 0 "register_operand" "=D")
18344         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18345                             (const_int 2))
18346                  (match_operand:DI 3 "register_operand" "0")))
18347    (set (mem:BLK (match_dup 3))
18348         (const_int 0))
18349    (use (match_operand:SI 2 "register_operand" "a"))
18350    (use (match_dup 4))]
18351   "TARGET_64BIT"
18352   "{rep\;stosl|rep stosd}"
18353   [(set_attr "type" "str")
18354    (set_attr "prefix_rep" "1")
18355    (set_attr "memory" "store")
18356    (set_attr "mode" "SI")])
18357
18358 (define_insn "*rep_stosqi"
18359   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18360    (set (match_operand:SI 0 "register_operand" "=D")
18361         (plus:SI (match_operand:SI 3 "register_operand" "0")
18362                  (match_operand:SI 4 "register_operand" "1")))
18363    (set (mem:BLK (match_dup 3))
18364         (const_int 0))
18365    (use (match_operand:QI 2 "register_operand" "a"))
18366    (use (match_dup 4))]
18367   "!TARGET_64BIT"
18368   "{rep\;stosb|rep stosb}"
18369   [(set_attr "type" "str")
18370    (set_attr "prefix_rep" "1")
18371    (set_attr "memory" "store")
18372    (set_attr "mode" "QI")])
18373
18374 (define_insn "*rep_stosqi_rex64"
18375   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18376    (set (match_operand:DI 0 "register_operand" "=D")
18377         (plus:DI (match_operand:DI 3 "register_operand" "0")
18378                  (match_operand:DI 4 "register_operand" "1")))
18379    (set (mem:BLK (match_dup 3))
18380         (const_int 0))
18381    (use (match_operand:QI 2 "register_operand" "a"))
18382    (use (match_dup 4))]
18383   "TARGET_64BIT"
18384   "{rep\;stosb|rep stosb}"
18385   [(set_attr "type" "str")
18386    (set_attr "prefix_rep" "1")
18387    (set_attr "memory" "store")
18388    (set_attr "mode" "QI")])
18389
18390 (define_expand "cmpstrnsi"
18391   [(set (match_operand:SI 0 "register_operand" "")
18392         (compare:SI (match_operand:BLK 1 "general_operand" "")
18393                     (match_operand:BLK 2 "general_operand" "")))
18394    (use (match_operand 3 "general_operand" ""))
18395    (use (match_operand 4 "immediate_operand" ""))]
18396   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18397 {
18398   rtx addr1, addr2, out, outlow, count, countreg, align;
18399
18400   /* Can't use this if the user has appropriated esi or edi.  */
18401   if (global_regs[4] || global_regs[5])
18402     FAIL;
18403
18404   out = operands[0];
18405   if (GET_CODE (out) != REG)
18406     out = gen_reg_rtx (SImode);
18407
18408   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18409   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18410   if (addr1 != XEXP (operands[1], 0))
18411     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18412   if (addr2 != XEXP (operands[2], 0))
18413     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18414
18415   count = operands[3];
18416   countreg = ix86_zero_extend_to_Pmode (count);
18417
18418   /* %%% Iff we are testing strict equality, we can use known alignment
18419      to good advantage.  This may be possible with combine, particularly
18420      once cc0 is dead.  */
18421   align = operands[4];
18422
18423   if (GET_CODE (count) == CONST_INT)
18424     {
18425       if (INTVAL (count) == 0)
18426         {
18427           emit_move_insn (operands[0], const0_rtx);
18428           DONE;
18429         }
18430       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18431                                      operands[1], operands[2]));
18432     }
18433   else
18434     {
18435       if (TARGET_64BIT)
18436         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18437       else
18438         emit_insn (gen_cmpsi_1 (countreg, countreg));
18439       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18440                                   operands[1], operands[2]));
18441     }
18442
18443   outlow = gen_lowpart (QImode, out);
18444   emit_insn (gen_cmpintqi (outlow));
18445   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18446
18447   if (operands[0] != out)
18448     emit_move_insn (operands[0], out);
18449
18450   DONE;
18451 })
18452
18453 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18454
18455 (define_expand "cmpintqi"
18456   [(set (match_dup 1)
18457         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18458    (set (match_dup 2)
18459         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18460    (parallel [(set (match_operand:QI 0 "register_operand" "")
18461                    (minus:QI (match_dup 1)
18462                              (match_dup 2)))
18463               (clobber (reg:CC FLAGS_REG))])]
18464   ""
18465   "operands[1] = gen_reg_rtx (QImode);
18466    operands[2] = gen_reg_rtx (QImode);")
18467
18468 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18469 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18470
18471 (define_expand "cmpstrnqi_nz_1"
18472   [(parallel [(set (reg:CC FLAGS_REG)
18473                    (compare:CC (match_operand 4 "memory_operand" "")
18474                                (match_operand 5 "memory_operand" "")))
18475               (use (match_operand 2 "register_operand" ""))
18476               (use (match_operand:SI 3 "immediate_operand" ""))
18477               (clobber (match_operand 0 "register_operand" ""))
18478               (clobber (match_operand 1 "register_operand" ""))
18479               (clobber (match_dup 2))])]
18480   ""
18481   "")
18482
18483 (define_insn "*cmpstrnqi_nz_1"
18484   [(set (reg:CC FLAGS_REG)
18485         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18486                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18487    (use (match_operand:SI 6 "register_operand" "2"))
18488    (use (match_operand:SI 3 "immediate_operand" "i"))
18489    (clobber (match_operand:SI 0 "register_operand" "=S"))
18490    (clobber (match_operand:SI 1 "register_operand" "=D"))
18491    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18492   "!TARGET_64BIT"
18493   "repz{\;| }cmpsb"
18494   [(set_attr "type" "str")
18495    (set_attr "mode" "QI")
18496    (set_attr "prefix_rep" "1")])
18497
18498 (define_insn "*cmpstrnqi_nz_rex_1"
18499   [(set (reg:CC FLAGS_REG)
18500         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18501                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18502    (use (match_operand:DI 6 "register_operand" "2"))
18503    (use (match_operand:SI 3 "immediate_operand" "i"))
18504    (clobber (match_operand:DI 0 "register_operand" "=S"))
18505    (clobber (match_operand:DI 1 "register_operand" "=D"))
18506    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18507   "TARGET_64BIT"
18508   "repz{\;| }cmpsb"
18509   [(set_attr "type" "str")
18510    (set_attr "mode" "QI")
18511    (set_attr "prefix_rep" "1")])
18512
18513 ;; The same, but the count is not known to not be zero.
18514
18515 (define_expand "cmpstrnqi_1"
18516   [(parallel [(set (reg:CC FLAGS_REG)
18517                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18518                                      (const_int 0))
18519                   (compare:CC (match_operand 4 "memory_operand" "")
18520                               (match_operand 5 "memory_operand" ""))
18521                   (const_int 0)))
18522               (use (match_operand:SI 3 "immediate_operand" ""))
18523               (use (reg:CC FLAGS_REG))
18524               (clobber (match_operand 0 "register_operand" ""))
18525               (clobber (match_operand 1 "register_operand" ""))
18526               (clobber (match_dup 2))])]
18527   ""
18528   "")
18529
18530 (define_insn "*cmpstrnqi_1"
18531   [(set (reg:CC FLAGS_REG)
18532         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18533                              (const_int 0))
18534           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18535                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18536           (const_int 0)))
18537    (use (match_operand:SI 3 "immediate_operand" "i"))
18538    (use (reg:CC FLAGS_REG))
18539    (clobber (match_operand:SI 0 "register_operand" "=S"))
18540    (clobber (match_operand:SI 1 "register_operand" "=D"))
18541    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18542   "!TARGET_64BIT"
18543   "repz{\;| }cmpsb"
18544   [(set_attr "type" "str")
18545    (set_attr "mode" "QI")
18546    (set_attr "prefix_rep" "1")])
18547
18548 (define_insn "*cmpstrnqi_rex_1"
18549   [(set (reg:CC FLAGS_REG)
18550         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18551                              (const_int 0))
18552           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18553                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18554           (const_int 0)))
18555    (use (match_operand:SI 3 "immediate_operand" "i"))
18556    (use (reg:CC FLAGS_REG))
18557    (clobber (match_operand:DI 0 "register_operand" "=S"))
18558    (clobber (match_operand:DI 1 "register_operand" "=D"))
18559    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18560   "TARGET_64BIT"
18561   "repz{\;| }cmpsb"
18562   [(set_attr "type" "str")
18563    (set_attr "mode" "QI")
18564    (set_attr "prefix_rep" "1")])
18565
18566 (define_expand "strlensi"
18567   [(set (match_operand:SI 0 "register_operand" "")
18568         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18569                     (match_operand:QI 2 "immediate_operand" "")
18570                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18571   ""
18572 {
18573  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18574    DONE;
18575  else
18576    FAIL;
18577 })
18578
18579 (define_expand "strlendi"
18580   [(set (match_operand:DI 0 "register_operand" "")
18581         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18582                     (match_operand:QI 2 "immediate_operand" "")
18583                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18584   ""
18585 {
18586  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18587    DONE;
18588  else
18589    FAIL;
18590 })
18591
18592 (define_expand "strlenqi_1"
18593   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18594               (clobber (match_operand 1 "register_operand" ""))
18595               (clobber (reg:CC FLAGS_REG))])]
18596   ""
18597   "")
18598
18599 (define_insn "*strlenqi_1"
18600   [(set (match_operand:SI 0 "register_operand" "=&c")
18601         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18602                     (match_operand:QI 2 "register_operand" "a")
18603                     (match_operand:SI 3 "immediate_operand" "i")
18604                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18605    (clobber (match_operand:SI 1 "register_operand" "=D"))
18606    (clobber (reg:CC FLAGS_REG))]
18607   "!TARGET_64BIT"
18608   "repnz{\;| }scasb"
18609   [(set_attr "type" "str")
18610    (set_attr "mode" "QI")
18611    (set_attr "prefix_rep" "1")])
18612
18613 (define_insn "*strlenqi_rex_1"
18614   [(set (match_operand:DI 0 "register_operand" "=&c")
18615         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18616                     (match_operand:QI 2 "register_operand" "a")
18617                     (match_operand:DI 3 "immediate_operand" "i")
18618                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18619    (clobber (match_operand:DI 1 "register_operand" "=D"))
18620    (clobber (reg:CC FLAGS_REG))]
18621   "TARGET_64BIT"
18622   "repnz{\;| }scasb"
18623   [(set_attr "type" "str")
18624    (set_attr "mode" "QI")
18625    (set_attr "prefix_rep" "1")])
18626
18627 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18628 ;; handled in combine, but it is not currently up to the task.
18629 ;; When used for their truth value, the cmpstrn* expanders generate
18630 ;; code like this:
18631 ;;
18632 ;;   repz cmpsb
18633 ;;   seta       %al
18634 ;;   setb       %dl
18635 ;;   cmpb       %al, %dl
18636 ;;   jcc        label
18637 ;;
18638 ;; The intermediate three instructions are unnecessary.
18639
18640 ;; This one handles cmpstrn*_nz_1...
18641 (define_peephole2
18642   [(parallel[
18643      (set (reg:CC FLAGS_REG)
18644           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18645                       (mem:BLK (match_operand 5 "register_operand" ""))))
18646      (use (match_operand 6 "register_operand" ""))
18647      (use (match_operand:SI 3 "immediate_operand" ""))
18648      (clobber (match_operand 0 "register_operand" ""))
18649      (clobber (match_operand 1 "register_operand" ""))
18650      (clobber (match_operand 2 "register_operand" ""))])
18651    (set (match_operand:QI 7 "register_operand" "")
18652         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18653    (set (match_operand:QI 8 "register_operand" "")
18654         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18655    (set (reg FLAGS_REG)
18656         (compare (match_dup 7) (match_dup 8)))
18657   ]
18658   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18659   [(parallel[
18660      (set (reg:CC FLAGS_REG)
18661           (compare:CC (mem:BLK (match_dup 4))
18662                       (mem:BLK (match_dup 5))))
18663      (use (match_dup 6))
18664      (use (match_dup 3))
18665      (clobber (match_dup 0))
18666      (clobber (match_dup 1))
18667      (clobber (match_dup 2))])]
18668   "")
18669
18670 ;; ...and this one handles cmpstrn*_1.
18671 (define_peephole2
18672   [(parallel[
18673      (set (reg:CC FLAGS_REG)
18674           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18675                                (const_int 0))
18676             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18677                         (mem:BLK (match_operand 5 "register_operand" "")))
18678             (const_int 0)))
18679      (use (match_operand:SI 3 "immediate_operand" ""))
18680      (use (reg:CC FLAGS_REG))
18681      (clobber (match_operand 0 "register_operand" ""))
18682      (clobber (match_operand 1 "register_operand" ""))
18683      (clobber (match_operand 2 "register_operand" ""))])
18684    (set (match_operand:QI 7 "register_operand" "")
18685         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18686    (set (match_operand:QI 8 "register_operand" "")
18687         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18688    (set (reg FLAGS_REG)
18689         (compare (match_dup 7) (match_dup 8)))
18690   ]
18691   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18692   [(parallel[
18693      (set (reg:CC FLAGS_REG)
18694           (if_then_else:CC (ne (match_dup 6)
18695                                (const_int 0))
18696             (compare:CC (mem:BLK (match_dup 4))
18697                         (mem:BLK (match_dup 5)))
18698             (const_int 0)))
18699      (use (match_dup 3))
18700      (use (reg:CC FLAGS_REG))
18701      (clobber (match_dup 0))
18702      (clobber (match_dup 1))
18703      (clobber (match_dup 2))])]
18704   "")
18705
18706
18707 \f
18708 ;; Conditional move instructions.
18709
18710 (define_expand "movdicc"
18711   [(set (match_operand:DI 0 "register_operand" "")
18712         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18713                          (match_operand:DI 2 "general_operand" "")
18714                          (match_operand:DI 3 "general_operand" "")))]
18715   "TARGET_64BIT"
18716   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18717
18718 (define_insn "x86_movdicc_0_m1_rex64"
18719   [(set (match_operand:DI 0 "register_operand" "=r")
18720         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18721           (const_int -1)
18722           (const_int 0)))
18723    (clobber (reg:CC FLAGS_REG))]
18724   "TARGET_64BIT"
18725   "sbb{q}\t%0, %0"
18726   ; Since we don't have the proper number of operands for an alu insn,
18727   ; fill in all the blanks.
18728   [(set_attr "type" "alu")
18729    (set_attr "pent_pair" "pu")
18730    (set_attr "memory" "none")
18731    (set_attr "imm_disp" "false")
18732    (set_attr "mode" "DI")
18733    (set_attr "length_immediate" "0")])
18734
18735 (define_insn "*movdicc_c_rex64"
18736   [(set (match_operand:DI 0 "register_operand" "=r,r")
18737         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18738                                 [(reg FLAGS_REG) (const_int 0)])
18739                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18740                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18741   "TARGET_64BIT && TARGET_CMOVE
18742    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18743   "@
18744    cmov%O2%C1\t{%2, %0|%0, %2}
18745    cmov%O2%c1\t{%3, %0|%0, %3}"
18746   [(set_attr "type" "icmov")
18747    (set_attr "mode" "DI")])
18748
18749 (define_expand "movsicc"
18750   [(set (match_operand:SI 0 "register_operand" "")
18751         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18752                          (match_operand:SI 2 "general_operand" "")
18753                          (match_operand:SI 3 "general_operand" "")))]
18754   ""
18755   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18756
18757 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18758 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18759 ;; So just document what we're doing explicitly.
18760
18761 (define_insn "x86_movsicc_0_m1"
18762   [(set (match_operand:SI 0 "register_operand" "=r")
18763         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18764           (const_int -1)
18765           (const_int 0)))
18766    (clobber (reg:CC FLAGS_REG))]
18767   ""
18768   "sbb{l}\t%0, %0"
18769   ; Since we don't have the proper number of operands for an alu insn,
18770   ; fill in all the blanks.
18771   [(set_attr "type" "alu")
18772    (set_attr "pent_pair" "pu")
18773    (set_attr "memory" "none")
18774    (set_attr "imm_disp" "false")
18775    (set_attr "mode" "SI")
18776    (set_attr "length_immediate" "0")])
18777
18778 (define_insn "*movsicc_noc"
18779   [(set (match_operand:SI 0 "register_operand" "=r,r")
18780         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18781                                 [(reg FLAGS_REG) (const_int 0)])
18782                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18783                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18784   "TARGET_CMOVE
18785    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18786   "@
18787    cmov%O2%C1\t{%2, %0|%0, %2}
18788    cmov%O2%c1\t{%3, %0|%0, %3}"
18789   [(set_attr "type" "icmov")
18790    (set_attr "mode" "SI")])
18791
18792 (define_expand "movhicc"
18793   [(set (match_operand:HI 0 "register_operand" "")
18794         (if_then_else:HI (match_operand 1 "comparison_operator" "")
18795                          (match_operand:HI 2 "general_operand" "")
18796                          (match_operand:HI 3 "general_operand" "")))]
18797   "TARGET_HIMODE_MATH"
18798   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18799
18800 (define_insn "*movhicc_noc"
18801   [(set (match_operand:HI 0 "register_operand" "=r,r")
18802         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18803                                 [(reg FLAGS_REG) (const_int 0)])
18804                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18805                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18806   "TARGET_CMOVE
18807    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18808   "@
18809    cmov%O2%C1\t{%2, %0|%0, %2}
18810    cmov%O2%c1\t{%3, %0|%0, %3}"
18811   [(set_attr "type" "icmov")
18812    (set_attr "mode" "HI")])
18813
18814 (define_expand "movqicc"
18815   [(set (match_operand:QI 0 "register_operand" "")
18816         (if_then_else:QI (match_operand 1 "comparison_operator" "")
18817                          (match_operand:QI 2 "general_operand" "")
18818                          (match_operand:QI 3 "general_operand" "")))]
18819   "TARGET_QIMODE_MATH"
18820   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18821
18822 (define_insn_and_split "*movqicc_noc"
18823   [(set (match_operand:QI 0 "register_operand" "=r,r")
18824         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18825                                 [(match_operand 4 "flags_reg_operand" "")
18826                                  (const_int 0)])
18827                       (match_operand:QI 2 "register_operand" "r,0")
18828                       (match_operand:QI 3 "register_operand" "0,r")))]
18829   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18830   "#"
18831   "&& reload_completed"
18832   [(set (match_dup 0)
18833         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18834                       (match_dup 2)
18835                       (match_dup 3)))]
18836   "operands[0] = gen_lowpart (SImode, operands[0]);
18837    operands[2] = gen_lowpart (SImode, operands[2]);
18838    operands[3] = gen_lowpart (SImode, operands[3]);"
18839   [(set_attr "type" "icmov")
18840    (set_attr "mode" "SI")])
18841
18842 (define_expand "movsfcc"
18843   [(set (match_operand:SF 0 "register_operand" "")
18844         (if_then_else:SF (match_operand 1 "comparison_operator" "")
18845                          (match_operand:SF 2 "register_operand" "")
18846                          (match_operand:SF 3 "register_operand" "")))]
18847   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18848   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18849
18850 (define_insn "*movsfcc_1_387"
18851   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18852         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18853                                 [(reg FLAGS_REG) (const_int 0)])
18854                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18855                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18856   "TARGET_80387 && TARGET_CMOVE
18857    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18858   "@
18859    fcmov%F1\t{%2, %0|%0, %2}
18860    fcmov%f1\t{%3, %0|%0, %3}
18861    cmov%O2%C1\t{%2, %0|%0, %2}
18862    cmov%O2%c1\t{%3, %0|%0, %3}"
18863   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18864    (set_attr "mode" "SF,SF,SI,SI")])
18865
18866 (define_expand "movdfcc"
18867   [(set (match_operand:DF 0 "register_operand" "")
18868         (if_then_else:DF (match_operand 1 "comparison_operator" "")
18869                          (match_operand:DF 2 "register_operand" "")
18870                          (match_operand:DF 3 "register_operand" "")))]
18871   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18872   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18873
18874 (define_insn "*movdfcc_1"
18875   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
18876         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18877                                 [(reg FLAGS_REG) (const_int 0)])
18878                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18879                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18880   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18881    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18882   "@
18883    fcmov%F1\t{%2, %0|%0, %2}
18884    fcmov%f1\t{%3, %0|%0, %3}
18885    #
18886    #"
18887   [(set_attr "type" "fcmov,fcmov,multi,multi")
18888    (set_attr "mode" "DF")])
18889
18890 (define_insn "*movdfcc_1_rex64"
18891   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
18892         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18893                                 [(reg FLAGS_REG) (const_int 0)])
18894                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18895                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18896   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18897    && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18898   "@
18899    fcmov%F1\t{%2, %0|%0, %2}
18900    fcmov%f1\t{%3, %0|%0, %3}
18901    cmov%O2%C1\t{%2, %0|%0, %2}
18902    cmov%O2%c1\t{%3, %0|%0, %3}"
18903   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18904    (set_attr "mode" "DF")])
18905
18906 (define_split
18907   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18908         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18909                                 [(match_operand 4 "flags_reg_operand" "")
18910                                  (const_int 0)])
18911                       (match_operand:DF 2 "nonimmediate_operand" "")
18912                       (match_operand:DF 3 "nonimmediate_operand" "")))]
18913   "!TARGET_64BIT && reload_completed"
18914   [(set (match_dup 2)
18915         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18916                       (match_dup 5)
18917                       (match_dup 7)))
18918    (set (match_dup 3)
18919         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18920                       (match_dup 6)
18921                       (match_dup 8)))]
18922   "split_di (operands+2, 1, operands+5, operands+6);
18923    split_di (operands+3, 1, operands+7, operands+8);
18924    split_di (operands, 1, operands+2, operands+3);")
18925
18926 (define_expand "movxfcc"
18927   [(set (match_operand:XF 0 "register_operand" "")
18928         (if_then_else:XF (match_operand 1 "comparison_operator" "")
18929                          (match_operand:XF 2 "register_operand" "")
18930                          (match_operand:XF 3 "register_operand" "")))]
18931   "TARGET_80387 && TARGET_CMOVE"
18932   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18933
18934 (define_insn "*movxfcc_1"
18935   [(set (match_operand:XF 0 "register_operand" "=f,f")
18936         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18937                                 [(reg FLAGS_REG) (const_int 0)])
18938                       (match_operand:XF 2 "register_operand" "f,0")
18939                       (match_operand:XF 3 "register_operand" "0,f")))]
18940   "TARGET_80387 && TARGET_CMOVE"
18941   "@
18942    fcmov%F1\t{%2, %0|%0, %2}
18943    fcmov%f1\t{%3, %0|%0, %3}"
18944   [(set_attr "type" "fcmov")
18945    (set_attr "mode" "XF")])
18946
18947 ;; These versions of the min/max patterns are intentionally ignorant of
18948 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18949 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18950 ;; are undefined in this condition, we're certain this is correct.
18951
18952 (define_insn "sminsf3"
18953   [(set (match_operand:SF 0 "register_operand" "=x")
18954         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18955                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18956   "TARGET_SSE_MATH"
18957   "minss\t{%2, %0|%0, %2}"
18958   [(set_attr "type" "sseadd")
18959    (set_attr "mode" "SF")])
18960
18961 (define_insn "smaxsf3"
18962   [(set (match_operand:SF 0 "register_operand" "=x")
18963         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18964                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18965   "TARGET_SSE_MATH"
18966   "maxss\t{%2, %0|%0, %2}"
18967   [(set_attr "type" "sseadd")
18968    (set_attr "mode" "SF")])
18969
18970 (define_insn "smindf3"
18971   [(set (match_operand:DF 0 "register_operand" "=x")
18972         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18973                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18974   "TARGET_SSE2 && TARGET_SSE_MATH"
18975   "minsd\t{%2, %0|%0, %2}"
18976   [(set_attr "type" "sseadd")
18977    (set_attr "mode" "DF")])
18978
18979 (define_insn "smaxdf3"
18980   [(set (match_operand:DF 0 "register_operand" "=x")
18981         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18982                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18983   "TARGET_SSE2 && TARGET_SSE_MATH"
18984   "maxsd\t{%2, %0|%0, %2}"
18985   [(set_attr "type" "sseadd")
18986    (set_attr "mode" "DF")])
18987
18988 ;; These versions of the min/max patterns implement exactly the operations
18989 ;;   min = (op1 < op2 ? op1 : op2)
18990 ;;   max = (!(op1 < op2) ? op1 : op2)
18991 ;; Their operands are not commutative, and thus they may be used in the
18992 ;; presence of -0.0 and NaN.
18993
18994 (define_insn "*ieee_sminsf3"
18995   [(set (match_operand:SF 0 "register_operand" "=x")
18996         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18997                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
18998                    UNSPEC_IEEE_MIN))]
18999   "TARGET_SSE_MATH"
19000   "minss\t{%2, %0|%0, %2}"
19001   [(set_attr "type" "sseadd")
19002    (set_attr "mode" "SF")])
19003
19004 (define_insn "*ieee_smaxsf3"
19005   [(set (match_operand:SF 0 "register_operand" "=x")
19006         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19007                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19008                    UNSPEC_IEEE_MAX))]
19009   "TARGET_SSE_MATH"
19010   "maxss\t{%2, %0|%0, %2}"
19011   [(set_attr "type" "sseadd")
19012    (set_attr "mode" "SF")])
19013
19014 (define_insn "*ieee_smindf3"
19015   [(set (match_operand:DF 0 "register_operand" "=x")
19016         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19017                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19018                    UNSPEC_IEEE_MIN))]
19019   "TARGET_SSE2 && TARGET_SSE_MATH"
19020   "minsd\t{%2, %0|%0, %2}"
19021   [(set_attr "type" "sseadd")
19022    (set_attr "mode" "DF")])
19023
19024 (define_insn "*ieee_smaxdf3"
19025   [(set (match_operand:DF 0 "register_operand" "=x")
19026         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19027                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19028                    UNSPEC_IEEE_MAX))]
19029   "TARGET_SSE2 && TARGET_SSE_MATH"
19030   "maxsd\t{%2, %0|%0, %2}"
19031   [(set_attr "type" "sseadd")
19032    (set_attr "mode" "DF")])
19033
19034 ;; Make two stack loads independent:
19035 ;;   fld aa              fld aa
19036 ;;   fld %st(0)     ->   fld bb
19037 ;;   fmul bb             fmul %st(1), %st
19038 ;;
19039 ;; Actually we only match the last two instructions for simplicity.
19040 (define_peephole2
19041   [(set (match_operand 0 "fp_register_operand" "")
19042         (match_operand 1 "fp_register_operand" ""))
19043    (set (match_dup 0)
19044         (match_operator 2 "binary_fp_operator"
19045            [(match_dup 0)
19046             (match_operand 3 "memory_operand" "")]))]
19047   "REGNO (operands[0]) != REGNO (operands[1])"
19048   [(set (match_dup 0) (match_dup 3))
19049    (set (match_dup 0) (match_dup 4))]
19050
19051   ;; The % modifier is not operational anymore in peephole2's, so we have to
19052   ;; swap the operands manually in the case of addition and multiplication.
19053   "if (COMMUTATIVE_ARITH_P (operands[2]))
19054      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19055                                  operands[0], operands[1]);
19056    else
19057      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19058                                  operands[1], operands[0]);")
19059
19060 ;; Conditional addition patterns
19061 (define_expand "addqicc"
19062   [(match_operand:QI 0 "register_operand" "")
19063    (match_operand 1 "comparison_operator" "")
19064    (match_operand:QI 2 "register_operand" "")
19065    (match_operand:QI 3 "const_int_operand" "")]
19066   ""
19067   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19068
19069 (define_expand "addhicc"
19070   [(match_operand:HI 0 "register_operand" "")
19071    (match_operand 1 "comparison_operator" "")
19072    (match_operand:HI 2 "register_operand" "")
19073    (match_operand:HI 3 "const_int_operand" "")]
19074   ""
19075   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19076
19077 (define_expand "addsicc"
19078   [(match_operand:SI 0 "register_operand" "")
19079    (match_operand 1 "comparison_operator" "")
19080    (match_operand:SI 2 "register_operand" "")
19081    (match_operand:SI 3 "const_int_operand" "")]
19082   ""
19083   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19084
19085 (define_expand "adddicc"
19086   [(match_operand:DI 0 "register_operand" "")
19087    (match_operand 1 "comparison_operator" "")
19088    (match_operand:DI 2 "register_operand" "")
19089    (match_operand:DI 3 "const_int_operand" "")]
19090   "TARGET_64BIT"
19091   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19092
19093 \f
19094 ;; Misc patterns (?)
19095
19096 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19097 ;; Otherwise there will be nothing to keep
19098 ;;
19099 ;; [(set (reg ebp) (reg esp))]
19100 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19101 ;;  (clobber (eflags)]
19102 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19103 ;;
19104 ;; in proper program order.
19105 (define_insn "pro_epilogue_adjust_stack_1"
19106   [(set (match_operand:SI 0 "register_operand" "=r,r")
19107         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19108                  (match_operand:SI 2 "immediate_operand" "i,i")))
19109    (clobber (reg:CC FLAGS_REG))
19110    (clobber (mem:BLK (scratch)))]
19111   "!TARGET_64BIT"
19112 {
19113   switch (get_attr_type (insn))
19114     {
19115     case TYPE_IMOV:
19116       return "mov{l}\t{%1, %0|%0, %1}";
19117
19118     case TYPE_ALU:
19119       if (GET_CODE (operands[2]) == CONST_INT
19120           && (INTVAL (operands[2]) == 128
19121               || (INTVAL (operands[2]) < 0
19122                   && INTVAL (operands[2]) != -128)))
19123         {
19124           operands[2] = GEN_INT (-INTVAL (operands[2]));
19125           return "sub{l}\t{%2, %0|%0, %2}";
19126         }
19127       return "add{l}\t{%2, %0|%0, %2}";
19128
19129     case TYPE_LEA:
19130       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19131       return "lea{l}\t{%a2, %0|%0, %a2}";
19132
19133     default:
19134       gcc_unreachable ();
19135     }
19136 }
19137   [(set (attr "type")
19138         (cond [(eq_attr "alternative" "0")
19139                  (const_string "alu")
19140                (match_operand:SI 2 "const0_operand" "")
19141                  (const_string "imov")
19142               ]
19143               (const_string "lea")))
19144    (set_attr "mode" "SI")])
19145
19146 (define_insn "pro_epilogue_adjust_stack_rex64"
19147   [(set (match_operand:DI 0 "register_operand" "=r,r")
19148         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19149                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19150    (clobber (reg:CC FLAGS_REG))
19151    (clobber (mem:BLK (scratch)))]
19152   "TARGET_64BIT"
19153 {
19154   switch (get_attr_type (insn))
19155     {
19156     case TYPE_IMOV:
19157       return "mov{q}\t{%1, %0|%0, %1}";
19158
19159     case TYPE_ALU:
19160       if (GET_CODE (operands[2]) == CONST_INT
19161           /* Avoid overflows.  */
19162           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19163           && (INTVAL (operands[2]) == 128
19164               || (INTVAL (operands[2]) < 0
19165                   && INTVAL (operands[2]) != -128)))
19166         {
19167           operands[2] = GEN_INT (-INTVAL (operands[2]));
19168           return "sub{q}\t{%2, %0|%0, %2}";
19169         }
19170       return "add{q}\t{%2, %0|%0, %2}";
19171
19172     case TYPE_LEA:
19173       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19174       return "lea{q}\t{%a2, %0|%0, %a2}";
19175
19176     default:
19177       gcc_unreachable ();
19178     }
19179 }
19180   [(set (attr "type")
19181         (cond [(eq_attr "alternative" "0")
19182                  (const_string "alu")
19183                (match_operand:DI 2 "const0_operand" "")
19184                  (const_string "imov")
19185               ]
19186               (const_string "lea")))
19187    (set_attr "mode" "DI")])
19188
19189 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19190   [(set (match_operand:DI 0 "register_operand" "=r,r")
19191         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19192                  (match_operand:DI 3 "immediate_operand" "i,i")))
19193    (use (match_operand:DI 2 "register_operand" "r,r"))
19194    (clobber (reg:CC FLAGS_REG))
19195    (clobber (mem:BLK (scratch)))]
19196   "TARGET_64BIT"
19197 {
19198   switch (get_attr_type (insn))
19199     {
19200     case TYPE_ALU:
19201       return "add{q}\t{%2, %0|%0, %2}";
19202
19203     case TYPE_LEA:
19204       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19205       return "lea{q}\t{%a2, %0|%0, %a2}";
19206
19207     default:
19208       gcc_unreachable ();
19209     }
19210 }
19211   [(set_attr "type" "alu,lea")
19212    (set_attr "mode" "DI")])
19213
19214 (define_expand "allocate_stack_worker"
19215   [(match_operand:SI 0 "register_operand" "")]
19216   "TARGET_STACK_PROBE"
19217 {
19218   if (reload_completed)
19219     {
19220       if (TARGET_64BIT)
19221         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19222       else
19223         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19224     }
19225   else
19226     {
19227       if (TARGET_64BIT)
19228         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19229       else
19230         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19231     }
19232   DONE;
19233 })
19234
19235 (define_insn "allocate_stack_worker_1"
19236   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19237     UNSPECV_STACK_PROBE)
19238    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19239    (clobber (match_scratch:SI 1 "=0"))
19240    (clobber (reg:CC FLAGS_REG))]
19241   "!TARGET_64BIT && TARGET_STACK_PROBE"
19242   "call\t__alloca"
19243   [(set_attr "type" "multi")
19244    (set_attr "length" "5")])
19245
19246 (define_expand "allocate_stack_worker_postreload"
19247   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19248                                     UNSPECV_STACK_PROBE)
19249               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19250               (clobber (match_dup 0))
19251               (clobber (reg:CC FLAGS_REG))])]
19252   ""
19253   "")
19254
19255 (define_insn "allocate_stack_worker_rex64"
19256   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19257     UNSPECV_STACK_PROBE)
19258    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19259    (clobber (match_scratch:DI 1 "=0"))
19260    (clobber (reg:CC FLAGS_REG))]
19261   "TARGET_64BIT && TARGET_STACK_PROBE"
19262   "call\t__alloca"
19263   [(set_attr "type" "multi")
19264    (set_attr "length" "5")])
19265
19266 (define_expand "allocate_stack_worker_rex64_postreload"
19267   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19268                                     UNSPECV_STACK_PROBE)
19269               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19270               (clobber (match_dup 0))
19271               (clobber (reg:CC FLAGS_REG))])]
19272   ""
19273   "")
19274
19275 (define_expand "allocate_stack"
19276   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19277                    (minus:SI (reg:SI SP_REG)
19278                              (match_operand:SI 1 "general_operand" "")))
19279               (clobber (reg:CC FLAGS_REG))])
19280    (parallel [(set (reg:SI SP_REG)
19281                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
19282               (clobber (reg:CC FLAGS_REG))])]
19283   "TARGET_STACK_PROBE"
19284 {
19285 #ifdef CHECK_STACK_LIMIT
19286   if (GET_CODE (operands[1]) == CONST_INT
19287       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19288     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19289                            operands[1]));
19290   else
19291 #endif
19292     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19293                                                             operands[1])));
19294
19295   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19296   DONE;
19297 })
19298
19299 (define_expand "builtin_setjmp_receiver"
19300   [(label_ref (match_operand 0 "" ""))]
19301   "!TARGET_64BIT && flag_pic"
19302 {
19303   if (TARGET_MACHO)
19304     {
19305       rtx xops[3];
19306       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19307       rtx label_rtx = gen_label_rtx ();
19308       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19309       xops[0] = xops[1] = picreg;
19310       xops[2] = gen_rtx_CONST (SImode,
19311                   gen_rtx_MINUS (SImode,
19312                     gen_rtx_LABEL_REF (SImode, label_rtx),
19313                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19314       ix86_expand_binary_operator (MINUS, SImode, xops);
19315     }
19316   else
19317     emit_insn (gen_set_got (pic_offset_table_rtx));
19318   DONE;
19319 })
19320 \f
19321 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19322
19323 (define_split
19324   [(set (match_operand 0 "register_operand" "")
19325         (match_operator 3 "promotable_binary_operator"
19326            [(match_operand 1 "register_operand" "")
19327             (match_operand 2 "aligned_operand" "")]))
19328    (clobber (reg:CC FLAGS_REG))]
19329   "! TARGET_PARTIAL_REG_STALL && reload_completed
19330    && ((GET_MODE (operands[0]) == HImode
19331         && ((!optimize_size && !TARGET_FAST_PREFIX)
19332             /* ??? next two lines just !satisfies_constraint_K (...) */
19333             || GET_CODE (operands[2]) != CONST_INT
19334             || satisfies_constraint_K (operands[2])))
19335        || (GET_MODE (operands[0]) == QImode
19336            && (TARGET_PROMOTE_QImode || optimize_size)))"
19337   [(parallel [(set (match_dup 0)
19338                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19339               (clobber (reg:CC FLAGS_REG))])]
19340   "operands[0] = gen_lowpart (SImode, operands[0]);
19341    operands[1] = gen_lowpart (SImode, operands[1]);
19342    if (GET_CODE (operands[3]) != ASHIFT)
19343      operands[2] = gen_lowpart (SImode, operands[2]);
19344    PUT_MODE (operands[3], SImode);")
19345
19346 ; Promote the QImode tests, as i386 has encoding of the AND
19347 ; instruction with 32-bit sign-extended immediate and thus the
19348 ; instruction size is unchanged, except in the %eax case for
19349 ; which it is increased by one byte, hence the ! optimize_size.
19350 (define_split
19351   [(set (match_operand 0 "flags_reg_operand" "")
19352         (match_operator 2 "compare_operator"
19353           [(and (match_operand 3 "aligned_operand" "")
19354                 (match_operand 4 "const_int_operand" ""))
19355            (const_int 0)]))
19356    (set (match_operand 1 "register_operand" "")
19357         (and (match_dup 3) (match_dup 4)))]
19358   "! TARGET_PARTIAL_REG_STALL && reload_completed
19359    /* Ensure that the operand will remain sign-extended immediate.  */
19360    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19361    && ! optimize_size
19362    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19363        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19364   [(parallel [(set (match_dup 0)
19365                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19366                                     (const_int 0)]))
19367               (set (match_dup 1)
19368                    (and:SI (match_dup 3) (match_dup 4)))])]
19369 {
19370   operands[4]
19371     = gen_int_mode (INTVAL (operands[4])
19372                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19373   operands[1] = gen_lowpart (SImode, operands[1]);
19374   operands[3] = gen_lowpart (SImode, operands[3]);
19375 })
19376
19377 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19378 ; the TEST instruction with 32-bit sign-extended immediate and thus
19379 ; the instruction size would at least double, which is not what we
19380 ; want even with ! optimize_size.
19381 (define_split
19382   [(set (match_operand 0 "flags_reg_operand" "")
19383         (match_operator 1 "compare_operator"
19384           [(and (match_operand:HI 2 "aligned_operand" "")
19385                 (match_operand:HI 3 "const_int_operand" ""))
19386            (const_int 0)]))]
19387   "! TARGET_PARTIAL_REG_STALL && reload_completed
19388    /* Ensure that the operand will remain sign-extended immediate.  */
19389    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19390    && ! TARGET_FAST_PREFIX
19391    && ! optimize_size"
19392   [(set (match_dup 0)
19393         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19394                          (const_int 0)]))]
19395 {
19396   operands[3]
19397     = gen_int_mode (INTVAL (operands[3])
19398                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19399   operands[2] = gen_lowpart (SImode, operands[2]);
19400 })
19401
19402 (define_split
19403   [(set (match_operand 0 "register_operand" "")
19404         (neg (match_operand 1 "register_operand" "")))
19405    (clobber (reg:CC FLAGS_REG))]
19406   "! TARGET_PARTIAL_REG_STALL && reload_completed
19407    && (GET_MODE (operands[0]) == HImode
19408        || (GET_MODE (operands[0]) == QImode
19409            && (TARGET_PROMOTE_QImode || optimize_size)))"
19410   [(parallel [(set (match_dup 0)
19411                    (neg:SI (match_dup 1)))
19412               (clobber (reg:CC FLAGS_REG))])]
19413   "operands[0] = gen_lowpart (SImode, operands[0]);
19414    operands[1] = gen_lowpart (SImode, operands[1]);")
19415
19416 (define_split
19417   [(set (match_operand 0 "register_operand" "")
19418         (not (match_operand 1 "register_operand" "")))]
19419   "! TARGET_PARTIAL_REG_STALL && reload_completed
19420    && (GET_MODE (operands[0]) == HImode
19421        || (GET_MODE (operands[0]) == QImode
19422            && (TARGET_PROMOTE_QImode || optimize_size)))"
19423   [(set (match_dup 0)
19424         (not:SI (match_dup 1)))]
19425   "operands[0] = gen_lowpart (SImode, operands[0]);
19426    operands[1] = gen_lowpart (SImode, operands[1]);")
19427
19428 (define_split
19429   [(set (match_operand 0 "register_operand" "")
19430         (if_then_else (match_operator 1 "comparison_operator"
19431                                 [(reg FLAGS_REG) (const_int 0)])
19432                       (match_operand 2 "register_operand" "")
19433                       (match_operand 3 "register_operand" "")))]
19434   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19435    && (GET_MODE (operands[0]) == HImode
19436        || (GET_MODE (operands[0]) == QImode
19437            && (TARGET_PROMOTE_QImode || optimize_size)))"
19438   [(set (match_dup 0)
19439         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19440   "operands[0] = gen_lowpart (SImode, operands[0]);
19441    operands[2] = gen_lowpart (SImode, operands[2]);
19442    operands[3] = gen_lowpart (SImode, operands[3]);")
19443
19444 \f
19445 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19446 ;; transform a complex memory operation into two memory to register operations.
19447
19448 ;; Don't push memory operands
19449 (define_peephole2
19450   [(set (match_operand:SI 0 "push_operand" "")
19451         (match_operand:SI 1 "memory_operand" ""))
19452    (match_scratch:SI 2 "r")]
19453   "!optimize_size && !TARGET_PUSH_MEMORY
19454    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19455   [(set (match_dup 2) (match_dup 1))
19456    (set (match_dup 0) (match_dup 2))]
19457   "")
19458
19459 (define_peephole2
19460   [(set (match_operand:DI 0 "push_operand" "")
19461         (match_operand:DI 1 "memory_operand" ""))
19462    (match_scratch:DI 2 "r")]
19463   "!optimize_size && !TARGET_PUSH_MEMORY
19464    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19465   [(set (match_dup 2) (match_dup 1))
19466    (set (match_dup 0) (match_dup 2))]
19467   "")
19468
19469 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19470 ;; SImode pushes.
19471 (define_peephole2
19472   [(set (match_operand:SF 0 "push_operand" "")
19473         (match_operand:SF 1 "memory_operand" ""))
19474    (match_scratch:SF 2 "r")]
19475   "!optimize_size && !TARGET_PUSH_MEMORY
19476    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19477   [(set (match_dup 2) (match_dup 1))
19478    (set (match_dup 0) (match_dup 2))]
19479   "")
19480
19481 (define_peephole2
19482   [(set (match_operand:HI 0 "push_operand" "")
19483         (match_operand:HI 1 "memory_operand" ""))
19484    (match_scratch:HI 2 "r")]
19485   "!optimize_size && !TARGET_PUSH_MEMORY
19486    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19487   [(set (match_dup 2) (match_dup 1))
19488    (set (match_dup 0) (match_dup 2))]
19489   "")
19490
19491 (define_peephole2
19492   [(set (match_operand:QI 0 "push_operand" "")
19493         (match_operand:QI 1 "memory_operand" ""))
19494    (match_scratch:QI 2 "q")]
19495   "!optimize_size && !TARGET_PUSH_MEMORY
19496    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19497   [(set (match_dup 2) (match_dup 1))
19498    (set (match_dup 0) (match_dup 2))]
19499   "")
19500
19501 ;; Don't move an immediate directly to memory when the instruction
19502 ;; gets too big.
19503 (define_peephole2
19504   [(match_scratch:SI 1 "r")
19505    (set (match_operand:SI 0 "memory_operand" "")
19506         (const_int 0))]
19507   "! optimize_size
19508    && ! TARGET_USE_MOV0
19509    && TARGET_SPLIT_LONG_MOVES
19510    && get_attr_length (insn) >= ix86_cost->large_insn
19511    && peep2_regno_dead_p (0, FLAGS_REG)"
19512   [(parallel [(set (match_dup 1) (const_int 0))
19513               (clobber (reg:CC FLAGS_REG))])
19514    (set (match_dup 0) (match_dup 1))]
19515   "")
19516
19517 (define_peephole2
19518   [(match_scratch:HI 1 "r")
19519    (set (match_operand:HI 0 "memory_operand" "")
19520         (const_int 0))]
19521   "! optimize_size
19522    && ! TARGET_USE_MOV0
19523    && TARGET_SPLIT_LONG_MOVES
19524    && get_attr_length (insn) >= ix86_cost->large_insn
19525    && peep2_regno_dead_p (0, FLAGS_REG)"
19526   [(parallel [(set (match_dup 2) (const_int 0))
19527               (clobber (reg:CC FLAGS_REG))])
19528    (set (match_dup 0) (match_dup 1))]
19529   "operands[2] = gen_lowpart (SImode, operands[1]);")
19530
19531 (define_peephole2
19532   [(match_scratch:QI 1 "q")
19533    (set (match_operand:QI 0 "memory_operand" "")
19534         (const_int 0))]
19535   "! optimize_size
19536    && ! TARGET_USE_MOV0
19537    && TARGET_SPLIT_LONG_MOVES
19538    && get_attr_length (insn) >= ix86_cost->large_insn
19539    && peep2_regno_dead_p (0, FLAGS_REG)"
19540   [(parallel [(set (match_dup 2) (const_int 0))
19541               (clobber (reg:CC FLAGS_REG))])
19542    (set (match_dup 0) (match_dup 1))]
19543   "operands[2] = gen_lowpart (SImode, operands[1]);")
19544
19545 (define_peephole2
19546   [(match_scratch:SI 2 "r")
19547    (set (match_operand:SI 0 "memory_operand" "")
19548         (match_operand:SI 1 "immediate_operand" ""))]
19549   "! optimize_size
19550    && get_attr_length (insn) >= ix86_cost->large_insn
19551    && TARGET_SPLIT_LONG_MOVES"
19552   [(set (match_dup 2) (match_dup 1))
19553    (set (match_dup 0) (match_dup 2))]
19554   "")
19555
19556 (define_peephole2
19557   [(match_scratch:HI 2 "r")
19558    (set (match_operand:HI 0 "memory_operand" "")
19559         (match_operand:HI 1 "immediate_operand" ""))]
19560   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19561   && TARGET_SPLIT_LONG_MOVES"
19562   [(set (match_dup 2) (match_dup 1))
19563    (set (match_dup 0) (match_dup 2))]
19564   "")
19565
19566 (define_peephole2
19567   [(match_scratch:QI 2 "q")
19568    (set (match_operand:QI 0 "memory_operand" "")
19569         (match_operand:QI 1 "immediate_operand" ""))]
19570   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19571   && TARGET_SPLIT_LONG_MOVES"
19572   [(set (match_dup 2) (match_dup 1))
19573    (set (match_dup 0) (match_dup 2))]
19574   "")
19575
19576 ;; Don't compare memory with zero, load and use a test instead.
19577 (define_peephole2
19578   [(set (match_operand 0 "flags_reg_operand" "")
19579         (match_operator 1 "compare_operator"
19580           [(match_operand:SI 2 "memory_operand" "")
19581            (const_int 0)]))
19582    (match_scratch:SI 3 "r")]
19583   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19584   [(set (match_dup 3) (match_dup 2))
19585    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19586   "")
19587
19588 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19589 ;; Don't split NOTs with a displacement operand, because resulting XOR
19590 ;; will not be pairable anyway.
19591 ;;
19592 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19593 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19594 ;; so this split helps here as well.
19595 ;;
19596 ;; Note: Can't do this as a regular split because we can't get proper
19597 ;; lifetime information then.
19598
19599 (define_peephole2
19600   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19601         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19602   "!optimize_size
19603    && peep2_regno_dead_p (0, FLAGS_REG)
19604    && ((TARGET_PENTIUM
19605         && (GET_CODE (operands[0]) != MEM
19606             || !memory_displacement_operand (operands[0], SImode)))
19607        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19608   [(parallel [(set (match_dup 0)
19609                    (xor:SI (match_dup 1) (const_int -1)))
19610               (clobber (reg:CC FLAGS_REG))])]
19611   "")
19612
19613 (define_peephole2
19614   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19615         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19616   "!optimize_size
19617    && peep2_regno_dead_p (0, FLAGS_REG)
19618    && ((TARGET_PENTIUM
19619         && (GET_CODE (operands[0]) != MEM
19620             || !memory_displacement_operand (operands[0], HImode)))
19621        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19622   [(parallel [(set (match_dup 0)
19623                    (xor:HI (match_dup 1) (const_int -1)))
19624               (clobber (reg:CC FLAGS_REG))])]
19625   "")
19626
19627 (define_peephole2
19628   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19629         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19630   "!optimize_size
19631    && peep2_regno_dead_p (0, FLAGS_REG)
19632    && ((TARGET_PENTIUM
19633         && (GET_CODE (operands[0]) != MEM
19634             || !memory_displacement_operand (operands[0], QImode)))
19635        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19636   [(parallel [(set (match_dup 0)
19637                    (xor:QI (match_dup 1) (const_int -1)))
19638               (clobber (reg:CC FLAGS_REG))])]
19639   "")
19640
19641 ;; Non pairable "test imm, reg" instructions can be translated to
19642 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19643 ;; byte opcode instead of two, have a short form for byte operands),
19644 ;; so do it for other CPUs as well.  Given that the value was dead,
19645 ;; this should not create any new dependencies.  Pass on the sub-word
19646 ;; versions if we're concerned about partial register stalls.
19647
19648 (define_peephole2
19649   [(set (match_operand 0 "flags_reg_operand" "")
19650         (match_operator 1 "compare_operator"
19651           [(and:SI (match_operand:SI 2 "register_operand" "")
19652                    (match_operand:SI 3 "immediate_operand" ""))
19653            (const_int 0)]))]
19654   "ix86_match_ccmode (insn, CCNOmode)
19655    && (true_regnum (operands[2]) != 0
19656        || satisfies_constraint_K (operands[3]))
19657    && peep2_reg_dead_p (1, operands[2])"
19658   [(parallel
19659      [(set (match_dup 0)
19660            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19661                             (const_int 0)]))
19662       (set (match_dup 2)
19663            (and:SI (match_dup 2) (match_dup 3)))])]
19664   "")
19665
19666 ;; We don't need to handle HImode case, because it will be promoted to SImode
19667 ;; on ! TARGET_PARTIAL_REG_STALL
19668
19669 (define_peephole2
19670   [(set (match_operand 0 "flags_reg_operand" "")
19671         (match_operator 1 "compare_operator"
19672           [(and:QI (match_operand:QI 2 "register_operand" "")
19673                    (match_operand:QI 3 "immediate_operand" ""))
19674            (const_int 0)]))]
19675   "! TARGET_PARTIAL_REG_STALL
19676    && ix86_match_ccmode (insn, CCNOmode)
19677    && true_regnum (operands[2]) != 0
19678    && peep2_reg_dead_p (1, operands[2])"
19679   [(parallel
19680      [(set (match_dup 0)
19681            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19682                             (const_int 0)]))
19683       (set (match_dup 2)
19684            (and:QI (match_dup 2) (match_dup 3)))])]
19685   "")
19686
19687 (define_peephole2
19688   [(set (match_operand 0 "flags_reg_operand" "")
19689         (match_operator 1 "compare_operator"
19690           [(and:SI
19691              (zero_extract:SI
19692                (match_operand 2 "ext_register_operand" "")
19693                (const_int 8)
19694                (const_int 8))
19695              (match_operand 3 "const_int_operand" ""))
19696            (const_int 0)]))]
19697   "! TARGET_PARTIAL_REG_STALL
19698    && ix86_match_ccmode (insn, CCNOmode)
19699    && true_regnum (operands[2]) != 0
19700    && peep2_reg_dead_p (1, operands[2])"
19701   [(parallel [(set (match_dup 0)
19702                    (match_op_dup 1
19703                      [(and:SI
19704                         (zero_extract:SI
19705                           (match_dup 2)
19706                           (const_int 8)
19707                           (const_int 8))
19708                         (match_dup 3))
19709                       (const_int 0)]))
19710               (set (zero_extract:SI (match_dup 2)
19711                                     (const_int 8)
19712                                     (const_int 8))
19713                    (and:SI
19714                      (zero_extract:SI
19715                        (match_dup 2)
19716                        (const_int 8)
19717                        (const_int 8))
19718                      (match_dup 3)))])]
19719   "")
19720
19721 ;; Don't do logical operations with memory inputs.
19722 (define_peephole2
19723   [(match_scratch:SI 2 "r")
19724    (parallel [(set (match_operand:SI 0 "register_operand" "")
19725                    (match_operator:SI 3 "arith_or_logical_operator"
19726                      [(match_dup 0)
19727                       (match_operand:SI 1 "memory_operand" "")]))
19728               (clobber (reg:CC FLAGS_REG))])]
19729   "! optimize_size && ! TARGET_READ_MODIFY"
19730   [(set (match_dup 2) (match_dup 1))
19731    (parallel [(set (match_dup 0)
19732                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19733               (clobber (reg:CC FLAGS_REG))])]
19734   "")
19735
19736 (define_peephole2
19737   [(match_scratch:SI 2 "r")
19738    (parallel [(set (match_operand:SI 0 "register_operand" "")
19739                    (match_operator:SI 3 "arith_or_logical_operator"
19740                      [(match_operand:SI 1 "memory_operand" "")
19741                       (match_dup 0)]))
19742               (clobber (reg:CC FLAGS_REG))])]
19743   "! optimize_size && ! TARGET_READ_MODIFY"
19744   [(set (match_dup 2) (match_dup 1))
19745    (parallel [(set (match_dup 0)
19746                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19747               (clobber (reg:CC FLAGS_REG))])]
19748   "")
19749
19750 ; Don't do logical operations with memory outputs
19751 ;
19752 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19753 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19754 ; the same decoder scheduling characteristics as the original.
19755
19756 (define_peephole2
19757   [(match_scratch:SI 2 "r")
19758    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19759                    (match_operator:SI 3 "arith_or_logical_operator"
19760                      [(match_dup 0)
19761                       (match_operand:SI 1 "nonmemory_operand" "")]))
19762               (clobber (reg:CC FLAGS_REG))])]
19763   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19764   [(set (match_dup 2) (match_dup 0))
19765    (parallel [(set (match_dup 2)
19766                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19767               (clobber (reg:CC FLAGS_REG))])
19768    (set (match_dup 0) (match_dup 2))]
19769   "")
19770
19771 (define_peephole2
19772   [(match_scratch:SI 2 "r")
19773    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19774                    (match_operator:SI 3 "arith_or_logical_operator"
19775                      [(match_operand:SI 1 "nonmemory_operand" "")
19776                       (match_dup 0)]))
19777               (clobber (reg:CC FLAGS_REG))])]
19778   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19779   [(set (match_dup 2) (match_dup 0))
19780    (parallel [(set (match_dup 2)
19781                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19782               (clobber (reg:CC FLAGS_REG))])
19783    (set (match_dup 0) (match_dup 2))]
19784   "")
19785
19786 ;; Attempt to always use XOR for zeroing registers.
19787 (define_peephole2
19788   [(set (match_operand 0 "register_operand" "")
19789         (match_operand 1 "const0_operand" ""))]
19790   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19791    && (! TARGET_USE_MOV0 || optimize_size)
19792    && GENERAL_REG_P (operands[0])
19793    && peep2_regno_dead_p (0, FLAGS_REG)"
19794   [(parallel [(set (match_dup 0) (const_int 0))
19795               (clobber (reg:CC FLAGS_REG))])]
19796 {
19797   operands[0] = gen_lowpart (word_mode, operands[0]);
19798 })
19799
19800 (define_peephole2
19801   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19802         (const_int 0))]
19803   "(GET_MODE (operands[0]) == QImode
19804     || GET_MODE (operands[0]) == HImode)
19805    && (! TARGET_USE_MOV0 || optimize_size)
19806    && peep2_regno_dead_p (0, FLAGS_REG)"
19807   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19808               (clobber (reg:CC FLAGS_REG))])])
19809
19810 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19811 (define_peephole2
19812   [(set (match_operand 0 "register_operand" "")
19813         (const_int -1))]
19814   "(GET_MODE (operands[0]) == HImode
19815     || GET_MODE (operands[0]) == SImode
19816     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19817    && (optimize_size || TARGET_PENTIUM)
19818    && peep2_regno_dead_p (0, FLAGS_REG)"
19819   [(parallel [(set (match_dup 0) (const_int -1))
19820               (clobber (reg:CC FLAGS_REG))])]
19821   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19822                               operands[0]);")
19823
19824 ;; Attempt to convert simple leas to adds. These can be created by
19825 ;; move expanders.
19826 (define_peephole2
19827   [(set (match_operand:SI 0 "register_operand" "")
19828         (plus:SI (match_dup 0)
19829                  (match_operand:SI 1 "nonmemory_operand" "")))]
19830   "peep2_regno_dead_p (0, FLAGS_REG)"
19831   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19832               (clobber (reg:CC FLAGS_REG))])]
19833   "")
19834
19835 (define_peephole2
19836   [(set (match_operand:SI 0 "register_operand" "")
19837         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19838                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19839   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19840   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19841               (clobber (reg:CC FLAGS_REG))])]
19842   "operands[2] = gen_lowpart (SImode, operands[2]);")
19843
19844 (define_peephole2
19845   [(set (match_operand:DI 0 "register_operand" "")
19846         (plus:DI (match_dup 0)
19847                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19848   "peep2_regno_dead_p (0, FLAGS_REG)"
19849   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19850               (clobber (reg:CC FLAGS_REG))])]
19851   "")
19852
19853 (define_peephole2
19854   [(set (match_operand:SI 0 "register_operand" "")
19855         (mult:SI (match_dup 0)
19856                  (match_operand:SI 1 "const_int_operand" "")))]
19857   "exact_log2 (INTVAL (operands[1])) >= 0
19858    && peep2_regno_dead_p (0, FLAGS_REG)"
19859   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19860               (clobber (reg:CC FLAGS_REG))])]
19861   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19862
19863 (define_peephole2
19864   [(set (match_operand:DI 0 "register_operand" "")
19865         (mult:DI (match_dup 0)
19866                  (match_operand:DI 1 "const_int_operand" "")))]
19867   "exact_log2 (INTVAL (operands[1])) >= 0
19868    && peep2_regno_dead_p (0, FLAGS_REG)"
19869   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19870               (clobber (reg:CC FLAGS_REG))])]
19871   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19872
19873 (define_peephole2
19874   [(set (match_operand:SI 0 "register_operand" "")
19875         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19876                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19877   "exact_log2 (INTVAL (operands[2])) >= 0
19878    && REGNO (operands[0]) == REGNO (operands[1])
19879    && peep2_regno_dead_p (0, FLAGS_REG)"
19880   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19881               (clobber (reg:CC FLAGS_REG))])]
19882   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19883
19884 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19885 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19886 ;; many CPUs it is also faster, since special hardware to avoid esp
19887 ;; dependencies is present.
19888
19889 ;; While some of these conversions may be done using splitters, we use peepholes
19890 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19891
19892 ;; Convert prologue esp subtractions to push.
19893 ;; We need register to push.  In order to keep verify_flow_info happy we have
19894 ;; two choices
19895 ;; - use scratch and clobber it in order to avoid dependencies
19896 ;; - use already live register
19897 ;; We can't use the second way right now, since there is no reliable way how to
19898 ;; verify that given register is live.  First choice will also most likely in
19899 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19900 ;; call clobbered registers are dead.  We may want to use base pointer as an
19901 ;; alternative when no register is available later.
19902
19903 (define_peephole2
19904   [(match_scratch:SI 0 "r")
19905    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19906               (clobber (reg:CC FLAGS_REG))
19907               (clobber (mem:BLK (scratch)))])]
19908   "optimize_size || !TARGET_SUB_ESP_4"
19909   [(clobber (match_dup 0))
19910    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19911               (clobber (mem:BLK (scratch)))])])
19912
19913 (define_peephole2
19914   [(match_scratch:SI 0 "r")
19915    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19916               (clobber (reg:CC FLAGS_REG))
19917               (clobber (mem:BLK (scratch)))])]
19918   "optimize_size || !TARGET_SUB_ESP_8"
19919   [(clobber (match_dup 0))
19920    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19921    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19922               (clobber (mem:BLK (scratch)))])])
19923
19924 ;; Convert esp subtractions to push.
19925 (define_peephole2
19926   [(match_scratch:SI 0 "r")
19927    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19928               (clobber (reg:CC FLAGS_REG))])]
19929   "optimize_size || !TARGET_SUB_ESP_4"
19930   [(clobber (match_dup 0))
19931    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19932
19933 (define_peephole2
19934   [(match_scratch:SI 0 "r")
19935    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19936               (clobber (reg:CC FLAGS_REG))])]
19937   "optimize_size || !TARGET_SUB_ESP_8"
19938   [(clobber (match_dup 0))
19939    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19940    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19941
19942 ;; Convert epilogue deallocator to pop.
19943 (define_peephole2
19944   [(match_scratch:SI 0 "r")
19945    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19946               (clobber (reg:CC FLAGS_REG))
19947               (clobber (mem:BLK (scratch)))])]
19948   "optimize_size || !TARGET_ADD_ESP_4"
19949   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19950               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19951               (clobber (mem:BLK (scratch)))])]
19952   "")
19953
19954 ;; Two pops case is tricky, since pop causes dependency on destination register.
19955 ;; We use two registers if available.
19956 (define_peephole2
19957   [(match_scratch:SI 0 "r")
19958    (match_scratch:SI 1 "r")
19959    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19960               (clobber (reg:CC FLAGS_REG))
19961               (clobber (mem:BLK (scratch)))])]
19962   "optimize_size || !TARGET_ADD_ESP_8"
19963   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19964               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19965               (clobber (mem:BLK (scratch)))])
19966    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19967               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19968   "")
19969
19970 (define_peephole2
19971   [(match_scratch:SI 0 "r")
19972    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19973               (clobber (reg:CC FLAGS_REG))
19974               (clobber (mem:BLK (scratch)))])]
19975   "optimize_size"
19976   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19977               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19978               (clobber (mem:BLK (scratch)))])
19979    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19980               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19981   "")
19982
19983 ;; Convert esp additions to pop.
19984 (define_peephole2
19985   [(match_scratch:SI 0 "r")
19986    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19987               (clobber (reg:CC FLAGS_REG))])]
19988   ""
19989   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19990               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19991   "")
19992
19993 ;; Two pops case is tricky, since pop causes dependency on destination register.
19994 ;; We use two registers if available.
19995 (define_peephole2
19996   [(match_scratch:SI 0 "r")
19997    (match_scratch:SI 1 "r")
19998    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19999               (clobber (reg:CC FLAGS_REG))])]
20000   ""
20001   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20002               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20003    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20004               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20005   "")
20006
20007 (define_peephole2
20008   [(match_scratch:SI 0 "r")
20009    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20010               (clobber (reg:CC FLAGS_REG))])]
20011   "optimize_size"
20012   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20013               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20014    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20015               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20016   "")
20017 \f
20018 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20019 ;; required and register dies.  Similarly for 128 to plus -128.
20020 (define_peephole2
20021   [(set (match_operand 0 "flags_reg_operand" "")
20022         (match_operator 1 "compare_operator"
20023           [(match_operand 2 "register_operand" "")
20024            (match_operand 3 "const_int_operand" "")]))]
20025   "(INTVAL (operands[3]) == -1
20026     || INTVAL (operands[3]) == 1
20027     || INTVAL (operands[3]) == 128)
20028    && ix86_match_ccmode (insn, CCGCmode)
20029    && peep2_reg_dead_p (1, operands[2])"
20030   [(parallel [(set (match_dup 0)
20031                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20032               (clobber (match_dup 2))])]
20033   "")
20034 \f
20035 (define_peephole2
20036   [(match_scratch:DI 0 "r")
20037    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20038               (clobber (reg:CC FLAGS_REG))
20039               (clobber (mem:BLK (scratch)))])]
20040   "optimize_size || !TARGET_SUB_ESP_4"
20041   [(clobber (match_dup 0))
20042    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20043               (clobber (mem:BLK (scratch)))])])
20044
20045 (define_peephole2
20046   [(match_scratch:DI 0 "r")
20047    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20048               (clobber (reg:CC FLAGS_REG))
20049               (clobber (mem:BLK (scratch)))])]
20050   "optimize_size || !TARGET_SUB_ESP_8"
20051   [(clobber (match_dup 0))
20052    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20053    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20054               (clobber (mem:BLK (scratch)))])])
20055
20056 ;; Convert esp subtractions to push.
20057 (define_peephole2
20058   [(match_scratch:DI 0 "r")
20059    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20060               (clobber (reg:CC FLAGS_REG))])]
20061   "optimize_size || !TARGET_SUB_ESP_4"
20062   [(clobber (match_dup 0))
20063    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20064
20065 (define_peephole2
20066   [(match_scratch:DI 0 "r")
20067    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20068               (clobber (reg:CC FLAGS_REG))])]
20069   "optimize_size || !TARGET_SUB_ESP_8"
20070   [(clobber (match_dup 0))
20071    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20072    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20073
20074 ;; Convert epilogue deallocator to pop.
20075 (define_peephole2
20076   [(match_scratch:DI 0 "r")
20077    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20078               (clobber (reg:CC FLAGS_REG))
20079               (clobber (mem:BLK (scratch)))])]
20080   "optimize_size || !TARGET_ADD_ESP_4"
20081   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20082               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20083               (clobber (mem:BLK (scratch)))])]
20084   "")
20085
20086 ;; Two pops case is tricky, since pop causes dependency on destination register.
20087 ;; We use two registers if available.
20088 (define_peephole2
20089   [(match_scratch:DI 0 "r")
20090    (match_scratch:DI 1 "r")
20091    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20092               (clobber (reg:CC FLAGS_REG))
20093               (clobber (mem:BLK (scratch)))])]
20094   "optimize_size || !TARGET_ADD_ESP_8"
20095   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20096               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20097               (clobber (mem:BLK (scratch)))])
20098    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20099               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20100   "")
20101
20102 (define_peephole2
20103   [(match_scratch:DI 0 "r")
20104    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20105               (clobber (reg:CC FLAGS_REG))
20106               (clobber (mem:BLK (scratch)))])]
20107   "optimize_size"
20108   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20109               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20110               (clobber (mem:BLK (scratch)))])
20111    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20112               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20113   "")
20114
20115 ;; Convert esp additions to pop.
20116 (define_peephole2
20117   [(match_scratch:DI 0 "r")
20118    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20119               (clobber (reg:CC FLAGS_REG))])]
20120   ""
20121   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20122               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20123   "")
20124
20125 ;; Two pops case is tricky, since pop causes dependency on destination register.
20126 ;; We use two registers if available.
20127 (define_peephole2
20128   [(match_scratch:DI 0 "r")
20129    (match_scratch:DI 1 "r")
20130    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20131               (clobber (reg:CC FLAGS_REG))])]
20132   ""
20133   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20134               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20135    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20136               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20137   "")
20138
20139 (define_peephole2
20140   [(match_scratch:DI 0 "r")
20141    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20142               (clobber (reg:CC FLAGS_REG))])]
20143   "optimize_size"
20144   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20145               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20146    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20147               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20148   "")
20149 \f
20150 ;; Convert imul by three, five and nine into lea
20151 (define_peephole2
20152   [(parallel
20153     [(set (match_operand:SI 0 "register_operand" "")
20154           (mult:SI (match_operand:SI 1 "register_operand" "")
20155                    (match_operand:SI 2 "const_int_operand" "")))
20156      (clobber (reg:CC FLAGS_REG))])]
20157   "INTVAL (operands[2]) == 3
20158    || INTVAL (operands[2]) == 5
20159    || INTVAL (operands[2]) == 9"
20160   [(set (match_dup 0)
20161         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20162                  (match_dup 1)))]
20163   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20164
20165 (define_peephole2
20166   [(parallel
20167     [(set (match_operand:SI 0 "register_operand" "")
20168           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20169                    (match_operand:SI 2 "const_int_operand" "")))
20170      (clobber (reg:CC FLAGS_REG))])]
20171   "!optimize_size
20172    && (INTVAL (operands[2]) == 3
20173        || INTVAL (operands[2]) == 5
20174        || INTVAL (operands[2]) == 9)"
20175   [(set (match_dup 0) (match_dup 1))
20176    (set (match_dup 0)
20177         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20178                  (match_dup 0)))]
20179   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20180
20181 (define_peephole2
20182   [(parallel
20183     [(set (match_operand:DI 0 "register_operand" "")
20184           (mult:DI (match_operand:DI 1 "register_operand" "")
20185                    (match_operand:DI 2 "const_int_operand" "")))
20186      (clobber (reg:CC FLAGS_REG))])]
20187   "TARGET_64BIT
20188    && (INTVAL (operands[2]) == 3
20189        || INTVAL (operands[2]) == 5
20190        || INTVAL (operands[2]) == 9)"
20191   [(set (match_dup 0)
20192         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20193                  (match_dup 1)))]
20194   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20195
20196 (define_peephole2
20197   [(parallel
20198     [(set (match_operand:DI 0 "register_operand" "")
20199           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20200                    (match_operand:DI 2 "const_int_operand" "")))
20201      (clobber (reg:CC FLAGS_REG))])]
20202   "TARGET_64BIT
20203    && !optimize_size
20204    && (INTVAL (operands[2]) == 3
20205        || INTVAL (operands[2]) == 5
20206        || INTVAL (operands[2]) == 9)"
20207   [(set (match_dup 0) (match_dup 1))
20208    (set (match_dup 0)
20209         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20210                  (match_dup 0)))]
20211   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20212
20213 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20214 ;; imul $32bit_imm, reg, reg is direct decoded.
20215 (define_peephole2
20216   [(match_scratch:DI 3 "r")
20217    (parallel [(set (match_operand:DI 0 "register_operand" "")
20218                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20219                             (match_operand:DI 2 "immediate_operand" "")))
20220               (clobber (reg:CC FLAGS_REG))])]
20221   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20222    && !satisfies_constraint_K (operands[2])"
20223   [(set (match_dup 3) (match_dup 1))
20224    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20225               (clobber (reg:CC FLAGS_REG))])]
20226 "")
20227
20228 (define_peephole2
20229   [(match_scratch:SI 3 "r")
20230    (parallel [(set (match_operand:SI 0 "register_operand" "")
20231                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20232                             (match_operand:SI 2 "immediate_operand" "")))
20233               (clobber (reg:CC FLAGS_REG))])]
20234   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20235    && !satisfies_constraint_K (operands[2])"
20236   [(set (match_dup 3) (match_dup 1))
20237    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20238               (clobber (reg:CC FLAGS_REG))])]
20239 "")
20240
20241 (define_peephole2
20242   [(match_scratch:SI 3 "r")
20243    (parallel [(set (match_operand:DI 0 "register_operand" "")
20244                    (zero_extend:DI
20245                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20246                               (match_operand:SI 2 "immediate_operand" ""))))
20247               (clobber (reg:CC FLAGS_REG))])]
20248   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20249    && !satisfies_constraint_K (operands[2])"
20250   [(set (match_dup 3) (match_dup 1))
20251    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20252               (clobber (reg:CC FLAGS_REG))])]
20253 "")
20254
20255 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20256 ;; Convert it into imul reg, reg
20257 ;; It would be better to force assembler to encode instruction using long
20258 ;; immediate, but there is apparently no way to do so.
20259 (define_peephole2
20260   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20261                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20262                             (match_operand:DI 2 "const_int_operand" "")))
20263               (clobber (reg:CC FLAGS_REG))])
20264    (match_scratch:DI 3 "r")]
20265   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20266    && satisfies_constraint_K (operands[2])"
20267   [(set (match_dup 3) (match_dup 2))
20268    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20269               (clobber (reg:CC FLAGS_REG))])]
20270 {
20271   if (!rtx_equal_p (operands[0], operands[1]))
20272     emit_move_insn (operands[0], operands[1]);
20273 })
20274
20275 (define_peephole2
20276   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20277                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20278                             (match_operand:SI 2 "const_int_operand" "")))
20279               (clobber (reg:CC FLAGS_REG))])
20280    (match_scratch:SI 3 "r")]
20281   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20282    && satisfies_constraint_K (operands[2])"
20283   [(set (match_dup 3) (match_dup 2))
20284    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20285               (clobber (reg:CC FLAGS_REG))])]
20286 {
20287   if (!rtx_equal_p (operands[0], operands[1]))
20288     emit_move_insn (operands[0], operands[1]);
20289 })
20290
20291 (define_peephole2
20292   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20293                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20294                             (match_operand:HI 2 "immediate_operand" "")))
20295               (clobber (reg:CC FLAGS_REG))])
20296    (match_scratch:HI 3 "r")]
20297   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20298   [(set (match_dup 3) (match_dup 2))
20299    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20300               (clobber (reg:CC FLAGS_REG))])]
20301 {
20302   if (!rtx_equal_p (operands[0], operands[1]))
20303     emit_move_insn (operands[0], operands[1]);
20304 })
20305
20306 ;; After splitting up read-modify operations, array accesses with memory
20307 ;; operands might end up in form:
20308 ;;  sall    $2, %eax
20309 ;;  movl    4(%esp), %edx
20310 ;;  addl    %edx, %eax
20311 ;; instead of pre-splitting:
20312 ;;  sall    $2, %eax
20313 ;;  addl    4(%esp), %eax
20314 ;; Turn it into:
20315 ;;  movl    4(%esp), %edx
20316 ;;  leal    (%edx,%eax,4), %eax
20317
20318 (define_peephole2
20319   [(parallel [(set (match_operand 0 "register_operand" "")
20320                    (ashift (match_operand 1 "register_operand" "")
20321                            (match_operand 2 "const_int_operand" "")))
20322                (clobber (reg:CC FLAGS_REG))])
20323    (set (match_operand 3 "register_operand")
20324         (match_operand 4 "x86_64_general_operand" ""))
20325    (parallel [(set (match_operand 5 "register_operand" "")
20326                    (plus (match_operand 6 "register_operand" "")
20327                          (match_operand 7 "register_operand" "")))
20328                    (clobber (reg:CC FLAGS_REG))])]
20329   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20330    /* Validate MODE for lea.  */
20331    && ((!TARGET_PARTIAL_REG_STALL
20332         && (GET_MODE (operands[0]) == QImode
20333             || GET_MODE (operands[0]) == HImode))
20334        || GET_MODE (operands[0]) == SImode
20335        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20336    /* We reorder load and the shift.  */
20337    && !rtx_equal_p (operands[1], operands[3])
20338    && !reg_overlap_mentioned_p (operands[0], operands[4])
20339    /* Last PLUS must consist of operand 0 and 3.  */
20340    && !rtx_equal_p (operands[0], operands[3])
20341    && (rtx_equal_p (operands[3], operands[6])
20342        || rtx_equal_p (operands[3], operands[7]))
20343    && (rtx_equal_p (operands[0], operands[6])
20344        || rtx_equal_p (operands[0], operands[7]))
20345    /* The intermediate operand 0 must die or be same as output.  */
20346    && (rtx_equal_p (operands[0], operands[5])
20347        || peep2_reg_dead_p (3, operands[0]))"
20348   [(set (match_dup 3) (match_dup 4))
20349    (set (match_dup 0) (match_dup 1))]
20350 {
20351   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20352   int scale = 1 << INTVAL (operands[2]);
20353   rtx index = gen_lowpart (Pmode, operands[1]);
20354   rtx base = gen_lowpart (Pmode, operands[3]);
20355   rtx dest = gen_lowpart (mode, operands[5]);
20356
20357   operands[1] = gen_rtx_PLUS (Pmode, base,
20358                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20359   if (mode != Pmode)
20360     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20361   operands[0] = dest;
20362 })
20363 \f
20364 ;; Call-value patterns last so that the wildcard operand does not
20365 ;; disrupt insn-recog's switch tables.
20366
20367 (define_insn "*call_value_pop_0"
20368   [(set (match_operand 0 "" "")
20369         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20370               (match_operand:SI 2 "" "")))
20371    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20372                             (match_operand:SI 3 "immediate_operand" "")))]
20373   "!TARGET_64BIT"
20374 {
20375   if (SIBLING_CALL_P (insn))
20376     return "jmp\t%P1";
20377   else
20378     return "call\t%P1";
20379 }
20380   [(set_attr "type" "callv")])
20381
20382 (define_insn "*call_value_pop_1"
20383   [(set (match_operand 0 "" "")
20384         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20385               (match_operand:SI 2 "" "")))
20386    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20387                             (match_operand:SI 3 "immediate_operand" "i")))]
20388   "!TARGET_64BIT"
20389 {
20390   if (constant_call_address_operand (operands[1], Pmode))
20391     {
20392       if (SIBLING_CALL_P (insn))
20393         return "jmp\t%P1";
20394       else
20395         return "call\t%P1";
20396     }
20397   if (SIBLING_CALL_P (insn))
20398     return "jmp\t%A1";
20399   else
20400     return "call\t%A1";
20401 }
20402   [(set_attr "type" "callv")])
20403
20404 (define_insn "*call_value_0"
20405   [(set (match_operand 0 "" "")
20406         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20407               (match_operand:SI 2 "" "")))]
20408   "!TARGET_64BIT"
20409 {
20410   if (SIBLING_CALL_P (insn))
20411     return "jmp\t%P1";
20412   else
20413     return "call\t%P1";
20414 }
20415   [(set_attr "type" "callv")])
20416
20417 (define_insn "*call_value_0_rex64"
20418   [(set (match_operand 0 "" "")
20419         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20420               (match_operand:DI 2 "const_int_operand" "")))]
20421   "TARGET_64BIT"
20422 {
20423   if (SIBLING_CALL_P (insn))
20424     return "jmp\t%P1";
20425   else
20426     return "call\t%P1";
20427 }
20428   [(set_attr "type" "callv")])
20429
20430 (define_insn "*call_value_1"
20431   [(set (match_operand 0 "" "")
20432         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20433               (match_operand:SI 2 "" "")))]
20434   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20435 {
20436   if (constant_call_address_operand (operands[1], Pmode))
20437     return "call\t%P1";
20438   return "call\t%A1";
20439 }
20440   [(set_attr "type" "callv")])
20441
20442 (define_insn "*sibcall_value_1"
20443   [(set (match_operand 0 "" "")
20444         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20445               (match_operand:SI 2 "" "")))]
20446   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20447 {
20448   if (constant_call_address_operand (operands[1], Pmode))
20449     return "jmp\t%P1";
20450   return "jmp\t%A1";
20451 }
20452   [(set_attr "type" "callv")])
20453
20454 (define_insn "*call_value_1_rex64"
20455   [(set (match_operand 0 "" "")
20456         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20457               (match_operand:DI 2 "" "")))]
20458   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20459 {
20460   if (constant_call_address_operand (operands[1], Pmode))
20461     return "call\t%P1";
20462   return "call\t%A1";
20463 }
20464   [(set_attr "type" "callv")])
20465
20466 (define_insn "*sibcall_value_1_rex64"
20467   [(set (match_operand 0 "" "")
20468         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20469               (match_operand:DI 2 "" "")))]
20470   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20471   "jmp\t%P1"
20472   [(set_attr "type" "callv")])
20473
20474 (define_insn "*sibcall_value_1_rex64_v"
20475   [(set (match_operand 0 "" "")
20476         (call (mem:QI (reg:DI R11_REG))
20477               (match_operand:DI 1 "" "")))]
20478   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20479   "jmp\t*%%r11"
20480   [(set_attr "type" "callv")])
20481 \f
20482 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20483 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20484 ;; caught for use by garbage collectors and the like.  Using an insn that
20485 ;; maps to SIGILL makes it more likely the program will rightfully die.
20486 ;; Keeping with tradition, "6" is in honor of #UD.
20487 (define_insn "trap"
20488   [(trap_if (const_int 1) (const_int 6))]
20489   ""
20490   { return ASM_SHORT "0x0b0f"; }
20491   [(set_attr "length" "2")])
20492
20493 (define_expand "sse_prologue_save"
20494   [(parallel [(set (match_operand:BLK 0 "" "")
20495                    (unspec:BLK [(reg:DI 21)
20496                                 (reg:DI 22)
20497                                 (reg:DI 23)
20498                                 (reg:DI 24)
20499                                 (reg:DI 25)
20500                                 (reg:DI 26)
20501                                 (reg:DI 27)
20502                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20503               (use (match_operand:DI 1 "register_operand" ""))
20504               (use (match_operand:DI 2 "immediate_operand" ""))
20505               (use (label_ref:DI (match_operand 3 "" "")))])]
20506   "TARGET_64BIT"
20507   "")
20508
20509 (define_insn "*sse_prologue_save_insn"
20510   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20511                           (match_operand:DI 4 "const_int_operand" "n")))
20512         (unspec:BLK [(reg:DI 21)
20513                      (reg:DI 22)
20514                      (reg:DI 23)
20515                      (reg:DI 24)
20516                      (reg:DI 25)
20517                      (reg:DI 26)
20518                      (reg:DI 27)
20519                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20520    (use (match_operand:DI 1 "register_operand" "r"))
20521    (use (match_operand:DI 2 "const_int_operand" "i"))
20522    (use (label_ref:DI (match_operand 3 "" "X")))]
20523   "TARGET_64BIT
20524    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20525    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20526   "*
20527 {
20528   int i;
20529   operands[0] = gen_rtx_MEM (Pmode,
20530                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20531   output_asm_insn (\"jmp\\t%A1\", operands);
20532   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20533     {
20534       operands[4] = adjust_address (operands[0], DImode, i*16);
20535       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20536       PUT_MODE (operands[4], TImode);
20537       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20538         output_asm_insn (\"rex\", operands);
20539       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20540     }
20541   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20542                              CODE_LABEL_NUMBER (operands[3]));
20543   return \"\";
20544 }
20545   "
20546   [(set_attr "type" "other")
20547    (set_attr "length_immediate" "0")
20548    (set_attr "length_address" "0")
20549    (set_attr "length" "135")
20550    (set_attr "memory" "store")
20551    (set_attr "modrm" "0")
20552    (set_attr "mode" "DI")])
20553
20554 (define_expand "prefetch"
20555   [(prefetch (match_operand 0 "address_operand" "")
20556              (match_operand:SI 1 "const_int_operand" "")
20557              (match_operand:SI 2 "const_int_operand" ""))]
20558   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20559 {
20560   int rw = INTVAL (operands[1]);
20561   int locality = INTVAL (operands[2]);
20562
20563   gcc_assert (rw == 0 || rw == 1);
20564   gcc_assert (locality >= 0 && locality <= 3);
20565   gcc_assert (GET_MODE (operands[0]) == Pmode
20566               || GET_MODE (operands[0]) == VOIDmode);
20567
20568   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20569      supported by SSE counterpart or the SSE prefetch is not available
20570      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20571      of locality.  */
20572   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20573     operands[2] = GEN_INT (3);
20574   else
20575     operands[1] = const0_rtx;
20576 })
20577
20578 (define_insn "*prefetch_sse"
20579   [(prefetch (match_operand:SI 0 "address_operand" "p")
20580              (const_int 0)
20581              (match_operand:SI 1 "const_int_operand" ""))]
20582   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20583 {
20584   static const char * const patterns[4] = {
20585    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20586   };
20587
20588   int locality = INTVAL (operands[1]);
20589   gcc_assert (locality >= 0 && locality <= 3);
20590
20591   return patterns[locality];
20592 }
20593   [(set_attr "type" "sse")
20594    (set_attr "memory" "none")])
20595
20596 (define_insn "*prefetch_sse_rex"
20597   [(prefetch (match_operand:DI 0 "address_operand" "p")
20598              (const_int 0)
20599              (match_operand:SI 1 "const_int_operand" ""))]
20600   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20601 {
20602   static const char * const patterns[4] = {
20603    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20604   };
20605
20606   int locality = INTVAL (operands[1]);
20607   gcc_assert (locality >= 0 && locality <= 3);
20608
20609   return patterns[locality];
20610 }
20611   [(set_attr "type" "sse")
20612    (set_attr "memory" "none")])
20613
20614 (define_insn "*prefetch_3dnow"
20615   [(prefetch (match_operand:SI 0 "address_operand" "p")
20616              (match_operand:SI 1 "const_int_operand" "n")
20617              (const_int 3))]
20618   "TARGET_3DNOW && !TARGET_64BIT"
20619 {
20620   if (INTVAL (operands[1]) == 0)
20621     return "prefetch\t%a0";
20622   else
20623     return "prefetchw\t%a0";
20624 }
20625   [(set_attr "type" "mmx")
20626    (set_attr "memory" "none")])
20627
20628 (define_insn "*prefetch_3dnow_rex"
20629   [(prefetch (match_operand:DI 0 "address_operand" "p")
20630              (match_operand:SI 1 "const_int_operand" "n")
20631              (const_int 3))]
20632   "TARGET_3DNOW && TARGET_64BIT"
20633 {
20634   if (INTVAL (operands[1]) == 0)
20635     return "prefetch\t%a0";
20636   else
20637     return "prefetchw\t%a0";
20638 }
20639   [(set_attr "type" "mmx")
20640    (set_attr "memory" "none")])
20641
20642 (define_expand "stack_protect_set"
20643   [(match_operand 0 "memory_operand" "")
20644    (match_operand 1 "memory_operand" "")]
20645   ""
20646 {
20647 #ifdef TARGET_THREAD_SSP_OFFSET
20648   if (TARGET_64BIT)
20649     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20650                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20651   else
20652     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20653                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20654 #else
20655   if (TARGET_64BIT)
20656     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20657   else
20658     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20659 #endif
20660   DONE;
20661 })
20662
20663 (define_insn "stack_protect_set_si"
20664   [(set (match_operand:SI 0 "memory_operand" "=m")
20665         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20666    (set (match_scratch:SI 2 "=&r") (const_int 0))
20667    (clobber (reg:CC FLAGS_REG))]
20668   ""
20669   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20670   [(set_attr "type" "multi")])
20671
20672 (define_insn "stack_protect_set_di"
20673   [(set (match_operand:DI 0 "memory_operand" "=m")
20674         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20675    (set (match_scratch:DI 2 "=&r") (const_int 0))
20676    (clobber (reg:CC FLAGS_REG))]
20677   "TARGET_64BIT"
20678   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20679   [(set_attr "type" "multi")])
20680
20681 (define_insn "stack_tls_protect_set_si"
20682   [(set (match_operand:SI 0 "memory_operand" "=m")
20683         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20684    (set (match_scratch:SI 2 "=&r") (const_int 0))
20685    (clobber (reg:CC FLAGS_REG))]
20686   ""
20687   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20688   [(set_attr "type" "multi")])
20689
20690 (define_insn "stack_tls_protect_set_di"
20691   [(set (match_operand:DI 0 "memory_operand" "=m")
20692         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20693    (set (match_scratch:DI 2 "=&r") (const_int 0))
20694    (clobber (reg:CC FLAGS_REG))]
20695   "TARGET_64BIT"
20696   {
20697      /* The kernel uses a different segment register for performance reasons; a
20698         system call would not have to trash the userspace segment register,
20699         which would be expensive */
20700      if (ix86_cmodel != CM_KERNEL)
20701         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20702      else
20703         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20704   }
20705   [(set_attr "type" "multi")])
20706
20707 (define_expand "stack_protect_test"
20708   [(match_operand 0 "memory_operand" "")
20709    (match_operand 1 "memory_operand" "")
20710    (match_operand 2 "" "")]
20711   ""
20712 {
20713   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20714   ix86_compare_op0 = operands[0];
20715   ix86_compare_op1 = operands[1];
20716   ix86_compare_emitted = flags;
20717
20718 #ifdef TARGET_THREAD_SSP_OFFSET
20719   if (TARGET_64BIT)
20720     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20721                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20722   else
20723     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20724                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20725 #else
20726   if (TARGET_64BIT)
20727     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20728   else
20729     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20730 #endif
20731   emit_jump_insn (gen_beq (operands[2]));
20732   DONE;
20733 })
20734
20735 (define_insn "stack_protect_test_si"
20736   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20737         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20738                      (match_operand:SI 2 "memory_operand" "m")]
20739                     UNSPEC_SP_TEST))
20740    (clobber (match_scratch:SI 3 "=&r"))]
20741   ""
20742   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20743   [(set_attr "type" "multi")])
20744
20745 (define_insn "stack_protect_test_di"
20746   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20747         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20748                      (match_operand:DI 2 "memory_operand" "m")]
20749                     UNSPEC_SP_TEST))
20750    (clobber (match_scratch:DI 3 "=&r"))]
20751   "TARGET_64BIT"
20752   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20753   [(set_attr "type" "multi")])
20754
20755 (define_insn "stack_tls_protect_test_si"
20756   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20757         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20758                      (match_operand:SI 2 "const_int_operand" "i")]
20759                     UNSPEC_SP_TLS_TEST))
20760    (clobber (match_scratch:SI 3 "=r"))]
20761   ""
20762   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20763   [(set_attr "type" "multi")])
20764
20765 (define_insn "stack_tls_protect_test_di"
20766   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20767         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20768                      (match_operand:DI 2 "const_int_operand" "i")]
20769                     UNSPEC_SP_TLS_TEST))
20770    (clobber (match_scratch:DI 3 "=r"))]
20771   "TARGET_64BIT"
20772   {
20773      /* The kernel uses a different segment register for performance reasons; a
20774         system call would not have to trash the userspace segment register,
20775         which would be expensive */
20776      if (ix86_cmodel != CM_KERNEL)
20777         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20778      else
20779         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20780   }
20781   [(set_attr "type" "multi")])
20782
20783 (include "mmx.md")
20784 (include "sse.md")
20785 (include "sync.md")