OSDN Git Service

* config/i386/i386.md: Remove misleading comment.
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.  */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; The special asm out single letter directives following a '%' are:
31 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
32 ;;     operands[1].
33 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
34 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
35 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
36 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
37 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
38 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
39 ;; 'J' Print the appropriate jump operand.
40 ;;
41 ;; 'b' Print the QImode name of the register for the indicated operand.
42 ;;     %b0 would print %al if operands[0] is reg 0.
43 ;; 'w' Likewise, print the HImode name of the register.
44 ;; 'k' Likewise, print the SImode name of the register.
45 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
46 ;; 'y' Print "st(0)" instead of "st" as a register.
47
48 ;; UNSPEC usage:
49
50 (define_constants
51   [; Relocation specifiers
52    (UNSPEC_GOT                  0)
53    (UNSPEC_GOTOFF               1)
54    (UNSPEC_GOTPCREL             2)
55    (UNSPEC_GOTTPOFF             3)
56    (UNSPEC_TPOFF                4)
57    (UNSPEC_NTPOFF               5)
58    (UNSPEC_DTPOFF               6)
59    (UNSPEC_GOTNTPOFF            7)
60    (UNSPEC_INDNTPOFF            8)
61
62    ; Prologue support
63    (UNSPEC_STACK_ALLOC          11)
64    (UNSPEC_SET_GOT              12)
65    (UNSPEC_SSE_PROLOGUE_SAVE    13)
66    (UNSPEC_REG_SAVE             14)
67    (UNSPEC_DEF_CFA              15)
68
69    ; TLS support
70    (UNSPEC_TP                   16)
71    (UNSPEC_TLS_GD               17)
72    (UNSPEC_TLS_LD_BASE          18)
73    (UNSPEC_TLSDESC              19)
74
75    ; Other random patterns
76    (UNSPEC_SCAS                 20)
77    (UNSPEC_FNSTSW               21)
78    (UNSPEC_SAHF                 22)
79    (UNSPEC_FSTCW                23)
80    (UNSPEC_ADD_CARRY            24)
81    (UNSPEC_FLDCW                25)
82    (UNSPEC_REP                  26)
83    (UNSPEC_EH_RETURN            27)
84    (UNSPEC_LD_MPIC              28)     ; load_macho_picbase
85    (UNSPEC_TRUNC_NOOP           29)
86
87    ; For SSE/MMX support:
88    (UNSPEC_FIX_NOTRUNC          30)
89    (UNSPEC_MASKMOV              31)
90    (UNSPEC_MOVMSK               32)
91    (UNSPEC_MOVNT                33)
92    (UNSPEC_MOVU                 34)
93    (UNSPEC_RCP                  35)
94    (UNSPEC_RSQRT                36)
95    (UNSPEC_SFENCE               37)
96    (UNSPEC_NOP                  38)     ; prevents combiner cleverness
97    (UNSPEC_PFRCP                39)
98    (UNSPEC_PFRCPIT1             40)
99    (UNSPEC_PFRCPIT2             41)
100    (UNSPEC_PFRSQRT              42)
101    (UNSPEC_PFRSQIT1             43)
102    (UNSPEC_MFENCE               44)
103    (UNSPEC_LFENCE               45)
104    (UNSPEC_PSADBW               46)
105    (UNSPEC_LDDQU                47)
106
107    ; Generic math support
108    (UNSPEC_COPYSIGN             50)
109    (UNSPEC_IEEE_MIN             51)     ; not commutative
110    (UNSPEC_IEEE_MAX             52)     ; not commutative
111
112    ; x87 Floating point
113    (UNSPEC_SIN                  60)
114    (UNSPEC_COS                  61)
115    (UNSPEC_FPATAN               62)
116    (UNSPEC_FYL2X                63)
117    (UNSPEC_FYL2XP1              64)
118    (UNSPEC_FRNDINT              65)
119    (UNSPEC_FIST                 66)
120    (UNSPEC_F2XM1                67)
121    (UNSPEC_TAN                  68)
122    (UNSPEC_FXAM                 69)
123
124    ; x87 Rounding
125    (UNSPEC_FRNDINT_FLOOR        70)
126    (UNSPEC_FRNDINT_CEIL         71)
127    (UNSPEC_FRNDINT_TRUNC        72)
128    (UNSPEC_FRNDINT_MASK_PM      73)
129    (UNSPEC_FIST_FLOOR           74)
130    (UNSPEC_FIST_CEIL            75)
131
132    ; x87 Double output FP
133    (UNSPEC_SINCOS_COS           80)
134    (UNSPEC_SINCOS_SIN           81)
135    (UNSPEC_XTRACT_FRACT         84)
136    (UNSPEC_XTRACT_EXP           85)
137    (UNSPEC_FSCALE_FRACT         86)
138    (UNSPEC_FSCALE_EXP           87)
139    (UNSPEC_FPREM_F              88)
140    (UNSPEC_FPREM_U              89)
141    (UNSPEC_FPREM1_F             90)
142    (UNSPEC_FPREM1_U             91)
143
144    ; SSP patterns
145    (UNSPEC_SP_SET               100)
146    (UNSPEC_SP_TEST              101)
147    (UNSPEC_SP_TLS_SET           102)
148    (UNSPEC_SP_TLS_TEST          103)
149
150    ; SSSE3
151    (UNSPEC_PSHUFB               120)
152    (UNSPEC_PSIGN                121)
153    (UNSPEC_PALIGNR              122)
154
155    ; For SSE4A support
156    (UNSPEC_EXTRQI               130)
157    (UNSPEC_EXTRQ                131)   
158    (UNSPEC_INSERTQI             132)
159    (UNSPEC_INSERTQ              133)
160   ])
161
162 (define_constants
163   [(UNSPECV_BLOCKAGE            0)
164    (UNSPECV_STACK_PROBE         1)
165    (UNSPECV_EMMS                2)
166    (UNSPECV_LDMXCSR             3)
167    (UNSPECV_STMXCSR             4)
168    (UNSPECV_FEMMS               5)
169    (UNSPECV_CLFLUSH             6)
170    (UNSPECV_ALIGN               7)
171    (UNSPECV_MONITOR             8)
172    (UNSPECV_MWAIT               9)
173    (UNSPECV_CMPXCHG_1           10)
174    (UNSPECV_CMPXCHG_2           11)
175    (UNSPECV_XCHG                12)
176    (UNSPECV_LOCK                13)
177   ])
178
179 ;; Registers by name.
180 (define_constants
181   [(BP_REG                       6)
182    (SP_REG                       7)
183    (FLAGS_REG                   17)
184    (FPSR_REG                    18)
185    (FPCR_REG                    19)
186    (R10_REG                     39)
187    (R11_REG                     40)
188   ])
189
190 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
191 ;; from i386.c.
192
193 ;; In C guard expressions, put expressions which may be compile-time
194 ;; constants first.  This allows for better optimization.  For
195 ;; example, write "TARGET_64BIT && reload_completed", not
196 ;; "reload_completed && TARGET_64BIT".
197
198 \f
199 ;; Processor type.  This attribute must exactly match the processor_type
200 ;; enumeration in i386.h.
201 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
202                     nocona,core2,generic32,generic64,amdfam10"
203   (const (symbol_ref "ix86_tune")))
204
205 ;; A basic instruction type.  Refinements due to arguments to be
206 ;; provided in other attributes.
207 (define_attr "type"
208   "other,multi,
209    alu,alu1,negnot,imov,imovx,lea,
210    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
211    icmp,test,ibr,setcc,icmov,
212    push,pop,call,callv,leave,
213    str,bitmanip,
214    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
215    sselog,sselog1,sseiadd,sseishft,sseimul,
216    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins,
217    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
218   (const_string "other"))
219
220 ;; Main data type used by the insn
221 (define_attr "mode"
222   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
223   (const_string "unknown"))
224
225 ;; The CPU unit operations uses.
226 (define_attr "unit" "integer,i387,sse,mmx,unknown"
227   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
228            (const_string "i387")
229          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
230                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins")
231            (const_string "sse")
232          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
233            (const_string "mmx")
234          (eq_attr "type" "other")
235            (const_string "unknown")]
236          (const_string "integer")))
237
238 ;; The (bounding maximum) length of an instruction immediate.
239 (define_attr "length_immediate" ""
240   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
241                           bitmanip")
242            (const_int 0)
243          (eq_attr "unit" "i387,sse,mmx")
244            (const_int 0)
245          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
246                           imul,icmp,push,pop")
247            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
248          (eq_attr "type" "imov,test")
249            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
250          (eq_attr "type" "call")
251            (if_then_else (match_operand 0 "constant_call_address_operand" "")
252              (const_int 4)
253              (const_int 0))
254          (eq_attr "type" "callv")
255            (if_then_else (match_operand 1 "constant_call_address_operand" "")
256              (const_int 4)
257              (const_int 0))
258          ;; We don't know the size before shorten_branches.  Expect
259          ;; the instruction to fit for better scheduling.
260          (eq_attr "type" "ibr")
261            (const_int 1)
262          ]
263          (symbol_ref "/* Update immediate_length and other attributes! */
264                       gcc_unreachable (),1")))
265
266 ;; The (bounding maximum) length of an instruction address.
267 (define_attr "length_address" ""
268   (cond [(eq_attr "type" "str,other,multi,fxch")
269            (const_int 0)
270          (and (eq_attr "type" "call")
271               (match_operand 0 "constant_call_address_operand" ""))
272              (const_int 0)
273          (and (eq_attr "type" "callv")
274               (match_operand 1 "constant_call_address_operand" ""))
275              (const_int 0)
276          ]
277          (symbol_ref "ix86_attr_length_address_default (insn)")))
278
279 ;; Set when length prefix is used.
280 (define_attr "prefix_data16" ""
281   (if_then_else (ior (eq_attr "mode" "HI")
282                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
283     (const_int 1)
284     (const_int 0)))
285
286 ;; Set when string REP prefix is used.
287 (define_attr "prefix_rep" ""
288   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
289     (const_int 1)
290     (const_int 0)))
291
292 ;; Set when 0f opcode prefix is used.
293 (define_attr "prefix_0f" ""
294   (if_then_else
295     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
296          (eq_attr "unit" "sse,mmx"))
297     (const_int 1)
298     (const_int 0)))
299
300 ;; Set when REX opcode prefix is used.
301 (define_attr "prefix_rex" ""
302   (cond [(and (eq_attr "mode" "DI")
303               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
304            (const_int 1)
305          (and (eq_attr "mode" "QI")
306               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
307                   (const_int 0)))
308            (const_int 1)
309          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
310              (const_int 0))
311            (const_int 1)
312         ]
313         (const_int 0)))
314
315 ;; Set when modrm byte is used.
316 (define_attr "modrm" ""
317   (cond [(eq_attr "type" "str,leave")
318            (const_int 0)
319          (eq_attr "unit" "i387")
320            (const_int 0)
321          (and (eq_attr "type" "incdec")
322               (ior (match_operand:SI 1 "register_operand" "")
323                    (match_operand:HI 1 "register_operand" "")))
324            (const_int 0)
325          (and (eq_attr "type" "push")
326               (not (match_operand 1 "memory_operand" "")))
327            (const_int 0)
328          (and (eq_attr "type" "pop")
329               (not (match_operand 0 "memory_operand" "")))
330            (const_int 0)
331          (and (eq_attr "type" "imov")
332               (ior (and (match_operand 0 "register_operand" "")
333                         (match_operand 1 "immediate_operand" ""))
334                    (ior (and (match_operand 0 "ax_reg_operand" "")
335                              (match_operand 1 "memory_displacement_only_operand" ""))
336                         (and (match_operand 0 "memory_displacement_only_operand" "")
337                              (match_operand 1 "ax_reg_operand" "")))))
338            (const_int 0)
339          (and (eq_attr "type" "call")
340               (match_operand 0 "constant_call_address_operand" ""))
341              (const_int 0)
342          (and (eq_attr "type" "callv")
343               (match_operand 1 "constant_call_address_operand" ""))
344              (const_int 0)
345          ]
346          (const_int 1)))
347
348 ;; The (bounding maximum) length of an instruction in bytes.
349 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
350 ;; Later we may want to split them and compute proper length as for
351 ;; other insns.
352 (define_attr "length" ""
353   (cond [(eq_attr "type" "other,multi,fistp,frndint")
354            (const_int 16)
355          (eq_attr "type" "fcmp")
356            (const_int 4)
357          (eq_attr "unit" "i387")
358            (plus (const_int 2)
359                  (plus (attr "prefix_data16")
360                        (attr "length_address")))]
361          (plus (plus (attr "modrm")
362                      (plus (attr "prefix_0f")
363                            (plus (attr "prefix_rex")
364                                  (const_int 1))))
365                (plus (attr "prefix_rep")
366                      (plus (attr "prefix_data16")
367                            (plus (attr "length_immediate")
368                                  (attr "length_address")))))))
369
370 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
371 ;; `store' if there is a simple memory reference therein, or `unknown'
372 ;; if the instruction is complex.
373
374 (define_attr "memory" "none,load,store,both,unknown"
375   (cond [(eq_attr "type" "other,multi,str")
376            (const_string "unknown")
377          (eq_attr "type" "lea,fcmov,fpspc")
378            (const_string "none")
379          (eq_attr "type" "fistp,leave")
380            (const_string "both")
381          (eq_attr "type" "frndint")
382            (const_string "load")
383          (eq_attr "type" "push")
384            (if_then_else (match_operand 1 "memory_operand" "")
385              (const_string "both")
386              (const_string "store"))
387          (eq_attr "type" "pop")
388            (if_then_else (match_operand 0 "memory_operand" "")
389              (const_string "both")
390              (const_string "load"))
391          (eq_attr "type" "setcc")
392            (if_then_else (match_operand 0 "memory_operand" "")
393              (const_string "store")
394              (const_string "none"))
395          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
396            (if_then_else (ior (match_operand 0 "memory_operand" "")
397                               (match_operand 1 "memory_operand" ""))
398              (const_string "load")
399              (const_string "none"))
400          (eq_attr "type" "ibr")
401            (if_then_else (match_operand 0 "memory_operand" "")
402              (const_string "load")
403              (const_string "none"))
404          (eq_attr "type" "call")
405            (if_then_else (match_operand 0 "constant_call_address_operand" "")
406              (const_string "none")
407              (const_string "load"))
408          (eq_attr "type" "callv")
409            (if_then_else (match_operand 1 "constant_call_address_operand" "")
410              (const_string "none")
411              (const_string "load"))
412          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
413               (match_operand 1 "memory_operand" ""))
414            (const_string "both")
415          (and (match_operand 0 "memory_operand" "")
416               (match_operand 1 "memory_operand" ""))
417            (const_string "both")
418          (match_operand 0 "memory_operand" "")
419            (const_string "store")
420          (match_operand 1 "memory_operand" "")
421            (const_string "load")
422          (and (eq_attr "type"
423                  "!alu1,negnot,ishift1,
424                    imov,imovx,icmp,test,bitmanip,
425                    fmov,fcmp,fsgn,
426                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
427                    mmx,mmxmov,mmxcmp,mmxcvt")
428               (match_operand 2 "memory_operand" ""))
429            (const_string "load")
430          (and (eq_attr "type" "icmov")
431               (match_operand 3 "memory_operand" ""))
432            (const_string "load")
433         ]
434         (const_string "none")))
435
436 ;; Indicates if an instruction has both an immediate and a displacement.
437
438 (define_attr "imm_disp" "false,true,unknown"
439   (cond [(eq_attr "type" "other,multi")
440            (const_string "unknown")
441          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
442               (and (match_operand 0 "memory_displacement_operand" "")
443                    (match_operand 1 "immediate_operand" "")))
444            (const_string "true")
445          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
446               (and (match_operand 0 "memory_displacement_operand" "")
447                    (match_operand 2 "immediate_operand" "")))
448            (const_string "true")
449         ]
450         (const_string "false")))
451
452 ;; Indicates if an FP operation has an integer source.
453
454 (define_attr "fp_int_src" "false,true"
455   (const_string "false"))
456
457 ;; Defines rounding mode of an FP operation.
458
459 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
460   (const_string "any"))
461
462 ;; Describe a user's asm statement.
463 (define_asm_attributes
464   [(set_attr "length" "128")
465    (set_attr "type" "multi")])
466
467 ;; All x87 floating point modes
468 (define_mode_macro X87MODEF [SF DF XF])
469
470 ;; x87 SFmode and DFMode floating point modes
471 (define_mode_macro X87MODEF12 [SF DF])
472
473 ;; All integer modes handled by x87 fisttp operator.
474 (define_mode_macro X87MODEI [HI SI DI])
475
476 ;; All integer modes handled by integer x87 operators.
477 (define_mode_macro X87MODEI12 [HI SI])
478
479 ;; All SSE floating point modes
480 (define_mode_macro SSEMODEF [SF DF])
481
482 ;; All integer modes handled by SSE cvtts?2si* operators.
483 (define_mode_macro SSEMODEI24 [SI DI])
484
485 ;; SSE asm suffix for floating point modes
486 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
487
488 ;; SSE vector mode corresponding to a scalar mode
489 (define_mode_attr ssevecmode
490   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
491 \f
492 ;; Scheduling descriptions
493
494 (include "pentium.md")
495 (include "ppro.md")
496 (include "k6.md")
497 (include "athlon.md")
498 (include "geode.md")
499
500 \f
501 ;; Operand and operator predicates and constraints
502
503 (include "predicates.md")
504 (include "constraints.md")
505
506 \f
507 ;; Compare instructions.
508
509 ;; All compare insns have expanders that save the operands away without
510 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
511 ;; after the cmp) will actually emit the cmpM.
512
513 (define_expand "cmpti"
514   [(set (reg:CC FLAGS_REG)
515         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
516                     (match_operand:TI 1 "x86_64_general_operand" "")))]
517   "TARGET_64BIT"
518 {
519   if (MEM_P (operands[0]) && MEM_P (operands[1]))
520     operands[0] = force_reg (TImode, operands[0]);
521   ix86_compare_op0 = operands[0];
522   ix86_compare_op1 = operands[1];
523   DONE;
524 })
525
526 (define_expand "cmpdi"
527   [(set (reg:CC FLAGS_REG)
528         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
529                     (match_operand:DI 1 "x86_64_general_operand" "")))]
530   ""
531 {
532   if (MEM_P (operands[0]) && MEM_P (operands[1]))
533     operands[0] = force_reg (DImode, operands[0]);
534   ix86_compare_op0 = operands[0];
535   ix86_compare_op1 = operands[1];
536   DONE;
537 })
538
539 (define_expand "cmpsi"
540   [(set (reg:CC FLAGS_REG)
541         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
542                     (match_operand:SI 1 "general_operand" "")))]
543   ""
544 {
545   if (MEM_P (operands[0]) && MEM_P (operands[1]))
546     operands[0] = force_reg (SImode, operands[0]);
547   ix86_compare_op0 = operands[0];
548   ix86_compare_op1 = operands[1];
549   DONE;
550 })
551
552 (define_expand "cmphi"
553   [(set (reg:CC FLAGS_REG)
554         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
555                     (match_operand:HI 1 "general_operand" "")))]
556   ""
557 {
558   if (MEM_P (operands[0]) && MEM_P (operands[1]))
559     operands[0] = force_reg (HImode, operands[0]);
560   ix86_compare_op0 = operands[0];
561   ix86_compare_op1 = operands[1];
562   DONE;
563 })
564
565 (define_expand "cmpqi"
566   [(set (reg:CC FLAGS_REG)
567         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
568                     (match_operand:QI 1 "general_operand" "")))]
569   "TARGET_QIMODE_MATH"
570 {
571   if (MEM_P (operands[0]) && MEM_P (operands[1]))
572     operands[0] = force_reg (QImode, operands[0]);
573   ix86_compare_op0 = operands[0];
574   ix86_compare_op1 = operands[1];
575   DONE;
576 })
577
578 (define_insn "cmpdi_ccno_1_rex64"
579   [(set (reg FLAGS_REG)
580         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
581                  (match_operand:DI 1 "const0_operand" "n,n")))]
582   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
583   "@
584    test{q}\t%0, %0
585    cmp{q}\t{%1, %0|%0, %1}"
586   [(set_attr "type" "test,icmp")
587    (set_attr "length_immediate" "0,1")
588    (set_attr "mode" "DI")])
589
590 (define_insn "*cmpdi_minus_1_rex64"
591   [(set (reg FLAGS_REG)
592         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
593                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
594                  (const_int 0)))]
595   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
596   "cmp{q}\t{%1, %0|%0, %1}"
597   [(set_attr "type" "icmp")
598    (set_attr "mode" "DI")])
599
600 (define_expand "cmpdi_1_rex64"
601   [(set (reg:CC FLAGS_REG)
602         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
603                     (match_operand:DI 1 "general_operand" "")))]
604   "TARGET_64BIT"
605   "")
606
607 (define_insn "cmpdi_1_insn_rex64"
608   [(set (reg FLAGS_REG)
609         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
610                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
611   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
612   "cmp{q}\t{%1, %0|%0, %1}"
613   [(set_attr "type" "icmp")
614    (set_attr "mode" "DI")])
615
616
617 (define_insn "*cmpsi_ccno_1"
618   [(set (reg FLAGS_REG)
619         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
620                  (match_operand:SI 1 "const0_operand" "n,n")))]
621   "ix86_match_ccmode (insn, CCNOmode)"
622   "@
623    test{l}\t%0, %0
624    cmp{l}\t{%1, %0|%0, %1}"
625   [(set_attr "type" "test,icmp")
626    (set_attr "length_immediate" "0,1")
627    (set_attr "mode" "SI")])
628
629 (define_insn "*cmpsi_minus_1"
630   [(set (reg FLAGS_REG)
631         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
632                            (match_operand:SI 1 "general_operand" "ri,mr"))
633                  (const_int 0)))]
634   "ix86_match_ccmode (insn, CCGOCmode)"
635   "cmp{l}\t{%1, %0|%0, %1}"
636   [(set_attr "type" "icmp")
637    (set_attr "mode" "SI")])
638
639 (define_expand "cmpsi_1"
640   [(set (reg:CC FLAGS_REG)
641         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
642                     (match_operand:SI 1 "general_operand" "ri,mr")))]
643   ""
644   "")
645
646 (define_insn "*cmpsi_1_insn"
647   [(set (reg FLAGS_REG)
648         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
649                  (match_operand:SI 1 "general_operand" "ri,mr")))]
650   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
651     && ix86_match_ccmode (insn, CCmode)"
652   "cmp{l}\t{%1, %0|%0, %1}"
653   [(set_attr "type" "icmp")
654    (set_attr "mode" "SI")])
655
656 (define_insn "*cmphi_ccno_1"
657   [(set (reg FLAGS_REG)
658         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
659                  (match_operand:HI 1 "const0_operand" "n,n")))]
660   "ix86_match_ccmode (insn, CCNOmode)"
661   "@
662    test{w}\t%0, %0
663    cmp{w}\t{%1, %0|%0, %1}"
664   [(set_attr "type" "test,icmp")
665    (set_attr "length_immediate" "0,1")
666    (set_attr "mode" "HI")])
667
668 (define_insn "*cmphi_minus_1"
669   [(set (reg FLAGS_REG)
670         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
671                            (match_operand:HI 1 "general_operand" "ri,mr"))
672                  (const_int 0)))]
673   "ix86_match_ccmode (insn, CCGOCmode)"
674   "cmp{w}\t{%1, %0|%0, %1}"
675   [(set_attr "type" "icmp")
676    (set_attr "mode" "HI")])
677
678 (define_insn "*cmphi_1"
679   [(set (reg FLAGS_REG)
680         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
681                  (match_operand:HI 1 "general_operand" "ri,mr")))]
682   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
683    && ix86_match_ccmode (insn, CCmode)"
684   "cmp{w}\t{%1, %0|%0, %1}"
685   [(set_attr "type" "icmp")
686    (set_attr "mode" "HI")])
687
688 (define_insn "*cmpqi_ccno_1"
689   [(set (reg FLAGS_REG)
690         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
691                  (match_operand:QI 1 "const0_operand" "n,n")))]
692   "ix86_match_ccmode (insn, CCNOmode)"
693   "@
694    test{b}\t%0, %0
695    cmp{b}\t{$0, %0|%0, 0}"
696   [(set_attr "type" "test,icmp")
697    (set_attr "length_immediate" "0,1")
698    (set_attr "mode" "QI")])
699
700 (define_insn "*cmpqi_1"
701   [(set (reg FLAGS_REG)
702         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
703                  (match_operand:QI 1 "general_operand" "qi,mq")))]
704   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
705     && ix86_match_ccmode (insn, CCmode)"
706   "cmp{b}\t{%1, %0|%0, %1}"
707   [(set_attr "type" "icmp")
708    (set_attr "mode" "QI")])
709
710 (define_insn "*cmpqi_minus_1"
711   [(set (reg FLAGS_REG)
712         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
713                            (match_operand:QI 1 "general_operand" "qi,mq"))
714                  (const_int 0)))]
715   "ix86_match_ccmode (insn, CCGOCmode)"
716   "cmp{b}\t{%1, %0|%0, %1}"
717   [(set_attr "type" "icmp")
718    (set_attr "mode" "QI")])
719
720 (define_insn "*cmpqi_ext_1"
721   [(set (reg FLAGS_REG)
722         (compare
723           (match_operand:QI 0 "general_operand" "Qm")
724           (subreg:QI
725             (zero_extract:SI
726               (match_operand 1 "ext_register_operand" "Q")
727               (const_int 8)
728               (const_int 8)) 0)))]
729   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
730   "cmp{b}\t{%h1, %0|%0, %h1}"
731   [(set_attr "type" "icmp")
732    (set_attr "mode" "QI")])
733
734 (define_insn "*cmpqi_ext_1_rex64"
735   [(set (reg FLAGS_REG)
736         (compare
737           (match_operand:QI 0 "register_operand" "Q")
738           (subreg:QI
739             (zero_extract:SI
740               (match_operand 1 "ext_register_operand" "Q")
741               (const_int 8)
742               (const_int 8)) 0)))]
743   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
744   "cmp{b}\t{%h1, %0|%0, %h1}"
745   [(set_attr "type" "icmp")
746    (set_attr "mode" "QI")])
747
748 (define_insn "*cmpqi_ext_2"
749   [(set (reg FLAGS_REG)
750         (compare
751           (subreg:QI
752             (zero_extract:SI
753               (match_operand 0 "ext_register_operand" "Q")
754               (const_int 8)
755               (const_int 8)) 0)
756           (match_operand:QI 1 "const0_operand" "n")))]
757   "ix86_match_ccmode (insn, CCNOmode)"
758   "test{b}\t%h0, %h0"
759   [(set_attr "type" "test")
760    (set_attr "length_immediate" "0")
761    (set_attr "mode" "QI")])
762
763 (define_expand "cmpqi_ext_3"
764   [(set (reg:CC FLAGS_REG)
765         (compare:CC
766           (subreg:QI
767             (zero_extract:SI
768               (match_operand 0 "ext_register_operand" "")
769               (const_int 8)
770               (const_int 8)) 0)
771           (match_operand:QI 1 "general_operand" "")))]
772   ""
773   "")
774
775 (define_insn "cmpqi_ext_3_insn"
776   [(set (reg FLAGS_REG)
777         (compare
778           (subreg:QI
779             (zero_extract:SI
780               (match_operand 0 "ext_register_operand" "Q")
781               (const_int 8)
782               (const_int 8)) 0)
783           (match_operand:QI 1 "general_operand" "Qmn")))]
784   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
785   "cmp{b}\t{%1, %h0|%h0, %1}"
786   [(set_attr "type" "icmp")
787    (set_attr "mode" "QI")])
788
789 (define_insn "cmpqi_ext_3_insn_rex64"
790   [(set (reg FLAGS_REG)
791         (compare
792           (subreg:QI
793             (zero_extract:SI
794               (match_operand 0 "ext_register_operand" "Q")
795               (const_int 8)
796               (const_int 8)) 0)
797           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
798   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
799   "cmp{b}\t{%1, %h0|%h0, %1}"
800   [(set_attr "type" "icmp")
801    (set_attr "mode" "QI")])
802
803 (define_insn "*cmpqi_ext_4"
804   [(set (reg FLAGS_REG)
805         (compare
806           (subreg:QI
807             (zero_extract:SI
808               (match_operand 0 "ext_register_operand" "Q")
809               (const_int 8)
810               (const_int 8)) 0)
811           (subreg:QI
812             (zero_extract:SI
813               (match_operand 1 "ext_register_operand" "Q")
814               (const_int 8)
815               (const_int 8)) 0)))]
816   "ix86_match_ccmode (insn, CCmode)"
817   "cmp{b}\t{%h1, %h0|%h0, %h1}"
818   [(set_attr "type" "icmp")
819    (set_attr "mode" "QI")])
820
821 ;; These implement float point compares.
822 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
823 ;; which would allow mix and match FP modes on the compares.  Which is what
824 ;; the old patterns did, but with many more of them.
825
826 (define_expand "cmpxf"
827   [(set (reg:CC FLAGS_REG)
828         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
829                     (match_operand:XF 1 "nonmemory_operand" "")))]
830   "TARGET_80387"
831 {
832   ix86_compare_op0 = operands[0];
833   ix86_compare_op1 = operands[1];
834   DONE;
835 })
836
837 (define_expand "cmpdf"
838   [(set (reg:CC FLAGS_REG)
839         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
840                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
841   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
842 {
843   ix86_compare_op0 = operands[0];
844   ix86_compare_op1 = operands[1];
845   DONE;
846 })
847
848 (define_expand "cmpsf"
849   [(set (reg:CC FLAGS_REG)
850         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
851                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
852   "TARGET_80387 || TARGET_SSE_MATH"
853 {
854   ix86_compare_op0 = operands[0];
855   ix86_compare_op1 = operands[1];
856   DONE;
857 })
858
859 ;; FP compares, step 1:
860 ;; Set the FP condition codes.
861 ;;
862 ;; CCFPmode     compare with exceptions
863 ;; CCFPUmode    compare with no exceptions
864
865 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
866 ;; used to manage the reg stack popping would not be preserved.
867
868 (define_insn "*cmpfp_0"
869   [(set (match_operand:HI 0 "register_operand" "=a")
870         (unspec:HI
871           [(compare:CCFP
872              (match_operand 1 "register_operand" "f")
873              (match_operand 2 "const0_operand" "X"))]
874         UNSPEC_FNSTSW))]
875   "TARGET_80387
876    && FLOAT_MODE_P (GET_MODE (operands[1]))
877    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
878   "* return output_fp_compare (insn, operands, 0, 0);"
879   [(set_attr "type" "multi")
880    (set_attr "unit" "i387")
881    (set (attr "mode")
882      (cond [(match_operand:SF 1 "" "")
883               (const_string "SF")
884             (match_operand:DF 1 "" "")
885               (const_string "DF")
886            ]
887            (const_string "XF")))])
888
889 (define_insn "*cmpfp_sf"
890   [(set (match_operand:HI 0 "register_operand" "=a")
891         (unspec:HI
892           [(compare:CCFP
893              (match_operand:SF 1 "register_operand" "f")
894              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
895           UNSPEC_FNSTSW))]
896   "TARGET_80387"
897   "* return output_fp_compare (insn, operands, 0, 0);"
898   [(set_attr "type" "multi")
899    (set_attr "unit" "i387")
900    (set_attr "mode" "SF")])
901
902 (define_insn "*cmpfp_df"
903   [(set (match_operand:HI 0 "register_operand" "=a")
904         (unspec:HI
905           [(compare:CCFP
906              (match_operand:DF 1 "register_operand" "f")
907              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
908           UNSPEC_FNSTSW))]
909   "TARGET_80387"
910   "* return output_fp_compare (insn, operands, 0, 0);"
911   [(set_attr "type" "multi")
912    (set_attr "unit" "i387")
913    (set_attr "mode" "DF")])
914
915 (define_insn "*cmpfp_xf"
916   [(set (match_operand:HI 0 "register_operand" "=a")
917         (unspec:HI
918           [(compare:CCFP
919              (match_operand:XF 1 "register_operand" "f")
920              (match_operand:XF 2 "register_operand" "f"))]
921           UNSPEC_FNSTSW))]
922   "TARGET_80387"
923   "* return output_fp_compare (insn, operands, 0, 0);"
924   [(set_attr "type" "multi")
925    (set_attr "unit" "i387")
926    (set_attr "mode" "XF")])
927
928 (define_insn "*cmpfp_u"
929   [(set (match_operand:HI 0 "register_operand" "=a")
930         (unspec:HI
931           [(compare:CCFPU
932              (match_operand 1 "register_operand" "f")
933              (match_operand 2 "register_operand" "f"))]
934           UNSPEC_FNSTSW))]
935   "TARGET_80387
936    && FLOAT_MODE_P (GET_MODE (operands[1]))
937    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
938   "* return output_fp_compare (insn, operands, 0, 1);"
939   [(set_attr "type" "multi")
940    (set_attr "unit" "i387")
941    (set (attr "mode")
942      (cond [(match_operand:SF 1 "" "")
943               (const_string "SF")
944             (match_operand:DF 1 "" "")
945               (const_string "DF")
946            ]
947            (const_string "XF")))])
948
949 (define_insn "*cmpfp_<mode>"
950   [(set (match_operand:HI 0 "register_operand" "=a")
951         (unspec:HI
952           [(compare:CCFP
953              (match_operand 1 "register_operand" "f")
954              (match_operator 3 "float_operator"
955                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
956           UNSPEC_FNSTSW))]
957   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
958    && FLOAT_MODE_P (GET_MODE (operands[1]))
959    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
960   "* return output_fp_compare (insn, operands, 0, 0);"
961   [(set_attr "type" "multi")
962    (set_attr "unit" "i387")
963    (set_attr "fp_int_src" "true")
964    (set_attr "mode" "<MODE>")])
965
966 ;; FP compares, step 2
967 ;; Move the fpsw to ax.
968
969 (define_insn "x86_fnstsw_1"
970   [(set (match_operand:HI 0 "register_operand" "=a")
971         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
972   "TARGET_80387"
973   "fnstsw\t%0"
974   [(set_attr "length" "2")
975    (set_attr "mode" "SI")
976    (set_attr "unit" "i387")])
977
978 ;; FP compares, step 3
979 ;; Get ax into flags, general case.
980
981 (define_insn "x86_sahf_1"
982   [(set (reg:CC FLAGS_REG)
983         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
984   "!TARGET_64BIT"
985   "sahf"
986   [(set_attr "length" "1")
987    (set_attr "athlon_decode" "vector")
988    (set_attr "amdfam10_decode" "direct")
989    (set_attr "mode" "SI")])
990
991 ;; Pentium Pro can do steps 1 through 3 in one go.
992 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes) 
993 (define_insn "*cmpfp_i_mixed"
994   [(set (reg:CCFP FLAGS_REG)
995         (compare:CCFP (match_operand 0 "register_operand" "f,x")
996                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
997   "TARGET_MIX_SSE_I387
998    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
999    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1000   "* return output_fp_compare (insn, operands, 1, 0);"
1001   [(set_attr "type" "fcmp,ssecomi")
1002    (set (attr "mode")
1003      (if_then_else (match_operand:SF 1 "" "")
1004         (const_string "SF")
1005         (const_string "DF")))
1006    (set_attr "athlon_decode" "vector")
1007    (set_attr "amdfam10_decode" "direct")])
1008
1009 (define_insn "*cmpfp_i_sse"
1010   [(set (reg:CCFP FLAGS_REG)
1011         (compare:CCFP (match_operand 0 "register_operand" "x")
1012                       (match_operand 1 "nonimmediate_operand" "xm")))]
1013   "TARGET_SSE_MATH
1014    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1015    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1016   "* return output_fp_compare (insn, operands, 1, 0);"
1017   [(set_attr "type" "ssecomi")
1018    (set (attr "mode")
1019      (if_then_else (match_operand:SF 1 "" "")
1020         (const_string "SF")
1021         (const_string "DF")))
1022    (set_attr "athlon_decode" "vector")
1023    (set_attr "amdfam10_decode" "direct")])
1024
1025 (define_insn "*cmpfp_i_i387"
1026   [(set (reg:CCFP FLAGS_REG)
1027         (compare:CCFP (match_operand 0 "register_operand" "f")
1028                       (match_operand 1 "register_operand" "f")))]
1029   "TARGET_80387 && TARGET_CMOVE
1030    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1031    && FLOAT_MODE_P (GET_MODE (operands[0]))
1032    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1033   "* return output_fp_compare (insn, operands, 1, 0);"
1034   [(set_attr "type" "fcmp")
1035    (set (attr "mode")
1036      (cond [(match_operand:SF 1 "" "")
1037               (const_string "SF")
1038             (match_operand:DF 1 "" "")
1039               (const_string "DF")
1040            ]
1041            (const_string "XF")))
1042    (set_attr "athlon_decode" "vector")
1043    (set_attr "amdfam10_decode" "direct")])
1044
1045 (define_insn "*cmpfp_iu_mixed"
1046   [(set (reg:CCFPU FLAGS_REG)
1047         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1048                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1049   "TARGET_MIX_SSE_I387
1050    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1051    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1052   "* return output_fp_compare (insn, operands, 1, 1);"
1053   [(set_attr "type" "fcmp,ssecomi")
1054    (set (attr "mode")
1055      (if_then_else (match_operand:SF 1 "" "")
1056         (const_string "SF")
1057         (const_string "DF")))
1058    (set_attr "athlon_decode" "vector")
1059    (set_attr "amdfam10_decode" "direct")])
1060
1061 (define_insn "*cmpfp_iu_sse"
1062   [(set (reg:CCFPU FLAGS_REG)
1063         (compare:CCFPU (match_operand 0 "register_operand" "x")
1064                        (match_operand 1 "nonimmediate_operand" "xm")))]
1065   "TARGET_SSE_MATH
1066    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1067    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1068   "* return output_fp_compare (insn, operands, 1, 1);"
1069   [(set_attr "type" "ssecomi")
1070    (set (attr "mode")
1071      (if_then_else (match_operand:SF 1 "" "")
1072         (const_string "SF")
1073         (const_string "DF")))
1074    (set_attr "athlon_decode" "vector")
1075    (set_attr "amdfam10_decode" "direct")])
1076
1077 (define_insn "*cmpfp_iu_387"
1078   [(set (reg:CCFPU FLAGS_REG)
1079         (compare:CCFPU (match_operand 0 "register_operand" "f")
1080                        (match_operand 1 "register_operand" "f")))]
1081   "TARGET_80387 && TARGET_CMOVE
1082    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1083    && FLOAT_MODE_P (GET_MODE (operands[0]))
1084    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1085   "* return output_fp_compare (insn, operands, 1, 1);"
1086   [(set_attr "type" "fcmp")
1087    (set (attr "mode")
1088      (cond [(match_operand:SF 1 "" "")
1089               (const_string "SF")
1090             (match_operand:DF 1 "" "")
1091               (const_string "DF")
1092            ]
1093            (const_string "XF")))
1094    (set_attr "athlon_decode" "vector")
1095    (set_attr "amdfam10_decode" "direct")])
1096 \f
1097 ;; Move instructions.
1098
1099 ;; General case of fullword move.
1100
1101 (define_expand "movsi"
1102   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1103         (match_operand:SI 1 "general_operand" ""))]
1104   ""
1105   "ix86_expand_move (SImode, operands); DONE;")
1106
1107 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1108 ;; general_operand.
1109 ;;
1110 ;; %%% We don't use a post-inc memory reference because x86 is not a
1111 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1112 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1113 ;; targets without our curiosities, and it is just as easy to represent
1114 ;; this differently.
1115
1116 (define_insn "*pushsi2"
1117   [(set (match_operand:SI 0 "push_operand" "=<")
1118         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1119   "!TARGET_64BIT"
1120   "push{l}\t%1"
1121   [(set_attr "type" "push")
1122    (set_attr "mode" "SI")])
1123
1124 ;; For 64BIT abi we always round up to 8 bytes.
1125 (define_insn "*pushsi2_rex64"
1126   [(set (match_operand:SI 0 "push_operand" "=X")
1127         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1128   "TARGET_64BIT"
1129   "push{q}\t%q1"
1130   [(set_attr "type" "push")
1131    (set_attr "mode" "SI")])
1132
1133 (define_insn "*pushsi2_prologue"
1134   [(set (match_operand:SI 0 "push_operand" "=<")
1135         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1136    (clobber (mem:BLK (scratch)))]
1137   "!TARGET_64BIT"
1138   "push{l}\t%1"
1139   [(set_attr "type" "push")
1140    (set_attr "mode" "SI")])
1141
1142 (define_insn "*popsi1_epilogue"
1143   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1144         (mem:SI (reg:SI SP_REG)))
1145    (set (reg:SI SP_REG)
1146         (plus:SI (reg:SI SP_REG) (const_int 4)))
1147    (clobber (mem:BLK (scratch)))]
1148   "!TARGET_64BIT"
1149   "pop{l}\t%0"
1150   [(set_attr "type" "pop")
1151    (set_attr "mode" "SI")])
1152
1153 (define_insn "popsi1"
1154   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1155         (mem:SI (reg:SI SP_REG)))
1156    (set (reg:SI SP_REG)
1157         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1158   "!TARGET_64BIT"
1159   "pop{l}\t%0"
1160   [(set_attr "type" "pop")
1161    (set_attr "mode" "SI")])
1162
1163 (define_insn "*movsi_xor"
1164   [(set (match_operand:SI 0 "register_operand" "=r")
1165         (match_operand:SI 1 "const0_operand" "i"))
1166    (clobber (reg:CC FLAGS_REG))]
1167   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1168   "xor{l}\t%0, %0"
1169   [(set_attr "type" "alu1")
1170    (set_attr "mode" "SI")
1171    (set_attr "length_immediate" "0")])
1172
1173 (define_insn "*movsi_or"
1174   [(set (match_operand:SI 0 "register_operand" "=r")
1175         (match_operand:SI 1 "immediate_operand" "i"))
1176    (clobber (reg:CC FLAGS_REG))]
1177   "reload_completed
1178    && operands[1] == constm1_rtx
1179    && (TARGET_PENTIUM || optimize_size)"
1180 {
1181   operands[1] = constm1_rtx;
1182   return "or{l}\t{%1, %0|%0, %1}";
1183 }
1184   [(set_attr "type" "alu1")
1185    (set_attr "mode" "SI")
1186    (set_attr "length_immediate" "1")])
1187
1188 (define_insn "*movsi_1"
1189   [(set (match_operand:SI 0 "nonimmediate_operand"
1190                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1191         (match_operand:SI 1 "general_operand"
1192                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1193   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1194 {
1195   switch (get_attr_type (insn))
1196     {
1197     case TYPE_SSELOG1:
1198       if (get_attr_mode (insn) == MODE_TI)
1199         return "pxor\t%0, %0";
1200       return "xorps\t%0, %0";
1201
1202     case TYPE_SSEMOV:
1203       switch (get_attr_mode (insn))
1204         {
1205         case MODE_TI:
1206           return "movdqa\t{%1, %0|%0, %1}";
1207         case MODE_V4SF:
1208           return "movaps\t{%1, %0|%0, %1}";
1209         case MODE_SI:
1210           return "movd\t{%1, %0|%0, %1}";
1211         case MODE_SF:
1212           return "movss\t{%1, %0|%0, %1}";
1213         default:
1214           gcc_unreachable ();
1215         }
1216
1217     case TYPE_MMXADD:
1218       return "pxor\t%0, %0";
1219
1220     case TYPE_MMXMOV:
1221       if (get_attr_mode (insn) == MODE_DI)
1222         return "movq\t{%1, %0|%0, %1}";
1223       return "movd\t{%1, %0|%0, %1}";
1224
1225     case TYPE_LEA:
1226       return "lea{l}\t{%1, %0|%0, %1}";
1227
1228     default:
1229       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1230       return "mov{l}\t{%1, %0|%0, %1}";
1231     }
1232 }
1233   [(set (attr "type")
1234      (cond [(eq_attr "alternative" "2")
1235               (const_string "mmxadd")
1236             (eq_attr "alternative" "3,4,5")
1237               (const_string "mmxmov")
1238             (eq_attr "alternative" "6")
1239               (const_string "sselog1")
1240             (eq_attr "alternative" "7,8,9,10,11")
1241               (const_string "ssemov")
1242             (match_operand:DI 1 "pic_32bit_operand" "")
1243               (const_string "lea")
1244            ]
1245            (const_string "imov")))
1246    (set (attr "mode")
1247      (cond [(eq_attr "alternative" "2,3")
1248               (const_string "DI")
1249             (eq_attr "alternative" "6,7")
1250               (if_then_else
1251                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1252                 (const_string "V4SF")
1253                 (const_string "TI"))
1254             (and (eq_attr "alternative" "8,9,10,11")
1255                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1256               (const_string "SF")
1257            ]
1258            (const_string "SI")))])
1259
1260 ;; Stores and loads of ax to arbitrary constant address.
1261 ;; We fake an second form of instruction to force reload to load address
1262 ;; into register when rax is not available
1263 (define_insn "*movabssi_1_rex64"
1264   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1265         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1266   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1267   "@
1268    movabs{l}\t{%1, %P0|%P0, %1}
1269    mov{l}\t{%1, %a0|%a0, %1}"
1270   [(set_attr "type" "imov")
1271    (set_attr "modrm" "0,*")
1272    (set_attr "length_address" "8,0")
1273    (set_attr "length_immediate" "0,*")
1274    (set_attr "memory" "store")
1275    (set_attr "mode" "SI")])
1276
1277 (define_insn "*movabssi_2_rex64"
1278   [(set (match_operand:SI 0 "register_operand" "=a,r")
1279         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1280   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1281   "@
1282    movabs{l}\t{%P1, %0|%0, %P1}
1283    mov{l}\t{%a1, %0|%0, %a1}"
1284   [(set_attr "type" "imov")
1285    (set_attr "modrm" "0,*")
1286    (set_attr "length_address" "8,0")
1287    (set_attr "length_immediate" "0")
1288    (set_attr "memory" "load")
1289    (set_attr "mode" "SI")])
1290
1291 (define_insn "*swapsi"
1292   [(set (match_operand:SI 0 "register_operand" "+r")
1293         (match_operand:SI 1 "register_operand" "+r"))
1294    (set (match_dup 1)
1295         (match_dup 0))]
1296   ""
1297   "xchg{l}\t%1, %0"
1298   [(set_attr "type" "imov")
1299    (set_attr "mode" "SI")
1300    (set_attr "pent_pair" "np")
1301    (set_attr "athlon_decode" "vector")
1302    (set_attr "amdfam10_decode" "double")])   
1303
1304 (define_expand "movhi"
1305   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1306         (match_operand:HI 1 "general_operand" ""))]
1307   ""
1308   "ix86_expand_move (HImode, operands); DONE;")
1309
1310 (define_insn "*pushhi2"
1311   [(set (match_operand:HI 0 "push_operand" "=X")
1312         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1313   "!TARGET_64BIT"
1314   "push{l}\t%k1"
1315   [(set_attr "type" "push")
1316    (set_attr "mode" "SI")])
1317
1318 ;; For 64BIT abi we always round up to 8 bytes.
1319 (define_insn "*pushhi2_rex64"
1320   [(set (match_operand:HI 0 "push_operand" "=X")
1321         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1322   "TARGET_64BIT"
1323   "push{q}\t%q1"
1324   [(set_attr "type" "push")
1325    (set_attr "mode" "DI")])
1326
1327 (define_insn "*movhi_1"
1328   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1329         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1330   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1331 {
1332   switch (get_attr_type (insn))
1333     {
1334     case TYPE_IMOVX:
1335       /* movzwl is faster than movw on p2 due to partial word stalls,
1336          though not as fast as an aligned movl.  */
1337       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1338     default:
1339       if (get_attr_mode (insn) == MODE_SI)
1340         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1341       else
1342         return "mov{w}\t{%1, %0|%0, %1}";
1343     }
1344 }
1345   [(set (attr "type")
1346      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1347               (const_string "imov")
1348             (and (eq_attr "alternative" "0")
1349                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1350                           (const_int 0))
1351                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1352                           (const_int 0))))
1353               (const_string "imov")
1354             (and (eq_attr "alternative" "1,2")
1355                  (match_operand:HI 1 "aligned_operand" ""))
1356               (const_string "imov")
1357             (and (ne (symbol_ref "TARGET_MOVX")
1358                      (const_int 0))
1359                  (eq_attr "alternative" "0,2"))
1360               (const_string "imovx")
1361            ]
1362            (const_string "imov")))
1363     (set (attr "mode")
1364       (cond [(eq_attr "type" "imovx")
1365                (const_string "SI")
1366              (and (eq_attr "alternative" "1,2")
1367                   (match_operand:HI 1 "aligned_operand" ""))
1368                (const_string "SI")
1369              (and (eq_attr "alternative" "0")
1370                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1371                            (const_int 0))
1372                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1373                            (const_int 0))))
1374                (const_string "SI")
1375             ]
1376             (const_string "HI")))])
1377
1378 ;; Stores and loads of ax to arbitrary constant address.
1379 ;; We fake an second form of instruction to force reload to load address
1380 ;; into register when rax is not available
1381 (define_insn "*movabshi_1_rex64"
1382   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1383         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1384   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1385   "@
1386    movabs{w}\t{%1, %P0|%P0, %1}
1387    mov{w}\t{%1, %a0|%a0, %1}"
1388   [(set_attr "type" "imov")
1389    (set_attr "modrm" "0,*")
1390    (set_attr "length_address" "8,0")
1391    (set_attr "length_immediate" "0,*")
1392    (set_attr "memory" "store")
1393    (set_attr "mode" "HI")])
1394
1395 (define_insn "*movabshi_2_rex64"
1396   [(set (match_operand:HI 0 "register_operand" "=a,r")
1397         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1398   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1399   "@
1400    movabs{w}\t{%P1, %0|%0, %P1}
1401    mov{w}\t{%a1, %0|%0, %a1}"
1402   [(set_attr "type" "imov")
1403    (set_attr "modrm" "0,*")
1404    (set_attr "length_address" "8,0")
1405    (set_attr "length_immediate" "0")
1406    (set_attr "memory" "load")
1407    (set_attr "mode" "HI")])
1408
1409 (define_insn "*swaphi_1"
1410   [(set (match_operand:HI 0 "register_operand" "+r")
1411         (match_operand:HI 1 "register_operand" "+r"))
1412    (set (match_dup 1)
1413         (match_dup 0))]
1414   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1415   "xchg{l}\t%k1, %k0"
1416   [(set_attr "type" "imov")
1417    (set_attr "mode" "SI")
1418    (set_attr "pent_pair" "np")
1419    (set_attr "athlon_decode" "vector")
1420    (set_attr "amdfam10_decode" "double")])   
1421
1422 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1423 (define_insn "*swaphi_2"
1424   [(set (match_operand:HI 0 "register_operand" "+r")
1425         (match_operand:HI 1 "register_operand" "+r"))
1426    (set (match_dup 1)
1427         (match_dup 0))]
1428   "TARGET_PARTIAL_REG_STALL"
1429   "xchg{w}\t%1, %0"
1430   [(set_attr "type" "imov")
1431    (set_attr "mode" "HI")
1432    (set_attr "pent_pair" "np")
1433    (set_attr "athlon_decode" "vector")])
1434
1435 (define_expand "movstricthi"
1436   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1437         (match_operand:HI 1 "general_operand" ""))]
1438   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1439 {
1440   /* Don't generate memory->memory moves, go through a register */
1441   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1442     operands[1] = force_reg (HImode, operands[1]);
1443 })
1444
1445 (define_insn "*movstricthi_1"
1446   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1447         (match_operand:HI 1 "general_operand" "rn,m"))]
1448   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1449    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1450   "mov{w}\t{%1, %0|%0, %1}"
1451   [(set_attr "type" "imov")
1452    (set_attr "mode" "HI")])
1453
1454 (define_insn "*movstricthi_xor"
1455   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1456         (match_operand:HI 1 "const0_operand" "i"))
1457    (clobber (reg:CC FLAGS_REG))]
1458   "reload_completed
1459    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1460   "xor{w}\t%0, %0"
1461   [(set_attr "type" "alu1")
1462    (set_attr "mode" "HI")
1463    (set_attr "length_immediate" "0")])
1464
1465 (define_expand "movqi"
1466   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1467         (match_operand:QI 1 "general_operand" ""))]
1468   ""
1469   "ix86_expand_move (QImode, operands); DONE;")
1470
1471 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1472 ;; "push a byte".  But actually we use pushl, which has the effect
1473 ;; of rounding the amount pushed up to a word.
1474
1475 (define_insn "*pushqi2"
1476   [(set (match_operand:QI 0 "push_operand" "=X")
1477         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1478   "!TARGET_64BIT"
1479   "push{l}\t%k1"
1480   [(set_attr "type" "push")
1481    (set_attr "mode" "SI")])
1482
1483 ;; For 64BIT abi we always round up to 8 bytes.
1484 (define_insn "*pushqi2_rex64"
1485   [(set (match_operand:QI 0 "push_operand" "=X")
1486         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1487   "TARGET_64BIT"
1488   "push{q}\t%q1"
1489   [(set_attr "type" "push")
1490    (set_attr "mode" "DI")])
1491
1492 ;; Situation is quite tricky about when to choose full sized (SImode) move
1493 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1494 ;; partial register dependency machines (such as AMD Athlon), where QImode
1495 ;; moves issue extra dependency and for partial register stalls machines
1496 ;; that don't use QImode patterns (and QImode move cause stall on the next
1497 ;; instruction).
1498 ;;
1499 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1500 ;; register stall machines with, where we use QImode instructions, since
1501 ;; partial register stall can be caused there.  Then we use movzx.
1502 (define_insn "*movqi_1"
1503   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1504         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1505   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1506 {
1507   switch (get_attr_type (insn))
1508     {
1509     case TYPE_IMOVX:
1510       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1511       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1512     default:
1513       if (get_attr_mode (insn) == MODE_SI)
1514         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1515       else
1516         return "mov{b}\t{%1, %0|%0, %1}";
1517     }
1518 }
1519   [(set (attr "type")
1520      (cond [(and (eq_attr "alternative" "5")
1521                  (not (match_operand:QI 1 "aligned_operand" "")))
1522               (const_string "imovx")
1523             (ne (symbol_ref "optimize_size") (const_int 0))
1524               (const_string "imov")
1525             (and (eq_attr "alternative" "3")
1526                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1527                           (const_int 0))
1528                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1529                           (const_int 0))))
1530               (const_string "imov")
1531             (eq_attr "alternative" "3,5")
1532               (const_string "imovx")
1533             (and (ne (symbol_ref "TARGET_MOVX")
1534                      (const_int 0))
1535                  (eq_attr "alternative" "2"))
1536               (const_string "imovx")
1537            ]
1538            (const_string "imov")))
1539    (set (attr "mode")
1540       (cond [(eq_attr "alternative" "3,4,5")
1541                (const_string "SI")
1542              (eq_attr "alternative" "6")
1543                (const_string "QI")
1544              (eq_attr "type" "imovx")
1545                (const_string "SI")
1546              (and (eq_attr "type" "imov")
1547                   (and (eq_attr "alternative" "0,1")
1548                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1549                                 (const_int 0))
1550                             (and (eq (symbol_ref "optimize_size")
1551                                      (const_int 0))
1552                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1553                                      (const_int 0))))))
1554                (const_string "SI")
1555              ;; Avoid partial register stalls when not using QImode arithmetic
1556              (and (eq_attr "type" "imov")
1557                   (and (eq_attr "alternative" "0,1")
1558                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1559                                 (const_int 0))
1560                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1561                                 (const_int 0)))))
1562                (const_string "SI")
1563            ]
1564            (const_string "QI")))])
1565
1566 (define_expand "reload_outqi"
1567   [(parallel [(match_operand:QI 0 "" "=m")
1568               (match_operand:QI 1 "register_operand" "r")
1569               (match_operand:QI 2 "register_operand" "=&q")])]
1570   ""
1571 {
1572   rtx op0, op1, op2;
1573   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1574
1575   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1576   if (! q_regs_operand (op1, QImode))
1577     {
1578       emit_insn (gen_movqi (op2, op1));
1579       op1 = op2;
1580     }
1581   emit_insn (gen_movqi (op0, op1));
1582   DONE;
1583 })
1584
1585 (define_insn "*swapqi_1"
1586   [(set (match_operand:QI 0 "register_operand" "+r")
1587         (match_operand:QI 1 "register_operand" "+r"))
1588    (set (match_dup 1)
1589         (match_dup 0))]
1590   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1591   "xchg{l}\t%k1, %k0"
1592   [(set_attr "type" "imov")
1593    (set_attr "mode" "SI")
1594    (set_attr "pent_pair" "np")
1595    (set_attr "athlon_decode" "vector")
1596    (set_attr "amdfam10_decode" "vector")])   
1597
1598 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1599 (define_insn "*swapqi_2"
1600   [(set (match_operand:QI 0 "register_operand" "+q")
1601         (match_operand:QI 1 "register_operand" "+q"))
1602    (set (match_dup 1)
1603         (match_dup 0))]
1604   "TARGET_PARTIAL_REG_STALL"
1605   "xchg{b}\t%1, %0"
1606   [(set_attr "type" "imov")
1607    (set_attr "mode" "QI")
1608    (set_attr "pent_pair" "np")
1609    (set_attr "athlon_decode" "vector")])
1610
1611 (define_expand "movstrictqi"
1612   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1613         (match_operand:QI 1 "general_operand" ""))]
1614   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1615 {
1616   /* Don't generate memory->memory moves, go through a register.  */
1617   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1618     operands[1] = force_reg (QImode, operands[1]);
1619 })
1620
1621 (define_insn "*movstrictqi_1"
1622   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1623         (match_operand:QI 1 "general_operand" "*qn,m"))]
1624   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1625    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1626   "mov{b}\t{%1, %0|%0, %1}"
1627   [(set_attr "type" "imov")
1628    (set_attr "mode" "QI")])
1629
1630 (define_insn "*movstrictqi_xor"
1631   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1632         (match_operand:QI 1 "const0_operand" "i"))
1633    (clobber (reg:CC FLAGS_REG))]
1634   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1635   "xor{b}\t%0, %0"
1636   [(set_attr "type" "alu1")
1637    (set_attr "mode" "QI")
1638    (set_attr "length_immediate" "0")])
1639
1640 (define_insn "*movsi_extv_1"
1641   [(set (match_operand:SI 0 "register_operand" "=R")
1642         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1643                          (const_int 8)
1644                          (const_int 8)))]
1645   ""
1646   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1647   [(set_attr "type" "imovx")
1648    (set_attr "mode" "SI")])
1649
1650 (define_insn "*movhi_extv_1"
1651   [(set (match_operand:HI 0 "register_operand" "=R")
1652         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1653                          (const_int 8)
1654                          (const_int 8)))]
1655   ""
1656   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1657   [(set_attr "type" "imovx")
1658    (set_attr "mode" "SI")])
1659
1660 (define_insn "*movqi_extv_1"
1661   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1662         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1663                          (const_int 8)
1664                          (const_int 8)))]
1665   "!TARGET_64BIT"
1666 {
1667   switch (get_attr_type (insn))
1668     {
1669     case TYPE_IMOVX:
1670       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1671     default:
1672       return "mov{b}\t{%h1, %0|%0, %h1}";
1673     }
1674 }
1675   [(set (attr "type")
1676      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1677                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1678                              (ne (symbol_ref "TARGET_MOVX")
1679                                  (const_int 0))))
1680         (const_string "imovx")
1681         (const_string "imov")))
1682    (set (attr "mode")
1683      (if_then_else (eq_attr "type" "imovx")
1684         (const_string "SI")
1685         (const_string "QI")))])
1686
1687 (define_insn "*movqi_extv_1_rex64"
1688   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1689         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1690                          (const_int 8)
1691                          (const_int 8)))]
1692   "TARGET_64BIT"
1693 {
1694   switch (get_attr_type (insn))
1695     {
1696     case TYPE_IMOVX:
1697       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1698     default:
1699       return "mov{b}\t{%h1, %0|%0, %h1}";
1700     }
1701 }
1702   [(set (attr "type")
1703      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1704                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1705                              (ne (symbol_ref "TARGET_MOVX")
1706                                  (const_int 0))))
1707         (const_string "imovx")
1708         (const_string "imov")))
1709    (set (attr "mode")
1710      (if_then_else (eq_attr "type" "imovx")
1711         (const_string "SI")
1712         (const_string "QI")))])
1713
1714 ;; Stores and loads of ax to arbitrary constant address.
1715 ;; We fake an second form of instruction to force reload to load address
1716 ;; into register when rax is not available
1717 (define_insn "*movabsqi_1_rex64"
1718   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1719         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1720   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1721   "@
1722    movabs{b}\t{%1, %P0|%P0, %1}
1723    mov{b}\t{%1, %a0|%a0, %1}"
1724   [(set_attr "type" "imov")
1725    (set_attr "modrm" "0,*")
1726    (set_attr "length_address" "8,0")
1727    (set_attr "length_immediate" "0,*")
1728    (set_attr "memory" "store")
1729    (set_attr "mode" "QI")])
1730
1731 (define_insn "*movabsqi_2_rex64"
1732   [(set (match_operand:QI 0 "register_operand" "=a,r")
1733         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1734   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1735   "@
1736    movabs{b}\t{%P1, %0|%0, %P1}
1737    mov{b}\t{%a1, %0|%0, %a1}"
1738   [(set_attr "type" "imov")
1739    (set_attr "modrm" "0,*")
1740    (set_attr "length_address" "8,0")
1741    (set_attr "length_immediate" "0")
1742    (set_attr "memory" "load")
1743    (set_attr "mode" "QI")])
1744
1745 (define_insn "*movdi_extzv_1"
1746   [(set (match_operand:DI 0 "register_operand" "=R")
1747         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1748                          (const_int 8)
1749                          (const_int 8)))]
1750   "TARGET_64BIT"
1751   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1752   [(set_attr "type" "imovx")
1753    (set_attr "mode" "DI")])
1754
1755 (define_insn "*movsi_extzv_1"
1756   [(set (match_operand:SI 0 "register_operand" "=R")
1757         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1758                          (const_int 8)
1759                          (const_int 8)))]
1760   ""
1761   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1762   [(set_attr "type" "imovx")
1763    (set_attr "mode" "SI")])
1764
1765 (define_insn "*movqi_extzv_2"
1766   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1767         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1768                                     (const_int 8)
1769                                     (const_int 8)) 0))]
1770   "!TARGET_64BIT"
1771 {
1772   switch (get_attr_type (insn))
1773     {
1774     case TYPE_IMOVX:
1775       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1776     default:
1777       return "mov{b}\t{%h1, %0|%0, %h1}";
1778     }
1779 }
1780   [(set (attr "type")
1781      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1782                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1783                              (ne (symbol_ref "TARGET_MOVX")
1784                                  (const_int 0))))
1785         (const_string "imovx")
1786         (const_string "imov")))
1787    (set (attr "mode")
1788      (if_then_else (eq_attr "type" "imovx")
1789         (const_string "SI")
1790         (const_string "QI")))])
1791
1792 (define_insn "*movqi_extzv_2_rex64"
1793   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1794         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1795                                     (const_int 8)
1796                                     (const_int 8)) 0))]
1797   "TARGET_64BIT"
1798 {
1799   switch (get_attr_type (insn))
1800     {
1801     case TYPE_IMOVX:
1802       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1803     default:
1804       return "mov{b}\t{%h1, %0|%0, %h1}";
1805     }
1806 }
1807   [(set (attr "type")
1808      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1809                         (ne (symbol_ref "TARGET_MOVX")
1810                             (const_int 0)))
1811         (const_string "imovx")
1812         (const_string "imov")))
1813    (set (attr "mode")
1814      (if_then_else (eq_attr "type" "imovx")
1815         (const_string "SI")
1816         (const_string "QI")))])
1817
1818 (define_insn "movsi_insv_1"
1819   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1820                          (const_int 8)
1821                          (const_int 8))
1822         (match_operand:SI 1 "general_operand" "Qmn"))]
1823   "!TARGET_64BIT"
1824   "mov{b}\t{%b1, %h0|%h0, %b1}"
1825   [(set_attr "type" "imov")
1826    (set_attr "mode" "QI")])
1827
1828 (define_insn "*movsi_insv_1_rex64"
1829   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1830                          (const_int 8)
1831                          (const_int 8))
1832         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1833   "TARGET_64BIT"
1834   "mov{b}\t{%b1, %h0|%h0, %b1}"
1835   [(set_attr "type" "imov")
1836    (set_attr "mode" "QI")])
1837
1838 (define_insn "movdi_insv_1_rex64"
1839   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1840                          (const_int 8)
1841                          (const_int 8))
1842         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1843   "TARGET_64BIT"
1844   "mov{b}\t{%b1, %h0|%h0, %b1}"
1845   [(set_attr "type" "imov")
1846    (set_attr "mode" "QI")])
1847
1848 (define_insn "*movqi_insv_2"
1849   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1850                          (const_int 8)
1851                          (const_int 8))
1852         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1853                      (const_int 8)))]
1854   ""
1855   "mov{b}\t{%h1, %h0|%h0, %h1}"
1856   [(set_attr "type" "imov")
1857    (set_attr "mode" "QI")])
1858
1859 (define_expand "movdi"
1860   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1861         (match_operand:DI 1 "general_operand" ""))]
1862   ""
1863   "ix86_expand_move (DImode, operands); DONE;")
1864
1865 (define_insn "*pushdi"
1866   [(set (match_operand:DI 0 "push_operand" "=<")
1867         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1868   "!TARGET_64BIT"
1869   "#")
1870
1871 (define_insn "*pushdi2_rex64"
1872   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1873         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1874   "TARGET_64BIT"
1875   "@
1876    push{q}\t%1
1877    #"
1878   [(set_attr "type" "push,multi")
1879    (set_attr "mode" "DI")])
1880
1881 ;; Convert impossible pushes of immediate to existing instructions.
1882 ;; First try to get scratch register and go through it.  In case this
1883 ;; fails, push sign extended lower part first and then overwrite
1884 ;; upper part by 32bit move.
1885 (define_peephole2
1886   [(match_scratch:DI 2 "r")
1887    (set (match_operand:DI 0 "push_operand" "")
1888         (match_operand:DI 1 "immediate_operand" ""))]
1889   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1890    && !x86_64_immediate_operand (operands[1], DImode)"
1891   [(set (match_dup 2) (match_dup 1))
1892    (set (match_dup 0) (match_dup 2))]
1893   "")
1894
1895 ;; We need to define this as both peepholer and splitter for case
1896 ;; peephole2 pass is not run.
1897 ;; "&& 1" is needed to keep it from matching the previous pattern.
1898 (define_peephole2
1899   [(set (match_operand:DI 0 "push_operand" "")
1900         (match_operand:DI 1 "immediate_operand" ""))]
1901   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1902    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1903   [(set (match_dup 0) (match_dup 1))
1904    (set (match_dup 2) (match_dup 3))]
1905   "split_di (operands + 1, 1, operands + 2, operands + 3);
1906    operands[1] = gen_lowpart (DImode, operands[2]);
1907    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1908                                                     GEN_INT (4)));
1909   ")
1910
1911 (define_split
1912   [(set (match_operand:DI 0 "push_operand" "")
1913         (match_operand:DI 1 "immediate_operand" ""))]
1914   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1915                     ? flow2_completed : reload_completed)
1916    && !symbolic_operand (operands[1], DImode)
1917    && !x86_64_immediate_operand (operands[1], DImode)"
1918   [(set (match_dup 0) (match_dup 1))
1919    (set (match_dup 2) (match_dup 3))]
1920   "split_di (operands + 1, 1, operands + 2, operands + 3);
1921    operands[1] = gen_lowpart (DImode, operands[2]);
1922    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1923                                                     GEN_INT (4)));
1924   ")
1925
1926 (define_insn "*pushdi2_prologue_rex64"
1927   [(set (match_operand:DI 0 "push_operand" "=<")
1928         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1929    (clobber (mem:BLK (scratch)))]
1930   "TARGET_64BIT"
1931   "push{q}\t%1"
1932   [(set_attr "type" "push")
1933    (set_attr "mode" "DI")])
1934
1935 (define_insn "*popdi1_epilogue_rex64"
1936   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1937         (mem:DI (reg:DI SP_REG)))
1938    (set (reg:DI SP_REG)
1939         (plus:DI (reg:DI SP_REG) (const_int 8)))
1940    (clobber (mem:BLK (scratch)))]
1941   "TARGET_64BIT"
1942   "pop{q}\t%0"
1943   [(set_attr "type" "pop")
1944    (set_attr "mode" "DI")])
1945
1946 (define_insn "popdi1"
1947   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1948         (mem:DI (reg:DI SP_REG)))
1949    (set (reg:DI SP_REG)
1950         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1951   "TARGET_64BIT"
1952   "pop{q}\t%0"
1953   [(set_attr "type" "pop")
1954    (set_attr "mode" "DI")])
1955
1956 (define_insn "*movdi_xor_rex64"
1957   [(set (match_operand:DI 0 "register_operand" "=r")
1958         (match_operand:DI 1 "const0_operand" "i"))
1959    (clobber (reg:CC FLAGS_REG))]
1960   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1961    && reload_completed"
1962   "xor{l}\t%k0, %k0";
1963   [(set_attr "type" "alu1")
1964    (set_attr "mode" "SI")
1965    (set_attr "length_immediate" "0")])
1966
1967 (define_insn "*movdi_or_rex64"
1968   [(set (match_operand:DI 0 "register_operand" "=r")
1969         (match_operand:DI 1 "const_int_operand" "i"))
1970    (clobber (reg:CC FLAGS_REG))]
1971   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1972    && reload_completed
1973    && operands[1] == constm1_rtx"
1974 {
1975   operands[1] = constm1_rtx;
1976   return "or{q}\t{%1, %0|%0, %1}";
1977 }
1978   [(set_attr "type" "alu1")
1979    (set_attr "mode" "DI")
1980    (set_attr "length_immediate" "1")])
1981
1982 (define_insn "*movdi_2"
1983   [(set (match_operand:DI 0 "nonimmediate_operand"
1984                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
1985         (match_operand:DI 1 "general_operand"
1986                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
1987   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1988   "@
1989    #
1990    #
1991    pxor\t%0, %0
1992    movq\t{%1, %0|%0, %1}
1993    movq\t{%1, %0|%0, %1}
1994    pxor\t%0, %0
1995    movq\t{%1, %0|%0, %1}
1996    movdqa\t{%1, %0|%0, %1}
1997    movq\t{%1, %0|%0, %1}
1998    xorps\t%0, %0
1999    movlps\t{%1, %0|%0, %1}
2000    movaps\t{%1, %0|%0, %1}
2001    movlps\t{%1, %0|%0, %1}"
2002   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2003    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2004
2005 (define_split
2006   [(set (match_operand:DI 0 "push_operand" "")
2007         (match_operand:DI 1 "general_operand" ""))]
2008   "!TARGET_64BIT && reload_completed
2009    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2010   [(const_int 0)]
2011   "ix86_split_long_move (operands); DONE;")
2012
2013 ;; %%% This multiword shite has got to go.
2014 (define_split
2015   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2016         (match_operand:DI 1 "general_operand" ""))]
2017   "!TARGET_64BIT && reload_completed
2018    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2019    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2020   [(const_int 0)]
2021   "ix86_split_long_move (operands); DONE;")
2022
2023 (define_insn "*movdi_1_rex64"
2024   [(set (match_operand:DI 0 "nonimmediate_operand"
2025           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2026         (match_operand:DI 1 "general_operand"
2027           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2028   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2029 {
2030   switch (get_attr_type (insn))
2031     {
2032     case TYPE_SSECVT:
2033       if (SSE_REG_P (operands[0]))
2034         return "movq2dq\t{%1, %0|%0, %1}";
2035       else
2036         return "movdq2q\t{%1, %0|%0, %1}";
2037
2038     case TYPE_SSEMOV:
2039       if (get_attr_mode (insn) == MODE_TI)
2040         return "movdqa\t{%1, %0|%0, %1}";
2041       /* FALLTHRU */
2042
2043     case TYPE_MMXMOV:
2044       /* Moves from and into integer register is done using movd
2045          opcode with REX prefix.  */
2046       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2047         return "movd\t{%1, %0|%0, %1}";
2048       return "movq\t{%1, %0|%0, %1}";
2049
2050     case TYPE_SSELOG1:
2051     case TYPE_MMXADD:
2052       return "pxor\t%0, %0";
2053
2054     case TYPE_MULTI:
2055       return "#";
2056
2057     case TYPE_LEA:
2058       return "lea{q}\t{%a1, %0|%0, %a1}";
2059
2060     default:
2061       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2062       if (get_attr_mode (insn) == MODE_SI)
2063         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2064       else if (which_alternative == 2)
2065         return "movabs{q}\t{%1, %0|%0, %1}";
2066       else
2067         return "mov{q}\t{%1, %0|%0, %1}";
2068     }
2069 }
2070   [(set (attr "type")
2071      (cond [(eq_attr "alternative" "5")
2072               (const_string "mmxadd")
2073             (eq_attr "alternative" "6,7,8,9,10")
2074               (const_string "mmxmov")
2075             (eq_attr "alternative" "11")
2076               (const_string "sselog1")
2077             (eq_attr "alternative" "12,13,14,15,16")
2078               (const_string "ssemov")
2079             (eq_attr "alternative" "17,18")
2080               (const_string "ssecvt")
2081             (eq_attr "alternative" "4")
2082               (const_string "multi")
2083             (match_operand:DI 1 "pic_32bit_operand" "")
2084               (const_string "lea")
2085            ]
2086            (const_string "imov")))
2087    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2088    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2089    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2090
2091 ;; Stores and loads of ax to arbitrary constant address.
2092 ;; We fake an second form of instruction to force reload to load address
2093 ;; into register when rax is not available
2094 (define_insn "*movabsdi_1_rex64"
2095   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2096         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2097   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2098   "@
2099    movabs{q}\t{%1, %P0|%P0, %1}
2100    mov{q}\t{%1, %a0|%a0, %1}"
2101   [(set_attr "type" "imov")
2102    (set_attr "modrm" "0,*")
2103    (set_attr "length_address" "8,0")
2104    (set_attr "length_immediate" "0,*")
2105    (set_attr "memory" "store")
2106    (set_attr "mode" "DI")])
2107
2108 (define_insn "*movabsdi_2_rex64"
2109   [(set (match_operand:DI 0 "register_operand" "=a,r")
2110         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2111   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2112   "@
2113    movabs{q}\t{%P1, %0|%0, %P1}
2114    mov{q}\t{%a1, %0|%0, %a1}"
2115   [(set_attr "type" "imov")
2116    (set_attr "modrm" "0,*")
2117    (set_attr "length_address" "8,0")
2118    (set_attr "length_immediate" "0")
2119    (set_attr "memory" "load")
2120    (set_attr "mode" "DI")])
2121
2122 ;; Convert impossible stores of immediate to existing instructions.
2123 ;; First try to get scratch register and go through it.  In case this
2124 ;; fails, move by 32bit parts.
2125 (define_peephole2
2126   [(match_scratch:DI 2 "r")
2127    (set (match_operand:DI 0 "memory_operand" "")
2128         (match_operand:DI 1 "immediate_operand" ""))]
2129   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2130    && !x86_64_immediate_operand (operands[1], DImode)"
2131   [(set (match_dup 2) (match_dup 1))
2132    (set (match_dup 0) (match_dup 2))]
2133   "")
2134
2135 ;; We need to define this as both peepholer and splitter for case
2136 ;; peephole2 pass is not run.
2137 ;; "&& 1" is needed to keep it from matching the previous pattern.
2138 (define_peephole2
2139   [(set (match_operand:DI 0 "memory_operand" "")
2140         (match_operand:DI 1 "immediate_operand" ""))]
2141   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2142    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2143   [(set (match_dup 2) (match_dup 3))
2144    (set (match_dup 4) (match_dup 5))]
2145   "split_di (operands, 2, operands + 2, operands + 4);")
2146
2147 (define_split
2148   [(set (match_operand:DI 0 "memory_operand" "")
2149         (match_operand:DI 1 "immediate_operand" ""))]
2150   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2151                     ? flow2_completed : reload_completed)
2152    && !symbolic_operand (operands[1], DImode)
2153    && !x86_64_immediate_operand (operands[1], DImode)"
2154   [(set (match_dup 2) (match_dup 3))
2155    (set (match_dup 4) (match_dup 5))]
2156   "split_di (operands, 2, operands + 2, operands + 4);")
2157
2158 (define_insn "*swapdi_rex64"
2159   [(set (match_operand:DI 0 "register_operand" "+r")
2160         (match_operand:DI 1 "register_operand" "+r"))
2161    (set (match_dup 1)
2162         (match_dup 0))]
2163   "TARGET_64BIT"
2164   "xchg{q}\t%1, %0"
2165   [(set_attr "type" "imov")
2166    (set_attr "mode" "DI")
2167    (set_attr "pent_pair" "np")
2168    (set_attr "athlon_decode" "vector")
2169    (set_attr "amdfam10_decode" "double")])   
2170
2171 (define_expand "movti"
2172   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2173         (match_operand:TI 1 "nonimmediate_operand" ""))]
2174   "TARGET_SSE || TARGET_64BIT"
2175 {
2176   if (TARGET_64BIT)
2177     ix86_expand_move (TImode, operands);
2178   else
2179     ix86_expand_vector_move (TImode, operands);
2180   DONE;
2181 })
2182
2183 (define_insn "*movti_internal"
2184   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2185         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2186   "TARGET_SSE && !TARGET_64BIT
2187    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2188 {
2189   switch (which_alternative)
2190     {
2191     case 0:
2192       if (get_attr_mode (insn) == MODE_V4SF)
2193         return "xorps\t%0, %0";
2194       else
2195         return "pxor\t%0, %0";
2196     case 1:
2197     case 2:
2198       if (get_attr_mode (insn) == MODE_V4SF)
2199         return "movaps\t{%1, %0|%0, %1}";
2200       else
2201         return "movdqa\t{%1, %0|%0, %1}";
2202     default:
2203       gcc_unreachable ();
2204     }
2205 }
2206   [(set_attr "type" "sselog1,ssemov,ssemov")
2207    (set (attr "mode")
2208         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2209                     (ne (symbol_ref "optimize_size") (const_int 0)))
2210                  (const_string "V4SF")
2211                (and (eq_attr "alternative" "2")
2212                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2213                         (const_int 0)))
2214                  (const_string "V4SF")]
2215               (const_string "TI")))])
2216
2217 (define_insn "*movti_rex64"
2218   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2219         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2220   "TARGET_64BIT
2221    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2222 {
2223   switch (which_alternative)
2224     {
2225     case 0:
2226     case 1:
2227       return "#";
2228     case 2:
2229       if (get_attr_mode (insn) == MODE_V4SF)
2230         return "xorps\t%0, %0";
2231       else
2232         return "pxor\t%0, %0";
2233     case 3:
2234     case 4:
2235       if (get_attr_mode (insn) == MODE_V4SF)
2236         return "movaps\t{%1, %0|%0, %1}";
2237       else
2238         return "movdqa\t{%1, %0|%0, %1}";
2239     default:
2240       gcc_unreachable ();
2241     }
2242 }
2243   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2244    (set (attr "mode")
2245         (cond [(eq_attr "alternative" "2,3")
2246                  (if_then_else
2247                    (ne (symbol_ref "optimize_size")
2248                        (const_int 0))
2249                    (const_string "V4SF")
2250                    (const_string "TI"))
2251                (eq_attr "alternative" "4")
2252                  (if_then_else
2253                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2254                             (const_int 0))
2255                         (ne (symbol_ref "optimize_size")
2256                             (const_int 0)))
2257                    (const_string "V4SF")
2258                    (const_string "TI"))]
2259                (const_string "DI")))])
2260
2261 (define_split
2262   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2263         (match_operand:TI 1 "general_operand" ""))]
2264   "reload_completed && !SSE_REG_P (operands[0])
2265    && !SSE_REG_P (operands[1])"
2266   [(const_int 0)]
2267   "ix86_split_long_move (operands); DONE;")
2268
2269 (define_expand "movsf"
2270   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2271         (match_operand:SF 1 "general_operand" ""))]
2272   ""
2273   "ix86_expand_move (SFmode, operands); DONE;")
2274
2275 (define_insn "*pushsf"
2276   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2277         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2278   "!TARGET_64BIT"
2279 {
2280   /* Anything else should be already split before reg-stack.  */
2281   gcc_assert (which_alternative == 1);
2282   return "push{l}\t%1";
2283 }
2284   [(set_attr "type" "multi,push,multi")
2285    (set_attr "unit" "i387,*,*")
2286    (set_attr "mode" "SF,SI,SF")])
2287
2288 (define_insn "*pushsf_rex64"
2289   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2290         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2291   "TARGET_64BIT"
2292 {
2293   /* Anything else should be already split before reg-stack.  */
2294   gcc_assert (which_alternative == 1);
2295   return "push{q}\t%q1";
2296 }
2297   [(set_attr "type" "multi,push,multi")
2298    (set_attr "unit" "i387,*,*")
2299    (set_attr "mode" "SF,DI,SF")])
2300
2301 (define_split
2302   [(set (match_operand:SF 0 "push_operand" "")
2303         (match_operand:SF 1 "memory_operand" ""))]
2304   "reload_completed
2305    && MEM_P (operands[1])
2306    && constant_pool_reference_p (operands[1])"
2307   [(set (match_dup 0)
2308         (match_dup 1))]
2309   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2310
2311
2312 ;; %%% Kill this when call knows how to work this out.
2313 (define_split
2314   [(set (match_operand:SF 0 "push_operand" "")
2315         (match_operand:SF 1 "any_fp_register_operand" ""))]
2316   "!TARGET_64BIT"
2317   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2318    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2319
2320 (define_split
2321   [(set (match_operand:SF 0 "push_operand" "")
2322         (match_operand:SF 1 "any_fp_register_operand" ""))]
2323   "TARGET_64BIT"
2324   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2325    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2326
2327 (define_insn "*movsf_1"
2328   [(set (match_operand:SF 0 "nonimmediate_operand"
2329           "=f,m,f,r  ,m ,x,x,x ,m,*y,m ,*y,Yi,r ,*Ym,r  ")
2330         (match_operand:SF 1 "general_operand"
2331           "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y,r ,Yi,r  ,*Ym"))]
2332   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2333    && (reload_in_progress || reload_completed
2334        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2335        || (!TARGET_SSE_MATH && optimize_size
2336            && standard_80387_constant_p (operands[1]))
2337        || GET_CODE (operands[1]) != CONST_DOUBLE
2338        || memory_operand (operands[0], SFmode))"
2339 {
2340   switch (which_alternative)
2341     {
2342     case 0:
2343       return output_387_reg_move (insn, operands);
2344
2345     case 1:
2346       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2347         return "fstp%z0\t%y0";
2348       else
2349         return "fst%z0\t%y0";
2350
2351     case 2:
2352       return standard_80387_constant_opcode (operands[1]);
2353
2354     case 3:
2355     case 4:
2356       return "mov{l}\t{%1, %0|%0, %1}";
2357     case 5:
2358       if (get_attr_mode (insn) == MODE_TI)
2359         return "pxor\t%0, %0";
2360       else
2361         return "xorps\t%0, %0";
2362     case 6:
2363       if (get_attr_mode (insn) == MODE_V4SF)
2364         return "movaps\t{%1, %0|%0, %1}";
2365       else
2366         return "movss\t{%1, %0|%0, %1}";
2367     case 7: case 8:
2368       return "movss\t{%1, %0|%0, %1}";
2369
2370     case 9: case 10:
2371     case 12: case 13: case 14: case 15:
2372       return "movd\t{%1, %0|%0, %1}";
2373
2374     case 11:
2375       return "movq\t{%1, %0|%0, %1}";
2376
2377     default:
2378       gcc_unreachable ();
2379     }
2380 }
2381   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2382    (set (attr "mode")
2383         (cond [(eq_attr "alternative" "3,4,9,10")
2384                  (const_string "SI")
2385                (eq_attr "alternative" "5")
2386                  (if_then_else
2387                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2388                                  (const_int 0))
2389                              (ne (symbol_ref "TARGET_SSE2")
2390                                  (const_int 0)))
2391                         (eq (symbol_ref "optimize_size")
2392                             (const_int 0)))
2393                    (const_string "TI")
2394                    (const_string "V4SF"))
2395                /* For architectures resolving dependencies on
2396                   whole SSE registers use APS move to break dependency
2397                   chains, otherwise use short move to avoid extra work.
2398
2399                   Do the same for architectures resolving dependencies on
2400                   the parts.  While in DF mode it is better to always handle
2401                   just register parts, the SF mode is different due to lack
2402                   of instructions to load just part of the register.  It is
2403                   better to maintain the whole registers in single format
2404                   to avoid problems on using packed logical operations.  */
2405                (eq_attr "alternative" "6")
2406                  (if_then_else
2407                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2408                             (const_int 0))
2409                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2410                             (const_int 0)))
2411                    (const_string "V4SF")
2412                    (const_string "SF"))
2413                (eq_attr "alternative" "11")
2414                  (const_string "DI")]
2415                (const_string "SF")))])
2416
2417 (define_insn "*swapsf"
2418   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2419         (match_operand:SF 1 "fp_register_operand" "+f"))
2420    (set (match_dup 1)
2421         (match_dup 0))]
2422   "reload_completed || TARGET_80387"
2423 {
2424   if (STACK_TOP_P (operands[0]))
2425     return "fxch\t%1";
2426   else
2427     return "fxch\t%0";
2428 }
2429   [(set_attr "type" "fxch")
2430    (set_attr "mode" "SF")])
2431
2432 (define_expand "movdf"
2433   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2434         (match_operand:DF 1 "general_operand" ""))]
2435   ""
2436   "ix86_expand_move (DFmode, operands); DONE;")
2437
2438 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2439 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2440 ;; On the average, pushdf using integers can be still shorter.  Allow this
2441 ;; pattern for optimize_size too.
2442
2443 (define_insn "*pushdf_nointeger"
2444   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2445         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2446   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2447 {
2448   /* This insn should be already split before reg-stack.  */
2449   gcc_unreachable ();
2450 }
2451   [(set_attr "type" "multi")
2452    (set_attr "unit" "i387,*,*,*")
2453    (set_attr "mode" "DF,SI,SI,DF")])
2454
2455 (define_insn "*pushdf_integer"
2456   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2457         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2458   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2459 {
2460   /* This insn should be already split before reg-stack.  */
2461   gcc_unreachable ();
2462 }
2463   [(set_attr "type" "multi")
2464    (set_attr "unit" "i387,*,*")
2465    (set_attr "mode" "DF,SI,DF")])
2466
2467 ;; %%% Kill this when call knows how to work this out.
2468 (define_split
2469   [(set (match_operand:DF 0 "push_operand" "")
2470         (match_operand:DF 1 "any_fp_register_operand" ""))]
2471   "!TARGET_64BIT && reload_completed"
2472   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2473    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2474   "")
2475
2476 (define_split
2477   [(set (match_operand:DF 0 "push_operand" "")
2478         (match_operand:DF 1 "any_fp_register_operand" ""))]
2479   "TARGET_64BIT && reload_completed"
2480   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2481    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2482   "")
2483
2484 (define_split
2485   [(set (match_operand:DF 0 "push_operand" "")
2486         (match_operand:DF 1 "general_operand" ""))]
2487   "reload_completed"
2488   [(const_int 0)]
2489   "ix86_split_long_move (operands); DONE;")
2490
2491 ;; Moving is usually shorter when only FP registers are used. This separate
2492 ;; movdf pattern avoids the use of integer registers for FP operations
2493 ;; when optimizing for size.
2494
2495 (define_insn "*movdf_nointeger"
2496   [(set (match_operand:DF 0 "nonimmediate_operand"
2497                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
2498         (match_operand:DF 1 "general_operand"
2499                         "fm,f,G,*roF,F*r,C   ,Y2*x,mY2*x,Y2*x"))]
2500   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2501    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2502    && (reload_in_progress || reload_completed
2503        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2504        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2505            && standard_80387_constant_p (operands[1]))
2506        || GET_CODE (operands[1]) != CONST_DOUBLE
2507        || memory_operand (operands[0], DFmode))"
2508 {
2509   switch (which_alternative)
2510     {
2511     case 0:
2512       return output_387_reg_move (insn, operands);
2513
2514     case 1:
2515       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2516         return "fstp%z0\t%y0";
2517       else
2518         return "fst%z0\t%y0";
2519
2520     case 2:
2521       return standard_80387_constant_opcode (operands[1]);
2522
2523     case 3:
2524     case 4:
2525       return "#";
2526     case 5:
2527       switch (get_attr_mode (insn))
2528         {
2529         case MODE_V4SF:
2530           return "xorps\t%0, %0";
2531         case MODE_V2DF:
2532           return "xorpd\t%0, %0";
2533         case MODE_TI:
2534           return "pxor\t%0, %0";
2535         default:
2536           gcc_unreachable ();
2537         }
2538     case 6:
2539     case 7:
2540     case 8:
2541       switch (get_attr_mode (insn))
2542         {
2543         case MODE_V4SF:
2544           return "movaps\t{%1, %0|%0, %1}";
2545         case MODE_V2DF:
2546           return "movapd\t{%1, %0|%0, %1}";
2547         case MODE_TI:
2548           return "movdqa\t{%1, %0|%0, %1}";
2549         case MODE_DI:
2550           return "movq\t{%1, %0|%0, %1}";
2551         case MODE_DF:
2552           return "movsd\t{%1, %0|%0, %1}";
2553         case MODE_V1DF:
2554           return "movlpd\t{%1, %0|%0, %1}";
2555         case MODE_V2SF:
2556           return "movlps\t{%1, %0|%0, %1}";
2557         default:
2558           gcc_unreachable ();
2559         }
2560
2561     default:
2562       gcc_unreachable ();
2563     }
2564 }
2565   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2566    (set (attr "mode")
2567         (cond [(eq_attr "alternative" "0,1,2")
2568                  (const_string "DF")
2569                (eq_attr "alternative" "3,4")
2570                  (const_string "SI")
2571
2572                /* For SSE1, we have many fewer alternatives.  */
2573                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2574                  (cond [(eq_attr "alternative" "5,6")
2575                           (const_string "V4SF")
2576                        ]
2577                    (const_string "V2SF"))
2578
2579                /* xorps is one byte shorter.  */
2580                (eq_attr "alternative" "5")
2581                  (cond [(ne (symbol_ref "optimize_size")
2582                             (const_int 0))
2583                           (const_string "V4SF")
2584                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2585                             (const_int 0))
2586                           (const_string "TI")
2587                        ]
2588                        (const_string "V2DF"))
2589
2590                /* For architectures resolving dependencies on
2591                   whole SSE registers use APD move to break dependency
2592                   chains, otherwise use short move to avoid extra work.
2593
2594                   movaps encodes one byte shorter.  */
2595                (eq_attr "alternative" "6")
2596                  (cond
2597                    [(ne (symbol_ref "optimize_size")
2598                         (const_int 0))
2599                       (const_string "V4SF")
2600                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2601                         (const_int 0))
2602                       (const_string "V2DF")
2603                    ]
2604                    (const_string "DF"))
2605                /* For architectures resolving dependencies on register
2606                   parts we may avoid extra work to zero out upper part
2607                   of register.  */
2608                (eq_attr "alternative" "7")
2609                  (if_then_else
2610                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2611                        (const_int 0))
2612                    (const_string "V1DF")
2613                    (const_string "DF"))
2614               ]
2615               (const_string "DF")))])
2616
2617 (define_insn "*movdf_integer_rex64"
2618   [(set (match_operand:DF 0 "nonimmediate_operand"
2619                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2620         (match_operand:DF 1 "general_operand"
2621                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2622   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2623    && (reload_in_progress || reload_completed
2624        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2625        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2626            && standard_80387_constant_p (operands[1]))
2627        || GET_CODE (operands[1]) != CONST_DOUBLE
2628        || memory_operand (operands[0], DFmode))"
2629 {
2630   switch (which_alternative)
2631     {
2632     case 0:
2633       return output_387_reg_move (insn, operands);
2634
2635     case 1:
2636       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2637         return "fstp%z0\t%y0";
2638       else
2639         return "fst%z0\t%y0";
2640
2641     case 2:
2642       return standard_80387_constant_opcode (operands[1]);
2643
2644     case 3:
2645     case 4:
2646       return "#";
2647
2648     case 5:
2649       switch (get_attr_mode (insn))
2650         {
2651         case MODE_V4SF:
2652           return "xorps\t%0, %0";
2653         case MODE_V2DF:
2654           return "xorpd\t%0, %0";
2655         case MODE_TI:
2656           return "pxor\t%0, %0";
2657         default:
2658           gcc_unreachable ();
2659         }
2660     case 6:
2661     case 7:
2662     case 8:
2663       switch (get_attr_mode (insn))
2664         {
2665         case MODE_V4SF:
2666           return "movaps\t{%1, %0|%0, %1}";
2667         case MODE_V2DF:
2668           return "movapd\t{%1, %0|%0, %1}";
2669         case MODE_TI:
2670           return "movdqa\t{%1, %0|%0, %1}";
2671         case MODE_DI:
2672           return "movq\t{%1, %0|%0, %1}";
2673         case MODE_DF:
2674           return "movsd\t{%1, %0|%0, %1}";
2675         case MODE_V1DF:
2676           return "movlpd\t{%1, %0|%0, %1}";
2677         case MODE_V2SF:
2678           return "movlps\t{%1, %0|%0, %1}";
2679         default:
2680           gcc_unreachable ();
2681         }
2682
2683     case 9:
2684     case 10:
2685       return "movd\t{%1, %0|%0, %1}";
2686
2687     default:
2688       gcc_unreachable();
2689     }
2690 }
2691   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2692    (set (attr "mode")
2693         (cond [(eq_attr "alternative" "0,1,2")
2694                  (const_string "DF")
2695                (eq_attr "alternative" "3,4,9,10")
2696                  (const_string "DI")
2697
2698                /* For SSE1, we have many fewer alternatives.  */
2699                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2700                  (cond [(eq_attr "alternative" "5,6")
2701                           (const_string "V4SF")
2702                        ]
2703                    (const_string "V2SF"))
2704
2705                /* xorps is one byte shorter.  */
2706                (eq_attr "alternative" "5")
2707                  (cond [(ne (symbol_ref "optimize_size")
2708                             (const_int 0))
2709                           (const_string "V4SF")
2710                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2711                             (const_int 0))
2712                           (const_string "TI")
2713                        ]
2714                        (const_string "V2DF"))
2715
2716                /* For architectures resolving dependencies on
2717                   whole SSE registers use APD move to break dependency
2718                   chains, otherwise use short move to avoid extra work.
2719
2720                   movaps encodes one byte shorter.  */
2721                (eq_attr "alternative" "6")
2722                  (cond
2723                    [(ne (symbol_ref "optimize_size")
2724                         (const_int 0))
2725                       (const_string "V4SF")
2726                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2727                         (const_int 0))
2728                       (const_string "V2DF")
2729                    ]
2730                    (const_string "DF"))
2731                /* For architectures resolving dependencies on register
2732                   parts we may avoid extra work to zero out upper part
2733                   of register.  */
2734                (eq_attr "alternative" "7")
2735                  (if_then_else
2736                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2737                        (const_int 0))
2738                    (const_string "V1DF")
2739                    (const_string "DF"))
2740               ]
2741               (const_string "DF")))])
2742
2743 (define_insn "*movdf_integer"
2744   [(set (match_operand:DF 0 "nonimmediate_operand"
2745                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
2746         (match_operand:DF 1 "general_operand"
2747                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
2748   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2749    && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2750    && (reload_in_progress || reload_completed
2751        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2752        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2753            && standard_80387_constant_p (operands[1]))
2754        || GET_CODE (operands[1]) != CONST_DOUBLE
2755        || memory_operand (operands[0], DFmode))"
2756 {
2757   switch (which_alternative)
2758     {
2759     case 0:
2760       return output_387_reg_move (insn, operands);
2761
2762     case 1:
2763       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2764         return "fstp%z0\t%y0";
2765       else
2766         return "fst%z0\t%y0";
2767
2768     case 2:
2769       return standard_80387_constant_opcode (operands[1]);
2770
2771     case 3:
2772     case 4:
2773       return "#";
2774
2775     case 5:
2776       switch (get_attr_mode (insn))
2777         {
2778         case MODE_V4SF:
2779           return "xorps\t%0, %0";
2780         case MODE_V2DF:
2781           return "xorpd\t%0, %0";
2782         case MODE_TI:
2783           return "pxor\t%0, %0";
2784         default:
2785           gcc_unreachable ();
2786         }
2787     case 6:
2788     case 7:
2789     case 8:
2790       switch (get_attr_mode (insn))
2791         {
2792         case MODE_V4SF:
2793           return "movaps\t{%1, %0|%0, %1}";
2794         case MODE_V2DF:
2795           return "movapd\t{%1, %0|%0, %1}";
2796         case MODE_TI:
2797           return "movdqa\t{%1, %0|%0, %1}";
2798         case MODE_DI:
2799           return "movq\t{%1, %0|%0, %1}";
2800         case MODE_DF:
2801           return "movsd\t{%1, %0|%0, %1}";
2802         case MODE_V1DF:
2803           return "movlpd\t{%1, %0|%0, %1}";
2804         case MODE_V2SF:
2805           return "movlps\t{%1, %0|%0, %1}";
2806         default:
2807           gcc_unreachable ();
2808         }
2809
2810     default:
2811       gcc_unreachable();
2812     }
2813 }
2814   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2815    (set (attr "mode")
2816         (cond [(eq_attr "alternative" "0,1,2")
2817                  (const_string "DF")
2818                (eq_attr "alternative" "3,4")
2819                  (const_string "SI")
2820
2821                /* For SSE1, we have many fewer alternatives.  */
2822                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2823                  (cond [(eq_attr "alternative" "5,6")
2824                           (const_string "V4SF")
2825                        ]
2826                    (const_string "V2SF"))
2827
2828                /* xorps is one byte shorter.  */
2829                (eq_attr "alternative" "5")
2830                  (cond [(ne (symbol_ref "optimize_size")
2831                             (const_int 0))
2832                           (const_string "V4SF")
2833                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2834                             (const_int 0))
2835                           (const_string "TI")
2836                        ]
2837                        (const_string "V2DF"))
2838
2839                /* For architectures resolving dependencies on
2840                   whole SSE registers use APD move to break dependency
2841                   chains, otherwise use short move to avoid extra work.
2842
2843                   movaps encodes one byte shorter.  */
2844                (eq_attr "alternative" "6")
2845                  (cond
2846                    [(ne (symbol_ref "optimize_size")
2847                         (const_int 0))
2848                       (const_string "V4SF")
2849                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2850                         (const_int 0))
2851                       (const_string "V2DF")
2852                    ]
2853                    (const_string "DF"))
2854                /* For architectures resolving dependencies on register
2855                   parts we may avoid extra work to zero out upper part
2856                   of register.  */
2857                (eq_attr "alternative" "7")
2858                  (if_then_else
2859                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2860                        (const_int 0))
2861                    (const_string "V1DF")
2862                    (const_string "DF"))
2863               ]
2864               (const_string "DF")))])
2865
2866 (define_split
2867   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2868         (match_operand:DF 1 "general_operand" ""))]
2869   "reload_completed
2870    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2871    && ! (ANY_FP_REG_P (operands[0]) ||
2872          (GET_CODE (operands[0]) == SUBREG
2873           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2874    && ! (ANY_FP_REG_P (operands[1]) ||
2875          (GET_CODE (operands[1]) == SUBREG
2876           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2877   [(const_int 0)]
2878   "ix86_split_long_move (operands); DONE;")
2879
2880 (define_insn "*swapdf"
2881   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2882         (match_operand:DF 1 "fp_register_operand" "+f"))
2883    (set (match_dup 1)
2884         (match_dup 0))]
2885   "reload_completed || TARGET_80387"
2886 {
2887   if (STACK_TOP_P (operands[0]))
2888     return "fxch\t%1";
2889   else
2890     return "fxch\t%0";
2891 }
2892   [(set_attr "type" "fxch")
2893    (set_attr "mode" "DF")])
2894
2895 (define_expand "movxf"
2896   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2897         (match_operand:XF 1 "general_operand" ""))]
2898   ""
2899   "ix86_expand_move (XFmode, operands); DONE;")
2900
2901 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2902 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2903 ;; Pushing using integer instructions is longer except for constants
2904 ;; and direct memory references.
2905 ;; (assuming that any given constant is pushed only once, but this ought to be
2906 ;;  handled elsewhere).
2907
2908 (define_insn "*pushxf_nointeger"
2909   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2910         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2911   "optimize_size"
2912 {
2913   /* This insn should be already split before reg-stack.  */
2914   gcc_unreachable ();
2915 }
2916   [(set_attr "type" "multi")
2917    (set_attr "unit" "i387,*,*")
2918    (set_attr "mode" "XF,SI,SI")])
2919
2920 (define_insn "*pushxf_integer"
2921   [(set (match_operand:XF 0 "push_operand" "=<,<")
2922         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2923   "!optimize_size"
2924 {
2925   /* This insn should be already split before reg-stack.  */
2926   gcc_unreachable ();
2927 }
2928   [(set_attr "type" "multi")
2929    (set_attr "unit" "i387,*")
2930    (set_attr "mode" "XF,SI")])
2931
2932 (define_split
2933   [(set (match_operand 0 "push_operand" "")
2934         (match_operand 1 "general_operand" ""))]
2935   "reload_completed
2936    && (GET_MODE (operands[0]) == XFmode
2937        || GET_MODE (operands[0]) == DFmode)
2938    && !ANY_FP_REG_P (operands[1])"
2939   [(const_int 0)]
2940   "ix86_split_long_move (operands); DONE;")
2941
2942 (define_split
2943   [(set (match_operand:XF 0 "push_operand" "")
2944         (match_operand:XF 1 "any_fp_register_operand" ""))]
2945   "!TARGET_64BIT"
2946   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2947    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2948   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2949
2950 (define_split
2951   [(set (match_operand:XF 0 "push_operand" "")
2952         (match_operand:XF 1 "any_fp_register_operand" ""))]
2953   "TARGET_64BIT"
2954   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2955    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2956   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2957
2958 ;; Do not use integer registers when optimizing for size
2959 (define_insn "*movxf_nointeger"
2960   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2961         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2962   "optimize_size
2963    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2964    && (reload_in_progress || reload_completed
2965        || (optimize_size && standard_80387_constant_p (operands[1]))
2966        || GET_CODE (operands[1]) != CONST_DOUBLE
2967        || memory_operand (operands[0], XFmode))"
2968 {
2969   switch (which_alternative)
2970     {
2971     case 0:
2972       return output_387_reg_move (insn, operands);
2973
2974     case 1:
2975       /* There is no non-popping store to memory for XFmode.  So if
2976          we need one, follow the store with a load.  */
2977       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2978         return "fstp%z0\t%y0\;fld%z0\t%y0";
2979       else
2980         return "fstp%z0\t%y0";
2981
2982     case 2:
2983       return standard_80387_constant_opcode (operands[1]);
2984
2985     case 3: case 4:
2986       return "#";
2987     default:
2988       gcc_unreachable ();
2989     }
2990 }
2991   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2992    (set_attr "mode" "XF,XF,XF,SI,SI")])
2993
2994 (define_insn "*movxf_integer"
2995   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2996         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2997   "!optimize_size
2998    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2999    && (reload_in_progress || reload_completed
3000        || (optimize_size && standard_80387_constant_p (operands[1]))
3001        || GET_CODE (operands[1]) != CONST_DOUBLE
3002        || memory_operand (operands[0], XFmode))"
3003 {
3004   switch (which_alternative)
3005     {
3006     case 0:
3007       return output_387_reg_move (insn, operands);
3008
3009     case 1:
3010       /* There is no non-popping store to memory for XFmode.  So if
3011          we need one, follow the store with a load.  */
3012       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3013         return "fstp%z0\t%y0\;fld%z0\t%y0";
3014       else
3015         return "fstp%z0\t%y0";
3016
3017     case 2:
3018       return standard_80387_constant_opcode (operands[1]);
3019
3020     case 3: case 4:
3021       return "#";
3022
3023     default:
3024       gcc_unreachable ();
3025     }
3026 }
3027   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3028    (set_attr "mode" "XF,XF,XF,SI,SI")])
3029
3030 (define_split
3031   [(set (match_operand 0 "nonimmediate_operand" "")
3032         (match_operand 1 "general_operand" ""))]
3033   "reload_completed
3034    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3035    && GET_MODE (operands[0]) == XFmode
3036    && ! (ANY_FP_REG_P (operands[0]) ||
3037          (GET_CODE (operands[0]) == SUBREG
3038           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3039    && ! (ANY_FP_REG_P (operands[1]) ||
3040          (GET_CODE (operands[1]) == SUBREG
3041           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3042   [(const_int 0)]
3043   "ix86_split_long_move (operands); DONE;")
3044
3045 (define_split
3046   [(set (match_operand 0 "register_operand" "")
3047         (match_operand 1 "memory_operand" ""))]
3048   "reload_completed
3049    && MEM_P (operands[1])
3050    && (GET_MODE (operands[0]) == XFmode
3051        || GET_MODE (operands[0]) == SFmode
3052        || GET_MODE (operands[0]) == DFmode)
3053    && constant_pool_reference_p (operands[1])"
3054   [(set (match_dup 0) (match_dup 1))]
3055 {
3056   rtx c = avoid_constant_pool_reference (operands[1]);
3057   rtx r = operands[0];
3058
3059   if (GET_CODE (r) == SUBREG)
3060     r = SUBREG_REG (r);
3061
3062   if (SSE_REG_P (r))
3063     {
3064       if (!standard_sse_constant_p (c))
3065         FAIL;
3066     }
3067   else if (FP_REG_P (r))
3068     {
3069       if (!standard_80387_constant_p (c))
3070         FAIL;
3071     }
3072   else if (MMX_REG_P (r))
3073     FAIL;
3074
3075   operands[1] = c;
3076 })
3077
3078 (define_split
3079   [(set (match_operand 0 "register_operand" "")
3080         (float_extend (match_operand 1 "memory_operand" "")))]
3081   "reload_completed
3082    && MEM_P (operands[1])
3083    && (GET_MODE (operands[0]) == XFmode
3084        || GET_MODE (operands[0]) == SFmode
3085        || GET_MODE (operands[0]) == DFmode)
3086    && constant_pool_reference_p (operands[1])"
3087   [(set (match_dup 0) (match_dup 1))]
3088 {
3089   rtx c = avoid_constant_pool_reference (SET_SRC (PATTERN (curr_insn)));
3090   rtx r = operands[0];
3091
3092   if (GET_CODE (r) == SUBREG)
3093     r = SUBREG_REG (r);
3094
3095   if (SSE_REG_P (r))
3096     {
3097       if (!standard_sse_constant_p (c))
3098         FAIL;
3099     }
3100   else if (FP_REG_P (r))
3101     {
3102       if (!standard_80387_constant_p (c))
3103         FAIL;
3104     }
3105   else if (MMX_REG_P (r))
3106     FAIL;
3107
3108   operands[1] = c;
3109 })
3110
3111 (define_insn "swapxf"
3112   [(set (match_operand:XF 0 "register_operand" "+f")
3113         (match_operand:XF 1 "register_operand" "+f"))
3114    (set (match_dup 1)
3115         (match_dup 0))]
3116   "TARGET_80387"
3117 {
3118   if (STACK_TOP_P (operands[0]))
3119     return "fxch\t%1";
3120   else
3121     return "fxch\t%0";
3122 }
3123   [(set_attr "type" "fxch")
3124    (set_attr "mode" "XF")])
3125
3126 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3127 (define_split
3128   [(set (match_operand:X87MODEF 0 "register_operand" "")
3129         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3130   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3131    && (standard_80387_constant_p (operands[1]) == 8
3132        || standard_80387_constant_p (operands[1]) == 9)"
3133   [(set (match_dup 0)(match_dup 1))
3134    (set (match_dup 0)
3135         (neg:X87MODEF (match_dup 0)))]
3136 {
3137   REAL_VALUE_TYPE r;
3138
3139   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3140   if (real_isnegzero (&r))
3141     operands[1] = CONST0_RTX (<MODE>mode);
3142   else
3143     operands[1] = CONST1_RTX (<MODE>mode);
3144 })
3145
3146 (define_expand "movtf"
3147   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3148         (match_operand:TF 1 "nonimmediate_operand" ""))]
3149   "TARGET_64BIT"
3150 {
3151   ix86_expand_move (TFmode, operands);
3152   DONE;
3153 })
3154
3155 (define_insn "*movtf_internal"
3156   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3157         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3158   "TARGET_64BIT
3159    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3160 {
3161   switch (which_alternative)
3162     {
3163     case 0:
3164     case 1:
3165       return "#";
3166     case 2:
3167       if (get_attr_mode (insn) == MODE_V4SF)
3168         return "xorps\t%0, %0";
3169       else
3170         return "pxor\t%0, %0";
3171     case 3:
3172     case 4:
3173       if (get_attr_mode (insn) == MODE_V4SF)
3174         return "movaps\t{%1, %0|%0, %1}";
3175       else
3176         return "movdqa\t{%1, %0|%0, %1}";
3177     default:
3178       gcc_unreachable ();
3179     }
3180 }
3181   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3182    (set (attr "mode")
3183         (cond [(eq_attr "alternative" "2,3")
3184                  (if_then_else
3185                    (ne (symbol_ref "optimize_size")
3186                        (const_int 0))
3187                    (const_string "V4SF")
3188                    (const_string "TI"))
3189                (eq_attr "alternative" "4")
3190                  (if_then_else
3191                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3192                             (const_int 0))
3193                         (ne (symbol_ref "optimize_size")
3194                             (const_int 0)))
3195                    (const_string "V4SF")
3196                    (const_string "TI"))]
3197                (const_string "DI")))])
3198
3199 (define_split
3200   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3201         (match_operand:TF 1 "general_operand" ""))]
3202   "reload_completed && !SSE_REG_P (operands[0])
3203    && !SSE_REG_P (operands[1])"
3204   [(const_int 0)]
3205   "ix86_split_long_move (operands); DONE;")
3206 \f
3207 ;; Zero extension instructions
3208
3209 (define_expand "zero_extendhisi2"
3210   [(set (match_operand:SI 0 "register_operand" "")
3211      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3212   ""
3213 {
3214   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3215     {
3216       operands[1] = force_reg (HImode, operands[1]);
3217       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3218       DONE;
3219     }
3220 })
3221
3222 (define_insn "zero_extendhisi2_and"
3223   [(set (match_operand:SI 0 "register_operand" "=r")
3224      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3225    (clobber (reg:CC FLAGS_REG))]
3226   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3227   "#"
3228   [(set_attr "type" "alu1")
3229    (set_attr "mode" "SI")])
3230
3231 (define_split
3232   [(set (match_operand:SI 0 "register_operand" "")
3233         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3234    (clobber (reg:CC FLAGS_REG))]
3235   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3236   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3237               (clobber (reg:CC FLAGS_REG))])]
3238   "")
3239
3240 (define_insn "*zero_extendhisi2_movzwl"
3241   [(set (match_operand:SI 0 "register_operand" "=r")
3242      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3243   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3244   "movz{wl|x}\t{%1, %0|%0, %1}"
3245   [(set_attr "type" "imovx")
3246    (set_attr "mode" "SI")])
3247
3248 (define_expand "zero_extendqihi2"
3249   [(parallel
3250     [(set (match_operand:HI 0 "register_operand" "")
3251        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3252      (clobber (reg:CC FLAGS_REG))])]
3253   ""
3254   "")
3255
3256 (define_insn "*zero_extendqihi2_and"
3257   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3258      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3259    (clobber (reg:CC FLAGS_REG))]
3260   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3261   "#"
3262   [(set_attr "type" "alu1")
3263    (set_attr "mode" "HI")])
3264
3265 (define_insn "*zero_extendqihi2_movzbw_and"
3266   [(set (match_operand:HI 0 "register_operand" "=r,r")
3267      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3268    (clobber (reg:CC FLAGS_REG))]
3269   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3270   "#"
3271   [(set_attr "type" "imovx,alu1")
3272    (set_attr "mode" "HI")])
3273
3274 ; zero extend to SImode here to avoid partial register stalls
3275 (define_insn "*zero_extendqihi2_movzbl"
3276   [(set (match_operand:HI 0 "register_operand" "=r")
3277      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3278   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3279   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3280   [(set_attr "type" "imovx")
3281    (set_attr "mode" "SI")])
3282
3283 ;; For the movzbw case strip only the clobber
3284 (define_split
3285   [(set (match_operand:HI 0 "register_operand" "")
3286         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3287    (clobber (reg:CC FLAGS_REG))]
3288   "reload_completed
3289    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3290    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3291   [(set (match_operand:HI 0 "register_operand" "")
3292         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3293
3294 ;; When source and destination does not overlap, clear destination
3295 ;; first and then do the movb
3296 (define_split
3297   [(set (match_operand:HI 0 "register_operand" "")
3298         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3299    (clobber (reg:CC FLAGS_REG))]
3300   "reload_completed
3301    && ANY_QI_REG_P (operands[0])
3302    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3303    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3304   [(set (match_dup 0) (const_int 0))
3305    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3306   "operands[2] = gen_lowpart (QImode, operands[0]);")
3307
3308 ;; Rest is handled by single and.
3309 (define_split
3310   [(set (match_operand:HI 0 "register_operand" "")
3311         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3312    (clobber (reg:CC FLAGS_REG))]
3313   "reload_completed
3314    && true_regnum (operands[0]) == true_regnum (operands[1])"
3315   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3316               (clobber (reg:CC FLAGS_REG))])]
3317   "")
3318
3319 (define_expand "zero_extendqisi2"
3320   [(parallel
3321     [(set (match_operand:SI 0 "register_operand" "")
3322        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3323      (clobber (reg:CC FLAGS_REG))])]
3324   ""
3325   "")
3326
3327 (define_insn "*zero_extendqisi2_and"
3328   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3329      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3330    (clobber (reg:CC FLAGS_REG))]
3331   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3332   "#"
3333   [(set_attr "type" "alu1")
3334    (set_attr "mode" "SI")])
3335
3336 (define_insn "*zero_extendqisi2_movzbw_and"
3337   [(set (match_operand:SI 0 "register_operand" "=r,r")
3338      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3339    (clobber (reg:CC FLAGS_REG))]
3340   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3341   "#"
3342   [(set_attr "type" "imovx,alu1")
3343    (set_attr "mode" "SI")])
3344
3345 (define_insn "*zero_extendqisi2_movzbw"
3346   [(set (match_operand:SI 0 "register_operand" "=r")
3347      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3348   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3349   "movz{bl|x}\t{%1, %0|%0, %1}"
3350   [(set_attr "type" "imovx")
3351    (set_attr "mode" "SI")])
3352
3353 ;; For the movzbl case strip only the clobber
3354 (define_split
3355   [(set (match_operand:SI 0 "register_operand" "")
3356         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3357    (clobber (reg:CC FLAGS_REG))]
3358   "reload_completed
3359    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3360    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3361   [(set (match_dup 0)
3362         (zero_extend:SI (match_dup 1)))])
3363
3364 ;; When source and destination does not overlap, clear destination
3365 ;; first and then do the movb
3366 (define_split
3367   [(set (match_operand:SI 0 "register_operand" "")
3368         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3369    (clobber (reg:CC FLAGS_REG))]
3370   "reload_completed
3371    && ANY_QI_REG_P (operands[0])
3372    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3373    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3374    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3375   [(set (match_dup 0) (const_int 0))
3376    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3377   "operands[2] = gen_lowpart (QImode, operands[0]);")
3378
3379 ;; Rest is handled by single and.
3380 (define_split
3381   [(set (match_operand:SI 0 "register_operand" "")
3382         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3383    (clobber (reg:CC FLAGS_REG))]
3384   "reload_completed
3385    && true_regnum (operands[0]) == true_regnum (operands[1])"
3386   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3387               (clobber (reg:CC FLAGS_REG))])]
3388   "")
3389
3390 ;; %%% Kill me once multi-word ops are sane.
3391 (define_expand "zero_extendsidi2"
3392   [(set (match_operand:DI 0 "register_operand" "=r")
3393      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3394   ""
3395 {
3396   if (!TARGET_64BIT)
3397     {
3398       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3399       DONE;
3400     }
3401 })
3402
3403 (define_insn "zero_extendsidi2_32"
3404   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,*y,?*Yi,*Y2")
3405         (zero_extend:DI
3406          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m ,r   ,m")))
3407    (clobber (reg:CC FLAGS_REG))]
3408   "!TARGET_64BIT"
3409   "@
3410    #
3411    #
3412    #
3413    movd\t{%1, %0|%0, %1}
3414    movd\t{%1, %0|%0, %1}
3415    movd\t{%1, %0|%0, %1}
3416    movd\t{%1, %0|%0, %1}"
3417   [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3418    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3419
3420 (define_insn "zero_extendsidi2_rex64"
3421   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,*y,?*Yi,*Y2")
3422      (zero_extend:DI
3423        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m ,r   ,m")))]
3424   "TARGET_64BIT"
3425   "@
3426    mov\t{%k1, %k0|%k0, %k1}
3427    #
3428    movd\t{%1, %0|%0, %1}
3429    movd\t{%1, %0|%0, %1}
3430    movd\t{%1, %0|%0, %1}
3431    movd\t{%1, %0|%0, %1}"
3432   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3433    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3434
3435 (define_split
3436   [(set (match_operand:DI 0 "memory_operand" "")
3437      (zero_extend:DI (match_dup 0)))]
3438   "TARGET_64BIT"
3439   [(set (match_dup 4) (const_int 0))]
3440   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3441
3442 (define_split
3443   [(set (match_operand:DI 0 "register_operand" "")
3444         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3445    (clobber (reg:CC FLAGS_REG))]
3446   "!TARGET_64BIT && reload_completed
3447    && true_regnum (operands[0]) == true_regnum (operands[1])"
3448   [(set (match_dup 4) (const_int 0))]
3449   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3450
3451 (define_split
3452   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3453         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3454    (clobber (reg:CC FLAGS_REG))]
3455   "!TARGET_64BIT && reload_completed
3456    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3457   [(set (match_dup 3) (match_dup 1))
3458    (set (match_dup 4) (const_int 0))]
3459   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3460
3461 (define_insn "zero_extendhidi2"
3462   [(set (match_operand:DI 0 "register_operand" "=r")
3463      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3464   "TARGET_64BIT"
3465   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3466   [(set_attr "type" "imovx")
3467    (set_attr "mode" "DI")])
3468
3469 (define_insn "zero_extendqidi2"
3470   [(set (match_operand:DI 0 "register_operand" "=r")
3471      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3472   "TARGET_64BIT"
3473   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3474   [(set_attr "type" "imovx")
3475    (set_attr "mode" "DI")])
3476 \f
3477 ;; Sign extension instructions
3478
3479 (define_expand "extendsidi2"
3480   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3481                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3482               (clobber (reg:CC FLAGS_REG))
3483               (clobber (match_scratch:SI 2 ""))])]
3484   ""
3485 {
3486   if (TARGET_64BIT)
3487     {
3488       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3489       DONE;
3490     }
3491 })
3492
3493 (define_insn "*extendsidi2_1"
3494   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3495         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3496    (clobber (reg:CC FLAGS_REG))
3497    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3498   "!TARGET_64BIT"
3499   "#")
3500
3501 (define_insn "extendsidi2_rex64"
3502   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3503         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3504   "TARGET_64BIT"
3505   "@
3506    {cltq|cdqe}
3507    movs{lq|x}\t{%1,%0|%0, %1}"
3508   [(set_attr "type" "imovx")
3509    (set_attr "mode" "DI")
3510    (set_attr "prefix_0f" "0")
3511    (set_attr "modrm" "0,1")])
3512
3513 (define_insn "extendhidi2"
3514   [(set (match_operand:DI 0 "register_operand" "=r")
3515         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3516   "TARGET_64BIT"
3517   "movs{wq|x}\t{%1,%0|%0, %1}"
3518   [(set_attr "type" "imovx")
3519    (set_attr "mode" "DI")])
3520
3521 (define_insn "extendqidi2"
3522   [(set (match_operand:DI 0 "register_operand" "=r")
3523         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3524   "TARGET_64BIT"
3525   "movs{bq|x}\t{%1,%0|%0, %1}"
3526    [(set_attr "type" "imovx")
3527     (set_attr "mode" "DI")])
3528
3529 ;; Extend to memory case when source register does die.
3530 (define_split
3531   [(set (match_operand:DI 0 "memory_operand" "")
3532         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3533    (clobber (reg:CC FLAGS_REG))
3534    (clobber (match_operand:SI 2 "register_operand" ""))]
3535   "(reload_completed
3536     && dead_or_set_p (insn, operands[1])
3537     && !reg_mentioned_p (operands[1], operands[0]))"
3538   [(set (match_dup 3) (match_dup 1))
3539    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3540               (clobber (reg:CC FLAGS_REG))])
3541    (set (match_dup 4) (match_dup 1))]
3542   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3543
3544 ;; Extend to memory case when source register does not die.
3545 (define_split
3546   [(set (match_operand:DI 0 "memory_operand" "")
3547         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3548    (clobber (reg:CC FLAGS_REG))
3549    (clobber (match_operand:SI 2 "register_operand" ""))]
3550   "reload_completed"
3551   [(const_int 0)]
3552 {
3553   split_di (&operands[0], 1, &operands[3], &operands[4]);
3554
3555   emit_move_insn (operands[3], operands[1]);
3556
3557   /* Generate a cltd if possible and doing so it profitable.  */
3558   if (true_regnum (operands[1]) == 0
3559       && true_regnum (operands[2]) == 1
3560       && (optimize_size || TARGET_USE_CLTD))
3561     {
3562       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3563     }
3564   else
3565     {
3566       emit_move_insn (operands[2], operands[1]);
3567       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3568     }
3569   emit_move_insn (operands[4], operands[2]);
3570   DONE;
3571 })
3572
3573 ;; Extend to register case.  Optimize case where source and destination
3574 ;; registers match and cases where we can use cltd.
3575 (define_split
3576   [(set (match_operand:DI 0 "register_operand" "")
3577         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3578    (clobber (reg:CC FLAGS_REG))
3579    (clobber (match_scratch:SI 2 ""))]
3580   "reload_completed"
3581   [(const_int 0)]
3582 {
3583   split_di (&operands[0], 1, &operands[3], &operands[4]);
3584
3585   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3586     emit_move_insn (operands[3], operands[1]);
3587
3588   /* Generate a cltd if possible and doing so it profitable.  */
3589   if (true_regnum (operands[3]) == 0
3590       && (optimize_size || TARGET_USE_CLTD))
3591     {
3592       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3593       DONE;
3594     }
3595
3596   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3597     emit_move_insn (operands[4], operands[1]);
3598
3599   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3600   DONE;
3601 })
3602
3603 (define_insn "extendhisi2"
3604   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3605         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3606   ""
3607 {
3608   switch (get_attr_prefix_0f (insn))
3609     {
3610     case 0:
3611       return "{cwtl|cwde}";
3612     default:
3613       return "movs{wl|x}\t{%1,%0|%0, %1}";
3614     }
3615 }
3616   [(set_attr "type" "imovx")
3617    (set_attr "mode" "SI")
3618    (set (attr "prefix_0f")
3619      ;; movsx is short decodable while cwtl is vector decoded.
3620      (if_then_else (and (eq_attr "cpu" "!k6")
3621                         (eq_attr "alternative" "0"))
3622         (const_string "0")
3623         (const_string "1")))
3624    (set (attr "modrm")
3625      (if_then_else (eq_attr "prefix_0f" "0")
3626         (const_string "0")
3627         (const_string "1")))])
3628
3629 (define_insn "*extendhisi2_zext"
3630   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3631         (zero_extend:DI
3632           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3633   "TARGET_64BIT"
3634 {
3635   switch (get_attr_prefix_0f (insn))
3636     {
3637     case 0:
3638       return "{cwtl|cwde}";
3639     default:
3640       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3641     }
3642 }
3643   [(set_attr "type" "imovx")
3644    (set_attr "mode" "SI")
3645    (set (attr "prefix_0f")
3646      ;; movsx is short decodable while cwtl is vector decoded.
3647      (if_then_else (and (eq_attr "cpu" "!k6")
3648                         (eq_attr "alternative" "0"))
3649         (const_string "0")
3650         (const_string "1")))
3651    (set (attr "modrm")
3652      (if_then_else (eq_attr "prefix_0f" "0")
3653         (const_string "0")
3654         (const_string "1")))])
3655
3656 (define_insn "extendqihi2"
3657   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3658         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3659   ""
3660 {
3661   switch (get_attr_prefix_0f (insn))
3662     {
3663     case 0:
3664       return "{cbtw|cbw}";
3665     default:
3666       return "movs{bw|x}\t{%1,%0|%0, %1}";
3667     }
3668 }
3669   [(set_attr "type" "imovx")
3670    (set_attr "mode" "HI")
3671    (set (attr "prefix_0f")
3672      ;; movsx is short decodable while cwtl is vector decoded.
3673      (if_then_else (and (eq_attr "cpu" "!k6")
3674                         (eq_attr "alternative" "0"))
3675         (const_string "0")
3676         (const_string "1")))
3677    (set (attr "modrm")
3678      (if_then_else (eq_attr "prefix_0f" "0")
3679         (const_string "0")
3680         (const_string "1")))])
3681
3682 (define_insn "extendqisi2"
3683   [(set (match_operand:SI 0 "register_operand" "=r")
3684         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3685   ""
3686   "movs{bl|x}\t{%1,%0|%0, %1}"
3687    [(set_attr "type" "imovx")
3688     (set_attr "mode" "SI")])
3689
3690 (define_insn "*extendqisi2_zext"
3691   [(set (match_operand:DI 0 "register_operand" "=r")
3692         (zero_extend:DI
3693           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3694   "TARGET_64BIT"
3695   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3696    [(set_attr "type" "imovx")
3697     (set_attr "mode" "SI")])
3698 \f
3699 ;; Conversions between float and double.
3700
3701 ;; These are all no-ops in the model used for the 80387.  So just
3702 ;; emit moves.
3703
3704 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3705 (define_insn "*dummy_extendsfdf2"
3706   [(set (match_operand:DF 0 "push_operand" "=<")
3707         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3708   "0"
3709   "#")
3710
3711 (define_split
3712   [(set (match_operand:DF 0 "push_operand" "")
3713         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3714   "!TARGET_64BIT"
3715   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3716    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3717
3718 (define_split
3719   [(set (match_operand:DF 0 "push_operand" "")
3720         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3721   "TARGET_64BIT"
3722   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3723    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3724
3725 (define_insn "*dummy_extendsfxf2"
3726   [(set (match_operand:XF 0 "push_operand" "=<")
3727         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3728   "0"
3729   "#")
3730
3731 (define_split
3732   [(set (match_operand:XF 0 "push_operand" "")
3733         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3734   ""
3735   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3736    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3737   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3738
3739 (define_split
3740   [(set (match_operand:XF 0 "push_operand" "")
3741         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3742   "TARGET_64BIT"
3743   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3744    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3745   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3746
3747 (define_split
3748   [(set (match_operand:XF 0 "push_operand" "")
3749         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3750   ""
3751   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3752    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3753   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3754
3755 (define_split
3756   [(set (match_operand:XF 0 "push_operand" "")
3757         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3758   "TARGET_64BIT"
3759   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3760    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3761   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3762
3763 (define_expand "extendsfdf2"
3764   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3765         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3766   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3767 {
3768   /* ??? Needed for compress_float_constant since all fp constants
3769      are LEGITIMATE_CONSTANT_P.  */
3770   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3771     {
3772       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3773           && standard_80387_constant_p (operands[1]) > 0)
3774         {
3775           operands[1] = simplify_const_unary_operation
3776             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3777           emit_move_insn_1 (operands[0], operands[1]);
3778           DONE;
3779         }
3780       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3781     }
3782 })
3783
3784 (define_insn "*extendsfdf2_mixed"
3785   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3786         (float_extend:DF
3787           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3788   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3789 {
3790   switch (which_alternative)
3791     {
3792     case 0:
3793       return output_387_reg_move (insn, operands);
3794
3795     case 1:
3796       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3797         return "fstp%z0\t%y0";
3798       else
3799         return "fst%z0\t%y0";
3800
3801     case 2:
3802       return "cvtss2sd\t{%1, %0|%0, %1}";
3803
3804     default:
3805       gcc_unreachable ();
3806     }
3807 }
3808   [(set_attr "type" "fmov,fmov,ssecvt")
3809    (set_attr "mode" "SF,XF,DF")])
3810
3811 (define_insn "*extendsfdf2_sse"
3812   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3813         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3814   "TARGET_SSE2 && TARGET_SSE_MATH"
3815   "cvtss2sd\t{%1, %0|%0, %1}"
3816   [(set_attr "type" "ssecvt")
3817    (set_attr "mode" "DF")])
3818
3819 (define_insn "*extendsfdf2_i387"
3820   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3821         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3822   "TARGET_80387"
3823 {
3824   switch (which_alternative)
3825     {
3826     case 0:
3827       return output_387_reg_move (insn, operands);
3828
3829     case 1:
3830       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3831         return "fstp%z0\t%y0";
3832       else
3833         return "fst%z0\t%y0";
3834
3835     default:
3836       gcc_unreachable ();
3837     }
3838 }
3839   [(set_attr "type" "fmov")
3840    (set_attr "mode" "SF,XF")])
3841
3842 (define_expand "extendsfxf2"
3843   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3844         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3845   "TARGET_80387"
3846 {
3847   /* ??? Needed for compress_float_constant since all fp constants
3848      are LEGITIMATE_CONSTANT_P.  */
3849   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3850     {
3851       if (standard_80387_constant_p (operands[1]) > 0)
3852         {
3853           operands[1] = simplify_const_unary_operation
3854             (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3855           emit_move_insn_1 (operands[0], operands[1]);
3856           DONE;
3857         }
3858       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3859     }
3860 })
3861
3862 (define_insn "*extendsfxf2_i387"
3863   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3864         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3865   "TARGET_80387"
3866 {
3867   switch (which_alternative)
3868     {
3869     case 0:
3870       return output_387_reg_move (insn, operands);
3871
3872     case 1:
3873       /* There is no non-popping store to memory for XFmode.  So if
3874          we need one, follow the store with a load.  */
3875       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3876         return "fstp%z0\t%y0";
3877       else
3878         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3879
3880     default:
3881       gcc_unreachable ();
3882     }
3883 }
3884   [(set_attr "type" "fmov")
3885    (set_attr "mode" "SF,XF")])
3886
3887 (define_expand "extenddfxf2"
3888   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3889         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3890   "TARGET_80387"
3891 {
3892   /* ??? Needed for compress_float_constant since all fp constants
3893      are LEGITIMATE_CONSTANT_P.  */
3894   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3895     {
3896       if (standard_80387_constant_p (operands[1]) > 0)
3897         {
3898           operands[1] = simplify_const_unary_operation
3899             (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3900           emit_move_insn_1 (operands[0], operands[1]);
3901           DONE;
3902         }
3903       operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3904     }
3905 })
3906
3907 (define_insn "*extenddfxf2_i387"
3908   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3909         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3910   "TARGET_80387"
3911 {
3912   switch (which_alternative)
3913     {
3914     case 0:
3915       return output_387_reg_move (insn, operands);
3916
3917     case 1:
3918       /* There is no non-popping store to memory for XFmode.  So if
3919          we need one, follow the store with a load.  */
3920       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3921         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3922       else
3923         return "fstp%z0\t%y0";
3924
3925     default:
3926       gcc_unreachable ();
3927     }
3928 }
3929   [(set_attr "type" "fmov")
3930    (set_attr "mode" "DF,XF")])
3931
3932 ;; %%% This seems bad bad news.
3933 ;; This cannot output into an f-reg because there is no way to be sure
3934 ;; of truncating in that case.  Otherwise this is just like a simple move
3935 ;; insn.  So we pretend we can output to a reg in order to get better
3936 ;; register preferencing, but we really use a stack slot.
3937
3938 ;; Conversion from DFmode to SFmode.
3939
3940 (define_expand "truncdfsf2"
3941   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3942         (float_truncate:SF
3943           (match_operand:DF 1 "nonimmediate_operand" "")))]
3944   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3945 {
3946   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3947     ;
3948   else if (flag_unsafe_math_optimizations)
3949     ;
3950   else
3951     {
3952       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3953       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3954       DONE;
3955     }
3956 })
3957
3958 (define_expand "truncdfsf2_with_temp"
3959   [(parallel [(set (match_operand:SF 0 "" "")
3960                    (float_truncate:SF (match_operand:DF 1 "" "")))
3961               (clobber (match_operand:SF 2 "" ""))])]
3962   "")
3963
3964 (define_insn "*truncdfsf_fast_mixed"
3965   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,x")
3966         (float_truncate:SF
3967           (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
3968   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3969 {
3970   switch (which_alternative)
3971     {
3972     case 0:
3973       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3974         return "fstp%z0\t%y0";
3975       else
3976         return "fst%z0\t%y0";
3977     case 1:
3978       return output_387_reg_move (insn, operands);
3979     case 2:
3980       return "cvtsd2ss\t{%1, %0|%0, %1}";
3981     default:
3982       gcc_unreachable ();
3983     }
3984 }
3985   [(set_attr "type" "fmov,fmov,ssecvt")
3986    (set_attr "mode" "SF")])
3987
3988 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3989 ;; because nothing we do here is unsafe.
3990 (define_insn "*truncdfsf_fast_sse"
3991   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
3992         (float_truncate:SF
3993           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
3994   "TARGET_SSE2 && TARGET_SSE_MATH"
3995   "cvtsd2ss\t{%1, %0|%0, %1}"
3996   [(set_attr "type" "ssecvt")
3997    (set_attr "mode" "SF")])
3998
3999 (define_insn "*truncdfsf_fast_i387"
4000   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4001         (float_truncate:SF
4002           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4003   "TARGET_80387 && flag_unsafe_math_optimizations"
4004   "* return output_387_reg_move (insn, operands);"
4005   [(set_attr "type" "fmov")
4006    (set_attr "mode" "SF")])
4007
4008 (define_insn "*truncdfsf_mixed"
4009   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y2")
4010         (float_truncate:SF
4011           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Y2m")))
4012    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
4013   "TARGET_MIX_SSE_I387"
4014 {
4015   switch (which_alternative)
4016     {
4017     case 0:
4018       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4019         return "fstp%z0\t%y0";
4020       else
4021         return "fst%z0\t%y0";
4022     case 1:
4023       return "#";
4024     case 2:
4025       return "cvtsd2ss\t{%1, %0|%0, %1}";
4026     default:
4027       gcc_unreachable ();
4028     }
4029 }
4030   [(set_attr "type" "fmov,multi,ssecvt")
4031    (set_attr "unit" "*,i387,*")
4032    (set_attr "mode" "SF")])
4033
4034 (define_insn "*truncdfsf_i387"
4035   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4036         (float_truncate:SF
4037           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4038    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4039   "TARGET_80387"
4040 {
4041   switch (which_alternative)
4042     {
4043     case 0:
4044       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4045         return "fstp%z0\t%y0";
4046       else
4047         return "fst%z0\t%y0";
4048     case 1:
4049       return "#";
4050     default:
4051       gcc_unreachable ();
4052     }
4053 }
4054   [(set_attr "type" "fmov,multi")
4055    (set_attr "unit" "*,i387")
4056    (set_attr "mode" "SF")])
4057
4058 (define_insn "*truncdfsf2_i387_1"
4059   [(set (match_operand:SF 0 "memory_operand" "=m")
4060         (float_truncate:SF
4061           (match_operand:DF 1 "register_operand" "f")))]
4062   "TARGET_80387
4063    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4064    && !TARGET_MIX_SSE_I387"
4065 {
4066   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4067     return "fstp%z0\t%y0";
4068   else
4069     return "fst%z0\t%y0";
4070 }
4071   [(set_attr "type" "fmov")
4072    (set_attr "mode" "SF")])
4073
4074 (define_split
4075   [(set (match_operand:SF 0 "register_operand" "")
4076         (float_truncate:SF
4077          (match_operand:DF 1 "fp_register_operand" "")))
4078    (clobber (match_operand 2 "" ""))]
4079   "reload_completed"
4080   [(set (match_dup 2) (match_dup 1))
4081    (set (match_dup 0) (match_dup 2))]
4082 {
4083   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4084 })
4085
4086 ;; Conversion from XFmode to SFmode.
4087
4088 (define_expand "truncxfsf2"
4089   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4090                    (float_truncate:SF
4091                     (match_operand:XF 1 "register_operand" "")))
4092               (clobber (match_dup 2))])]
4093   "TARGET_80387"
4094 {
4095   if (flag_unsafe_math_optimizations)
4096     {
4097       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
4098       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
4099       if (reg != operands[0])
4100         emit_move_insn (operands[0], reg);
4101       DONE;
4102     }
4103   else
4104     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
4105 })
4106
4107 (define_insn "*truncxfsf2_mixed"
4108   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
4109         (float_truncate:SF
4110          (match_operand:XF 1 "register_operand" "f,f,f,f")))
4111    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4112   "TARGET_80387"
4113 {
4114   gcc_assert (!which_alternative);
4115   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4116     return "fstp%z0\t%y0";
4117   else
4118     return "fst%z0\t%y0";
4119 }
4120   [(set_attr "type" "fmov,multi,multi,multi")
4121    (set_attr "unit" "*,i387,i387,i387")
4122    (set_attr "mode" "SF")])
4123
4124 (define_insn "truncxfsf2_i387_noop"
4125   [(set (match_operand:SF 0 "register_operand" "=f")
4126         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
4127   "TARGET_80387 && flag_unsafe_math_optimizations"
4128   "* return output_387_reg_move (insn, operands);"
4129   [(set_attr "type" "fmov")
4130    (set_attr "mode" "SF")])
4131
4132 (define_insn "*truncxfsf2_i387"
4133   [(set (match_operand:SF 0 "memory_operand" "=m")
4134         (float_truncate:SF
4135          (match_operand:XF 1 "register_operand" "f")))]
4136   "TARGET_80387"
4137 {
4138   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4139     return "fstp%z0\t%y0";
4140   else
4141     return "fst%z0\t%y0";
4142 }
4143   [(set_attr "type" "fmov")
4144    (set_attr "mode" "SF")])
4145
4146 (define_split
4147   [(set (match_operand:SF 0 "register_operand" "")
4148         (float_truncate:SF
4149          (match_operand:XF 1 "register_operand" "")))
4150    (clobber (match_operand:SF 2 "memory_operand" ""))]
4151   "TARGET_80387 && reload_completed"
4152   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4153    (set (match_dup 0) (match_dup 2))]
4154   "")
4155
4156 (define_split
4157   [(set (match_operand:SF 0 "memory_operand" "")
4158         (float_truncate:SF
4159          (match_operand:XF 1 "register_operand" "")))
4160    (clobber (match_operand:SF 2 "memory_operand" ""))]
4161   "TARGET_80387"
4162   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4163   "")
4164
4165 ;; Conversion from XFmode to DFmode.
4166
4167 (define_expand "truncxfdf2"
4168   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4169                    (float_truncate:DF
4170                     (match_operand:XF 1 "register_operand" "")))
4171               (clobber (match_dup 2))])]
4172   "TARGET_80387"
4173 {
4174   if (flag_unsafe_math_optimizations)
4175     {
4176       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
4177       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
4178       if (reg != operands[0])
4179         emit_move_insn (operands[0], reg);
4180       DONE;
4181     }
4182   else
4183     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
4184 })
4185
4186 (define_insn "*truncxfdf2_mixed"
4187   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y2*x")
4188         (float_truncate:DF
4189          (match_operand:XF 1 "register_operand" "f,f,f,f")))
4190    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4191   "TARGET_80387"
4192 {
4193   gcc_assert (!which_alternative);
4194   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4195     return "fstp%z0\t%y0";
4196   else
4197     return "fst%z0\t%y0";
4198 }
4199   [(set_attr "type" "fmov,multi,multi,multi")
4200    (set_attr "unit" "*,i387,i387,i387")
4201    (set_attr "mode" "DF")])
4202
4203 (define_insn "truncxfdf2_i387_noop"
4204   [(set (match_operand:DF 0 "register_operand" "=f")
4205         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4206   "TARGET_80387 && flag_unsafe_math_optimizations"
4207   "* return output_387_reg_move (insn, operands);"
4208   [(set_attr "type" "fmov")
4209    (set_attr "mode" "DF")])
4210
4211 (define_insn "*truncxfdf2_i387"
4212   [(set (match_operand:DF 0 "memory_operand" "=m")
4213         (float_truncate:DF
4214           (match_operand:XF 1 "register_operand" "f")))]
4215   "TARGET_80387"
4216 {
4217   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4218     return "fstp%z0\t%y0";
4219   else
4220     return "fst%z0\t%y0";
4221 }
4222   [(set_attr "type" "fmov")
4223    (set_attr "mode" "DF")])
4224
4225 (define_split
4226   [(set (match_operand:DF 0 "register_operand" "")
4227         (float_truncate:DF
4228          (match_operand:XF 1 "register_operand" "")))
4229    (clobber (match_operand:DF 2 "memory_operand" ""))]
4230   "TARGET_80387 && reload_completed"
4231   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4232    (set (match_dup 0) (match_dup 2))]
4233   "")
4234
4235 (define_split
4236   [(set (match_operand:DF 0 "memory_operand" "")
4237         (float_truncate:DF
4238          (match_operand:XF 1 "register_operand" "")))
4239    (clobber (match_operand:DF 2 "memory_operand" ""))]
4240   "TARGET_80387"
4241   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4242   "")
4243 \f
4244 ;; Signed conversion to DImode.
4245
4246 (define_expand "fix_truncxfdi2"
4247   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4248                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4249               (clobber (reg:CC FLAGS_REG))])]
4250   "TARGET_80387"
4251 {
4252   if (TARGET_FISTTP)
4253    {
4254      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4255      DONE;
4256    }
4257 })
4258
4259 (define_expand "fix_trunc<mode>di2"
4260   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4261                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4262               (clobber (reg:CC FLAGS_REG))])]
4263   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4264 {
4265   if (TARGET_FISTTP
4266       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4267    {
4268      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4269      DONE;
4270    }
4271   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4272    {
4273      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4274      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4275      if (out != operands[0])
4276         emit_move_insn (operands[0], out);
4277      DONE;
4278    }
4279 })
4280
4281 ;; Signed conversion to SImode.
4282
4283 (define_expand "fix_truncxfsi2"
4284   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4285                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4286               (clobber (reg:CC FLAGS_REG))])]
4287   "TARGET_80387"
4288 {
4289   if (TARGET_FISTTP)
4290    {
4291      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4292      DONE;
4293    }
4294 })
4295
4296 (define_expand "fix_trunc<mode>si2"
4297   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4298                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4299               (clobber (reg:CC FLAGS_REG))])]
4300   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4301 {
4302   if (TARGET_FISTTP
4303       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4304    {
4305      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4306      DONE;
4307    }
4308   if (SSE_FLOAT_MODE_P (<MODE>mode))
4309    {
4310      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4311      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4312      if (out != operands[0])
4313         emit_move_insn (operands[0], out);
4314      DONE;
4315    }
4316 })
4317
4318 ;; Signed conversion to HImode.
4319
4320 (define_expand "fix_trunc<mode>hi2"
4321   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4322                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4323               (clobber (reg:CC FLAGS_REG))])]
4324   "TARGET_80387
4325    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4326 {
4327   if (TARGET_FISTTP)
4328    {
4329      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4330      DONE;
4331    }
4332 })
4333
4334 ;; Unsigned conversion to SImode.
4335
4336 (define_expand "fixuns_trunc<mode>si2"
4337   [(parallel
4338     [(set (match_operand:SI 0 "register_operand" "")
4339           (unsigned_fix:SI
4340             (match_operand:SSEMODEF 1 "nonimmediate_operand" "")))
4341      (use (match_dup 2))
4342      (clobber (match_scratch:<ssevecmode> 3 ""))
4343      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4344   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4345 {
4346   enum machine_mode mode = <MODE>mode;
4347   enum machine_mode vecmode = <ssevecmode>mode;
4348   REAL_VALUE_TYPE TWO31r;
4349   rtx two31;
4350
4351   real_ldexp (&TWO31r, &dconst1, 31);
4352   two31 = const_double_from_real_value (TWO31r, mode);
4353   two31 = ix86_build_const_vector (mode, true, two31);
4354   operands[2] = force_reg (vecmode, two31);
4355 })
4356
4357 (define_insn_and_split "*fixuns_trunc<mode>_1"
4358   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4359         (unsigned_fix:SI
4360           (match_operand:SSEMODEF 3 "nonimmediate_operand" "xm,xm")))
4361    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4362    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4363    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4364   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4365   "#"
4366   "&& reload_completed"
4367   [(const_int 0)]
4368 {
4369   ix86_split_convert_uns_si_sse (operands);
4370   DONE;
4371 })
4372
4373 ;; Unsigned conversion to HImode.
4374 ;; Without these patterns, we'll try the unsigned SI conversion which
4375 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4376
4377 (define_expand "fixuns_truncsfhi2"
4378   [(set (match_dup 2)
4379         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "")))
4380    (set (match_operand:HI 0 "nonimmediate_operand" "")
4381         (subreg:HI (match_dup 2) 0))]
4382   "TARGET_SSE_MATH"
4383   "operands[2] = gen_reg_rtx (SImode);")
4384
4385 (define_expand "fixuns_truncdfhi2"
4386   [(set (match_dup 2)
4387         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "")))
4388    (set (match_operand:HI 0 "nonimmediate_operand" "")
4389         (subreg:HI (match_dup 2) 0))]
4390   "TARGET_SSE_MATH && TARGET_SSE2"
4391   "operands[2] = gen_reg_rtx (SImode);")
4392
4393 ;; When SSE is available, it is always faster to use it!
4394 (define_insn "fix_truncsfdi_sse"
4395   [(set (match_operand:DI 0 "register_operand" "=r,r")
4396         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4397   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4398   "cvttss2si{q}\t{%1, %0|%0, %1}"
4399   [(set_attr "type" "sseicvt")
4400    (set_attr "mode" "SF")
4401    (set_attr "athlon_decode" "double,vector")
4402    (set_attr "amdfam10_decode" "double,double")])
4403
4404 (define_insn "fix_truncdfdi_sse"
4405   [(set (match_operand:DI 0 "register_operand" "=r,r")
4406         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "x,xm")))]
4407   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4408   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4409   [(set_attr "type" "sseicvt")
4410    (set_attr "mode" "DF")
4411    (set_attr "athlon_decode" "double,vector")
4412    (set_attr "amdfam10_decode" "double,double")])
4413
4414 (define_insn "fix_truncsfsi_sse"
4415   [(set (match_operand:SI 0 "register_operand" "=r,r")
4416         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4417   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4418   "cvttss2si\t{%1, %0|%0, %1}"
4419   [(set_attr "type" "sseicvt")
4420    (set_attr "mode" "DF")
4421    (set_attr "athlon_decode" "double,vector")
4422    (set_attr "amdfam10_decode" "double,double")])
4423
4424 (define_insn "fix_truncdfsi_sse"
4425   [(set (match_operand:SI 0 "register_operand" "=r,r")
4426         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "x,xm")))]
4427   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4428   "cvttsd2si\t{%1, %0|%0, %1}"
4429   [(set_attr "type" "sseicvt")
4430    (set_attr "mode" "DF")
4431    (set_attr "athlon_decode" "double,vector")
4432    (set_attr "amdfam10_decode" "double,double")])
4433
4434 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4435 (define_peephole2
4436   [(set (match_operand:DF 0 "register_operand" "")
4437         (match_operand:DF 1 "memory_operand" ""))
4438    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4439         (fix:SSEMODEI24 (match_dup 0)))]
4440   "!TARGET_K8
4441    && peep2_reg_dead_p (2, operands[0])"
4442   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4443   "")
4444
4445 (define_peephole2
4446   [(set (match_operand:SF 0 "register_operand" "")
4447         (match_operand:SF 1 "memory_operand" ""))
4448    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4449         (fix:SSEMODEI24 (match_dup 0)))]
4450   "!TARGET_K8
4451    && peep2_reg_dead_p (2, operands[0])"
4452   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4453   "")
4454
4455 ;; Avoid vector decoded forms of the instruction.
4456 (define_peephole2
4457   [(match_scratch:DF 2 "Y")
4458    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4459         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4460   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4461   [(set (match_dup 2) (match_dup 1))
4462    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4463   "")
4464
4465 (define_peephole2
4466   [(match_scratch:SF 2 "x")
4467    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4468         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4469   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4470   [(set (match_dup 2) (match_dup 1))
4471    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4472   "")
4473
4474 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4475   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4476         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4477   "TARGET_FISTTP
4478    && FLOAT_MODE_P (GET_MODE (operands[1]))
4479    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4480          && (TARGET_64BIT || <MODE>mode != DImode))
4481         && TARGET_SSE_MATH)
4482    && !(reload_completed || reload_in_progress)"
4483   "#"
4484   "&& 1"
4485   [(const_int 0)]
4486 {
4487   if (memory_operand (operands[0], VOIDmode))
4488     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4489   else
4490     {
4491       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4492       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4493                                                             operands[1],
4494                                                             operands[2]));
4495     }
4496   DONE;
4497 }
4498   [(set_attr "type" "fisttp")
4499    (set_attr "mode" "<MODE>")])
4500
4501 (define_insn "fix_trunc<mode>_i387_fisttp"
4502   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4503         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4504    (clobber (match_scratch:XF 2 "=&1f"))]
4505   "TARGET_FISTTP
4506    && FLOAT_MODE_P (GET_MODE (operands[1]))
4507    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4508          && (TARGET_64BIT || <MODE>mode != DImode))
4509         && TARGET_SSE_MATH)"
4510   "* return output_fix_trunc (insn, operands, 1);"
4511   [(set_attr "type" "fisttp")
4512    (set_attr "mode" "<MODE>")])
4513
4514 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4515   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4516         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4517    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4518    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4519   "TARGET_FISTTP
4520    && FLOAT_MODE_P (GET_MODE (operands[1]))
4521    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4522         && (TARGET_64BIT || <MODE>mode != DImode))
4523         && TARGET_SSE_MATH)"
4524   "#"
4525   [(set_attr "type" "fisttp")
4526    (set_attr "mode" "<MODE>")])
4527
4528 (define_split
4529   [(set (match_operand:X87MODEI 0 "register_operand" "")
4530         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4531    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4532    (clobber (match_scratch 3 ""))]
4533   "reload_completed"
4534   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4535               (clobber (match_dup 3))])
4536    (set (match_dup 0) (match_dup 2))]
4537   "")
4538
4539 (define_split
4540   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4541         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4542    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4543    (clobber (match_scratch 3 ""))]
4544   "reload_completed"
4545   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4546               (clobber (match_dup 3))])]
4547   "")
4548
4549 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4550 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4551 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4552 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4553 ;; function in i386.c.
4554 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4555   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4556         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4557    (clobber (reg:CC FLAGS_REG))]
4558   "TARGET_80387 && !TARGET_FISTTP
4559    && FLOAT_MODE_P (GET_MODE (operands[1]))
4560    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4561          && (TARGET_64BIT || <MODE>mode != DImode))
4562    && !(reload_completed || reload_in_progress)"
4563   "#"
4564   "&& 1"
4565   [(const_int 0)]
4566 {
4567   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4568
4569   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4570   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4571   if (memory_operand (operands[0], VOIDmode))
4572     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4573                                          operands[2], operands[3]));
4574   else
4575     {
4576       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4577       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4578                                                      operands[2], operands[3],
4579                                                      operands[4]));
4580     }
4581   DONE;
4582 }
4583   [(set_attr "type" "fistp")
4584    (set_attr "i387_cw" "trunc")
4585    (set_attr "mode" "<MODE>")])
4586
4587 (define_insn "fix_truncdi_i387"
4588   [(set (match_operand:DI 0 "memory_operand" "=m")
4589         (fix:DI (match_operand 1 "register_operand" "f")))
4590    (use (match_operand:HI 2 "memory_operand" "m"))
4591    (use (match_operand:HI 3 "memory_operand" "m"))
4592    (clobber (match_scratch:XF 4 "=&1f"))]
4593   "TARGET_80387 && !TARGET_FISTTP
4594    && FLOAT_MODE_P (GET_MODE (operands[1]))
4595    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4596   "* return output_fix_trunc (insn, operands, 0);"
4597   [(set_attr "type" "fistp")
4598    (set_attr "i387_cw" "trunc")
4599    (set_attr "mode" "DI")])
4600
4601 (define_insn "fix_truncdi_i387_with_temp"
4602   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4603         (fix:DI (match_operand 1 "register_operand" "f,f")))
4604    (use (match_operand:HI 2 "memory_operand" "m,m"))
4605    (use (match_operand:HI 3 "memory_operand" "m,m"))
4606    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4607    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4608   "TARGET_80387 && !TARGET_FISTTP
4609    && FLOAT_MODE_P (GET_MODE (operands[1]))
4610    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4611   "#"
4612   [(set_attr "type" "fistp")
4613    (set_attr "i387_cw" "trunc")
4614    (set_attr "mode" "DI")])
4615
4616 (define_split
4617   [(set (match_operand:DI 0 "register_operand" "")
4618         (fix:DI (match_operand 1 "register_operand" "")))
4619    (use (match_operand:HI 2 "memory_operand" ""))
4620    (use (match_operand:HI 3 "memory_operand" ""))
4621    (clobber (match_operand:DI 4 "memory_operand" ""))
4622    (clobber (match_scratch 5 ""))]
4623   "reload_completed"
4624   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4625               (use (match_dup 2))
4626               (use (match_dup 3))
4627               (clobber (match_dup 5))])
4628    (set (match_dup 0) (match_dup 4))]
4629   "")
4630
4631 (define_split
4632   [(set (match_operand:DI 0 "memory_operand" "")
4633         (fix:DI (match_operand 1 "register_operand" "")))
4634    (use (match_operand:HI 2 "memory_operand" ""))
4635    (use (match_operand:HI 3 "memory_operand" ""))
4636    (clobber (match_operand:DI 4 "memory_operand" ""))
4637    (clobber (match_scratch 5 ""))]
4638   "reload_completed"
4639   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4640               (use (match_dup 2))
4641               (use (match_dup 3))
4642               (clobber (match_dup 5))])]
4643   "")
4644
4645 (define_insn "fix_trunc<mode>_i387"
4646   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4647         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4648    (use (match_operand:HI 2 "memory_operand" "m"))
4649    (use (match_operand:HI 3 "memory_operand" "m"))]
4650   "TARGET_80387 && !TARGET_FISTTP
4651    && FLOAT_MODE_P (GET_MODE (operands[1]))
4652    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4653   "* return output_fix_trunc (insn, operands, 0);"
4654   [(set_attr "type" "fistp")
4655    (set_attr "i387_cw" "trunc")
4656    (set_attr "mode" "<MODE>")])
4657
4658 (define_insn "fix_trunc<mode>_i387_with_temp"
4659   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4660         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4661    (use (match_operand:HI 2 "memory_operand" "m,m"))
4662    (use (match_operand:HI 3 "memory_operand" "m,m"))
4663    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4664   "TARGET_80387 && !TARGET_FISTTP
4665    && FLOAT_MODE_P (GET_MODE (operands[1]))
4666    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4667   "#"
4668   [(set_attr "type" "fistp")
4669    (set_attr "i387_cw" "trunc")
4670    (set_attr "mode" "<MODE>")])
4671
4672 (define_split
4673   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4674         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4675    (use (match_operand:HI 2 "memory_operand" ""))
4676    (use (match_operand:HI 3 "memory_operand" ""))
4677    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4678   "reload_completed"
4679   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4680               (use (match_dup 2))
4681               (use (match_dup 3))])
4682    (set (match_dup 0) (match_dup 4))]
4683   "")
4684
4685 (define_split
4686   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4687         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4688    (use (match_operand:HI 2 "memory_operand" ""))
4689    (use (match_operand:HI 3 "memory_operand" ""))
4690    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4691   "reload_completed"
4692   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4693               (use (match_dup 2))
4694               (use (match_dup 3))])]
4695   "")
4696
4697 (define_insn "x86_fnstcw_1"
4698   [(set (match_operand:HI 0 "memory_operand" "=m")
4699         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4700   "TARGET_80387"
4701   "fnstcw\t%0"
4702   [(set_attr "length" "2")
4703    (set_attr "mode" "HI")
4704    (set_attr "unit" "i387")])
4705
4706 (define_insn "x86_fldcw_1"
4707   [(set (reg:HI FPCR_REG)
4708         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4709   "TARGET_80387"
4710   "fldcw\t%0"
4711   [(set_attr "length" "2")
4712    (set_attr "mode" "HI")
4713    (set_attr "unit" "i387")
4714    (set_attr "athlon_decode" "vector")
4715    (set_attr "amdfam10_decode" "vector")])   
4716 \f
4717 ;; Conversion between fixed point and floating point.
4718
4719 ;; Even though we only accept memory inputs, the backend _really_
4720 ;; wants to be able to do this between registers.
4721
4722 (define_expand "floathisf2"
4723   [(set (match_operand:SF 0 "register_operand" "")
4724         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4725   "TARGET_80387 || TARGET_SSE_MATH"
4726 {
4727   if (TARGET_SSE_MATH)
4728     {
4729       emit_insn (gen_floatsisf2 (operands[0],
4730                                  convert_to_mode (SImode, operands[1], 0)));
4731       DONE;
4732     }
4733 })
4734
4735 (define_insn "*floathisf2_i387"
4736   [(set (match_operand:SF 0 "register_operand" "=f,f")
4737         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4738   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4739   "@
4740    fild%z1\t%1
4741    #"
4742   [(set_attr "type" "fmov,multi")
4743    (set_attr "mode" "SF")
4744    (set_attr "unit" "*,i387")
4745    (set_attr "fp_int_src" "true")])
4746
4747 (define_expand "floatsisf2"
4748   [(set (match_operand:SF 0 "register_operand" "")
4749         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4750   "TARGET_80387 || TARGET_SSE_MATH"
4751   "")
4752
4753 (define_insn "*floatsisf2_mixed"
4754   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4755         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4756   "TARGET_MIX_SSE_I387"
4757   "@
4758    fild%z1\t%1
4759    #
4760    cvtsi2ss\t{%1, %0|%0, %1}
4761    cvtsi2ss\t{%1, %0|%0, %1}"
4762   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4763    (set_attr "mode" "SF")
4764    (set_attr "unit" "*,i387,*,*")
4765    (set_attr "athlon_decode" "*,*,vector,double")
4766    (set_attr "amdfam10_decode" "*,*,vector,double")
4767    (set_attr "fp_int_src" "true")])
4768
4769 (define_insn "*floatsisf2_sse"
4770   [(set (match_operand:SF 0 "register_operand" "=x,x")
4771         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4772   "TARGET_SSE_MATH"
4773   "cvtsi2ss\t{%1, %0|%0, %1}"
4774   [(set_attr "type" "sseicvt")
4775    (set_attr "mode" "SF")
4776    (set_attr "athlon_decode" "vector,double")
4777    (set_attr "amdfam10_decode" "vector,double")
4778    (set_attr "fp_int_src" "true")])
4779
4780 (define_insn "*floatsisf2_i387"
4781   [(set (match_operand:SF 0 "register_operand" "=f,f")
4782         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4783   "TARGET_80387"
4784   "@
4785    fild%z1\t%1
4786    #"
4787   [(set_attr "type" "fmov,multi")
4788    (set_attr "mode" "SF")
4789    (set_attr "unit" "*,i387")
4790    (set_attr "fp_int_src" "true")])
4791
4792 (define_expand "floatdisf2"
4793   [(set (match_operand:SF 0 "register_operand" "")
4794         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4795   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4796   "")
4797
4798 (define_insn "*floatdisf2_mixed"
4799   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4800         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4801   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4802   "@
4803    fild%z1\t%1
4804    #
4805    cvtsi2ss{q}\t{%1, %0|%0, %1}
4806    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4807   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4808    (set_attr "mode" "SF")
4809    (set_attr "unit" "*,i387,*,*")
4810    (set_attr "athlon_decode" "*,*,vector,double")
4811    (set_attr "amdfam10_decode" "*,*,vector,double")
4812    (set_attr "fp_int_src" "true")])
4813
4814 (define_insn "*floatdisf2_sse"
4815   [(set (match_operand:SF 0 "register_operand" "=x,x")
4816         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4817   "TARGET_64BIT && TARGET_SSE_MATH"
4818   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4819   [(set_attr "type" "sseicvt")
4820    (set_attr "mode" "SF")
4821    (set_attr "athlon_decode" "vector,double")
4822    (set_attr "amdfam10_decode" "vector,double")
4823    (set_attr "fp_int_src" "true")])
4824
4825 (define_insn "*floatdisf2_i387"
4826   [(set (match_operand:SF 0 "register_operand" "=f,f")
4827         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4828   "TARGET_80387"
4829   "@
4830    fild%z1\t%1
4831    #"
4832   [(set_attr "type" "fmov,multi")
4833    (set_attr "mode" "SF")
4834    (set_attr "unit" "*,i387")
4835    (set_attr "fp_int_src" "true")])
4836
4837 (define_expand "floathidf2"
4838   [(set (match_operand:DF 0 "register_operand" "")
4839         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4840   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4841 {
4842   if (TARGET_SSE2 && TARGET_SSE_MATH)
4843     {
4844       emit_insn (gen_floatsidf2 (operands[0],
4845                                  convert_to_mode (SImode, operands[1], 0)));
4846       DONE;
4847     }
4848 })
4849
4850 (define_insn "*floathidf2_i387"
4851   [(set (match_operand:DF 0 "register_operand" "=f,f")
4852         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4853   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4854   "@
4855    fild%z1\t%1
4856    #"
4857   [(set_attr "type" "fmov,multi")
4858    (set_attr "mode" "DF")
4859    (set_attr "unit" "*,i387")
4860    (set_attr "fp_int_src" "true")])
4861
4862 (define_expand "floatsidf2"
4863   [(set (match_operand:DF 0 "register_operand" "")
4864         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4865   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4866   "")
4867
4868 (define_insn "*floatsidf2_mixed"
4869   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4870         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4871   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4872   "@
4873    fild%z1\t%1
4874    #
4875    cvtsi2sd\t{%1, %0|%0, %1}
4876    cvtsi2sd\t{%1, %0|%0, %1}"
4877   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4878    (set_attr "mode" "DF")
4879    (set_attr "unit" "*,i387,*,*")
4880    (set_attr "athlon_decode" "*,*,double,direct")
4881    (set_attr "amdfam10_decode" "*,*,vector,double")
4882    (set_attr "fp_int_src" "true")])
4883
4884 (define_insn "*floatsidf2_sse"
4885   [(set (match_operand:DF 0 "register_operand" "=x,x")
4886         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4887   "TARGET_SSE2 && TARGET_SSE_MATH"
4888   "cvtsi2sd\t{%1, %0|%0, %1}"
4889   [(set_attr "type" "sseicvt")
4890    (set_attr "mode" "DF")
4891    (set_attr "athlon_decode" "double,direct")
4892    (set_attr "amdfam10_decode" "vector,double")
4893    (set_attr "fp_int_src" "true")])
4894
4895 (define_insn "*floatsidf2_i387"
4896   [(set (match_operand:DF 0 "register_operand" "=f,f")
4897         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4898   "TARGET_80387"
4899   "@
4900    fild%z1\t%1
4901    #"
4902   [(set_attr "type" "fmov,multi")
4903    (set_attr "mode" "DF")
4904    (set_attr "unit" "*,i387")
4905    (set_attr "fp_int_src" "true")])
4906
4907 (define_expand "floatdidf2"
4908   [(set (match_operand:DF 0 "register_operand" "")
4909         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4910   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4911 {
4912   if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
4913     {
4914       ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
4915       DONE;
4916     }
4917 })
4918
4919 (define_insn "*floatdidf2_mixed"
4920   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4921         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4922   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4923   "@
4924    fild%z1\t%1
4925    #
4926    cvtsi2sd{q}\t{%1, %0|%0, %1}
4927    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4928   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4929    (set_attr "mode" "DF")
4930    (set_attr "unit" "*,i387,*,*")
4931    (set_attr "athlon_decode" "*,*,double,direct")
4932    (set_attr "amdfam10_decode" "*,*,vector,double")
4933    (set_attr "fp_int_src" "true")])
4934
4935 (define_insn "*floatdidf2_sse"
4936   [(set (match_operand:DF 0 "register_operand" "=x,x")
4937         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4938   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4939   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4940   [(set_attr "type" "sseicvt")
4941    (set_attr "mode" "DF")
4942    (set_attr "athlon_decode" "double,direct")
4943    (set_attr "amdfam10_decode" "vector,double")
4944    (set_attr "fp_int_src" "true")])
4945
4946 (define_insn "*floatdidf2_i387"
4947   [(set (match_operand:DF 0 "register_operand" "=f,f")
4948         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4949   "TARGET_80387"
4950   "@
4951    fild%z1\t%1
4952    #"
4953   [(set_attr "type" "fmov,multi")
4954    (set_attr "mode" "DF")
4955    (set_attr "unit" "*,i387")
4956    (set_attr "fp_int_src" "true")])
4957
4958 (define_insn "floathixf2"
4959   [(set (match_operand:XF 0 "register_operand" "=f,f")
4960         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4961   "TARGET_80387"
4962   "@
4963    fild%z1\t%1
4964    #"
4965   [(set_attr "type" "fmov,multi")
4966    (set_attr "mode" "XF")
4967    (set_attr "unit" "*,i387")
4968    (set_attr "fp_int_src" "true")])
4969
4970 (define_insn "floatsixf2"
4971   [(set (match_operand:XF 0 "register_operand" "=f,f")
4972         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4973   "TARGET_80387"
4974   "@
4975    fild%z1\t%1
4976    #"
4977   [(set_attr "type" "fmov,multi")
4978    (set_attr "mode" "XF")
4979    (set_attr "unit" "*,i387")
4980    (set_attr "fp_int_src" "true")])
4981
4982 (define_insn "floatdixf2"
4983   [(set (match_operand:XF 0 "register_operand" "=f,f")
4984         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4985   "TARGET_80387"
4986   "@
4987    fild%z1\t%1
4988    #"
4989   [(set_attr "type" "fmov,multi")
4990    (set_attr "mode" "XF")
4991    (set_attr "unit" "*,i387")
4992    (set_attr "fp_int_src" "true")])
4993
4994 ;; %%% Kill these when reload knows how to do it.
4995 (define_split
4996   [(set (match_operand 0 "fp_register_operand" "")
4997         (float (match_operand 1 "register_operand" "")))]
4998   "reload_completed
4999    && TARGET_80387
5000    && FLOAT_MODE_P (GET_MODE (operands[0]))"
5001   [(const_int 0)]
5002 {
5003   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5004   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5005   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5006   ix86_free_from_memory (GET_MODE (operands[1]));
5007   DONE;
5008 })
5009
5010 (define_expand "floatunssisf2"
5011   [(use (match_operand:SF 0 "register_operand" ""))
5012    (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5013   "!TARGET_64BIT"
5014 {
5015   if (TARGET_SSE_MATH && TARGET_SSE2)
5016     ix86_expand_convert_uns_sisf_sse (operands[0], operands[1]);
5017   else
5018     x86_emit_floatuns (operands);
5019   DONE;
5020 })
5021
5022 (define_expand "floatunssidf2"
5023   [(use (match_operand:DF 0 "register_operand" ""))
5024    (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5025   "!TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE2"
5026   "ix86_expand_convert_uns_sidf_sse (operands[0], operands[1]); DONE;")
5027
5028 (define_expand "floatunsdisf2"
5029   [(use (match_operand:SF 0 "register_operand" ""))
5030    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5031   "TARGET_64BIT && TARGET_SSE_MATH"
5032   "x86_emit_floatuns (operands); DONE;")
5033
5034 (define_expand "floatunsdidf2"
5035   [(use (match_operand:DF 0 "register_operand" ""))
5036    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5037   "TARGET_SSE_MATH && TARGET_SSE2
5038    && (TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)"
5039 {
5040   if (TARGET_64BIT)
5041     x86_emit_floatuns (operands);
5042   else
5043     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5044   DONE;
5045 })
5046 \f
5047 ;; SSE extract/set expanders
5048
5049 \f
5050 ;; Add instructions
5051
5052 ;; %%% splits for addditi3
5053
5054 (define_expand "addti3"
5055   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5056         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5057                  (match_operand:TI 2 "x86_64_general_operand" "")))
5058    (clobber (reg:CC FLAGS_REG))]
5059   "TARGET_64BIT"
5060   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5061
5062 (define_insn "*addti3_1"
5063   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5064         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5065                  (match_operand:TI 2 "general_operand" "roiF,riF")))
5066    (clobber (reg:CC FLAGS_REG))]
5067   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5068   "#")
5069
5070 (define_split
5071   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5072         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5073                  (match_operand:TI 2 "general_operand" "")))
5074    (clobber (reg:CC FLAGS_REG))]
5075   "TARGET_64BIT && reload_completed"
5076   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5077                                           UNSPEC_ADD_CARRY))
5078               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5079    (parallel [(set (match_dup 3)
5080                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5081                                      (match_dup 4))
5082                             (match_dup 5)))
5083               (clobber (reg:CC FLAGS_REG))])]
5084   "split_ti (operands+0, 1, operands+0, operands+3);
5085    split_ti (operands+1, 1, operands+1, operands+4);
5086    split_ti (operands+2, 1, operands+2, operands+5);")
5087
5088 ;; %%% splits for addsidi3
5089 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5090 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5091 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5092
5093 (define_expand "adddi3"
5094   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5095         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5096                  (match_operand:DI 2 "x86_64_general_operand" "")))
5097    (clobber (reg:CC FLAGS_REG))]
5098   ""
5099   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5100
5101 (define_insn "*adddi3_1"
5102   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5103         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5104                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5105    (clobber (reg:CC FLAGS_REG))]
5106   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5107   "#")
5108
5109 (define_split
5110   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5111         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5112                  (match_operand:DI 2 "general_operand" "")))
5113    (clobber (reg:CC FLAGS_REG))]
5114   "!TARGET_64BIT && reload_completed"
5115   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5116                                           UNSPEC_ADD_CARRY))
5117               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5118    (parallel [(set (match_dup 3)
5119                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5120                                      (match_dup 4))
5121                             (match_dup 5)))
5122               (clobber (reg:CC FLAGS_REG))])]
5123   "split_di (operands+0, 1, operands+0, operands+3);
5124    split_di (operands+1, 1, operands+1, operands+4);
5125    split_di (operands+2, 1, operands+2, operands+5);")
5126
5127 (define_insn "adddi3_carry_rex64"
5128   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5129           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5130                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5131                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5132    (clobber (reg:CC FLAGS_REG))]
5133   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5134   "adc{q}\t{%2, %0|%0, %2}"
5135   [(set_attr "type" "alu")
5136    (set_attr "pent_pair" "pu")
5137    (set_attr "mode" "DI")])
5138
5139 (define_insn "*adddi3_cc_rex64"
5140   [(set (reg:CC FLAGS_REG)
5141         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5142                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5143                    UNSPEC_ADD_CARRY))
5144    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5145         (plus:DI (match_dup 1) (match_dup 2)))]
5146   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5147   "add{q}\t{%2, %0|%0, %2}"
5148   [(set_attr "type" "alu")
5149    (set_attr "mode" "DI")])
5150
5151 (define_insn "addqi3_carry"
5152   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5153           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5154                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5155                    (match_operand:QI 2 "general_operand" "qi,qm")))
5156    (clobber (reg:CC FLAGS_REG))]
5157   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5158   "adc{b}\t{%2, %0|%0, %2}"
5159   [(set_attr "type" "alu")
5160    (set_attr "pent_pair" "pu")
5161    (set_attr "mode" "QI")])
5162
5163 (define_insn "addhi3_carry"
5164   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5165           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5166                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5167                    (match_operand:HI 2 "general_operand" "ri,rm")))
5168    (clobber (reg:CC FLAGS_REG))]
5169   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5170   "adc{w}\t{%2, %0|%0, %2}"
5171   [(set_attr "type" "alu")
5172    (set_attr "pent_pair" "pu")
5173    (set_attr "mode" "HI")])
5174
5175 (define_insn "addsi3_carry"
5176   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5177           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5178                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5179                    (match_operand:SI 2 "general_operand" "ri,rm")))
5180    (clobber (reg:CC FLAGS_REG))]
5181   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5182   "adc{l}\t{%2, %0|%0, %2}"
5183   [(set_attr "type" "alu")
5184    (set_attr "pent_pair" "pu")
5185    (set_attr "mode" "SI")])
5186
5187 (define_insn "*addsi3_carry_zext"
5188   [(set (match_operand:DI 0 "register_operand" "=r")
5189           (zero_extend:DI
5190             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5191                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5192                      (match_operand:SI 2 "general_operand" "rim"))))
5193    (clobber (reg:CC FLAGS_REG))]
5194   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5195   "adc{l}\t{%2, %k0|%k0, %2}"
5196   [(set_attr "type" "alu")
5197    (set_attr "pent_pair" "pu")
5198    (set_attr "mode" "SI")])
5199
5200 (define_insn "*addsi3_cc"
5201   [(set (reg:CC FLAGS_REG)
5202         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5203                     (match_operand:SI 2 "general_operand" "ri,rm")]
5204                    UNSPEC_ADD_CARRY))
5205    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5206         (plus:SI (match_dup 1) (match_dup 2)))]
5207   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5208   "add{l}\t{%2, %0|%0, %2}"
5209   [(set_attr "type" "alu")
5210    (set_attr "mode" "SI")])
5211
5212 (define_insn "addqi3_cc"
5213   [(set (reg:CC FLAGS_REG)
5214         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5215                     (match_operand:QI 2 "general_operand" "qi,qm")]
5216                    UNSPEC_ADD_CARRY))
5217    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5218         (plus:QI (match_dup 1) (match_dup 2)))]
5219   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5220   "add{b}\t{%2, %0|%0, %2}"
5221   [(set_attr "type" "alu")
5222    (set_attr "mode" "QI")])
5223
5224 (define_expand "addsi3"
5225   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5226                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5227                             (match_operand:SI 2 "general_operand" "")))
5228               (clobber (reg:CC FLAGS_REG))])]
5229   ""
5230   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5231
5232 (define_insn "*lea_1"
5233   [(set (match_operand:SI 0 "register_operand" "=r")
5234         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5235   "!TARGET_64BIT"
5236   "lea{l}\t{%a1, %0|%0, %a1}"
5237   [(set_attr "type" "lea")
5238    (set_attr "mode" "SI")])
5239
5240 (define_insn "*lea_1_rex64"
5241   [(set (match_operand:SI 0 "register_operand" "=r")
5242         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5243   "TARGET_64BIT"
5244   "lea{l}\t{%a1, %0|%0, %a1}"
5245   [(set_attr "type" "lea")
5246    (set_attr "mode" "SI")])
5247
5248 (define_insn "*lea_1_zext"
5249   [(set (match_operand:DI 0 "register_operand" "=r")
5250         (zero_extend:DI
5251          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5252   "TARGET_64BIT"
5253   "lea{l}\t{%a1, %k0|%k0, %a1}"
5254   [(set_attr "type" "lea")
5255    (set_attr "mode" "SI")])
5256
5257 (define_insn "*lea_2_rex64"
5258   [(set (match_operand:DI 0 "register_operand" "=r")
5259         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5260   "TARGET_64BIT"
5261   "lea{q}\t{%a1, %0|%0, %a1}"
5262   [(set_attr "type" "lea")
5263    (set_attr "mode" "DI")])
5264
5265 ;; The lea patterns for non-Pmodes needs to be matched by several
5266 ;; insns converted to real lea by splitters.
5267
5268 (define_insn_and_split "*lea_general_1"
5269   [(set (match_operand 0 "register_operand" "=r")
5270         (plus (plus (match_operand 1 "index_register_operand" "l")
5271                     (match_operand 2 "register_operand" "r"))
5272               (match_operand 3 "immediate_operand" "i")))]
5273   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5274     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5275    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5276    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5277    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5278    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5279        || GET_MODE (operands[3]) == VOIDmode)"
5280   "#"
5281   "&& reload_completed"
5282   [(const_int 0)]
5283 {
5284   rtx pat;
5285   operands[0] = gen_lowpart (SImode, operands[0]);
5286   operands[1] = gen_lowpart (Pmode, operands[1]);
5287   operands[2] = gen_lowpart (Pmode, operands[2]);
5288   operands[3] = gen_lowpart (Pmode, operands[3]);
5289   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5290                       operands[3]);
5291   if (Pmode != SImode)
5292     pat = gen_rtx_SUBREG (SImode, pat, 0);
5293   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5294   DONE;
5295 }
5296   [(set_attr "type" "lea")
5297    (set_attr "mode" "SI")])
5298
5299 (define_insn_and_split "*lea_general_1_zext"
5300   [(set (match_operand:DI 0 "register_operand" "=r")
5301         (zero_extend:DI
5302           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5303                             (match_operand:SI 2 "register_operand" "r"))
5304                    (match_operand:SI 3 "immediate_operand" "i"))))]
5305   "TARGET_64BIT"
5306   "#"
5307   "&& reload_completed"
5308   [(set (match_dup 0)
5309         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5310                                                      (match_dup 2))
5311                                             (match_dup 3)) 0)))]
5312 {
5313   operands[1] = gen_lowpart (Pmode, operands[1]);
5314   operands[2] = gen_lowpart (Pmode, operands[2]);
5315   operands[3] = gen_lowpart (Pmode, operands[3]);
5316 }
5317   [(set_attr "type" "lea")
5318    (set_attr "mode" "SI")])
5319
5320 (define_insn_and_split "*lea_general_2"
5321   [(set (match_operand 0 "register_operand" "=r")
5322         (plus (mult (match_operand 1 "index_register_operand" "l")
5323                     (match_operand 2 "const248_operand" "i"))
5324               (match_operand 3 "nonmemory_operand" "ri")))]
5325   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5326     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5327    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5328    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5329    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5330        || GET_MODE (operands[3]) == VOIDmode)"
5331   "#"
5332   "&& reload_completed"
5333   [(const_int 0)]
5334 {
5335   rtx pat;
5336   operands[0] = gen_lowpart (SImode, operands[0]);
5337   operands[1] = gen_lowpart (Pmode, operands[1]);
5338   operands[3] = gen_lowpart (Pmode, operands[3]);
5339   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5340                       operands[3]);
5341   if (Pmode != SImode)
5342     pat = gen_rtx_SUBREG (SImode, pat, 0);
5343   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5344   DONE;
5345 }
5346   [(set_attr "type" "lea")
5347    (set_attr "mode" "SI")])
5348
5349 (define_insn_and_split "*lea_general_2_zext"
5350   [(set (match_operand:DI 0 "register_operand" "=r")
5351         (zero_extend:DI
5352           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5353                             (match_operand:SI 2 "const248_operand" "n"))
5354                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5355   "TARGET_64BIT"
5356   "#"
5357   "&& reload_completed"
5358   [(set (match_dup 0)
5359         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5360                                                      (match_dup 2))
5361                                             (match_dup 3)) 0)))]
5362 {
5363   operands[1] = gen_lowpart (Pmode, operands[1]);
5364   operands[3] = gen_lowpart (Pmode, operands[3]);
5365 }
5366   [(set_attr "type" "lea")
5367    (set_attr "mode" "SI")])
5368
5369 (define_insn_and_split "*lea_general_3"
5370   [(set (match_operand 0 "register_operand" "=r")
5371         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5372                           (match_operand 2 "const248_operand" "i"))
5373                     (match_operand 3 "register_operand" "r"))
5374               (match_operand 4 "immediate_operand" "i")))]
5375   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5376     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5377    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5378    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5379    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5380   "#"
5381   "&& reload_completed"
5382   [(const_int 0)]
5383 {
5384   rtx pat;
5385   operands[0] = gen_lowpart (SImode, operands[0]);
5386   operands[1] = gen_lowpart (Pmode, operands[1]);
5387   operands[3] = gen_lowpart (Pmode, operands[3]);
5388   operands[4] = gen_lowpart (Pmode, operands[4]);
5389   pat = gen_rtx_PLUS (Pmode,
5390                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5391                                                          operands[2]),
5392                                     operands[3]),
5393                       operands[4]);
5394   if (Pmode != SImode)
5395     pat = gen_rtx_SUBREG (SImode, pat, 0);
5396   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5397   DONE;
5398 }
5399   [(set_attr "type" "lea")
5400    (set_attr "mode" "SI")])
5401
5402 (define_insn_and_split "*lea_general_3_zext"
5403   [(set (match_operand:DI 0 "register_operand" "=r")
5404         (zero_extend:DI
5405           (plus:SI (plus:SI (mult:SI
5406                               (match_operand:SI 1 "index_register_operand" "l")
5407                               (match_operand:SI 2 "const248_operand" "n"))
5408                             (match_operand:SI 3 "register_operand" "r"))
5409                    (match_operand:SI 4 "immediate_operand" "i"))))]
5410   "TARGET_64BIT"
5411   "#"
5412   "&& reload_completed"
5413   [(set (match_dup 0)
5414         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5415                                                               (match_dup 2))
5416                                                      (match_dup 3))
5417                                             (match_dup 4)) 0)))]
5418 {
5419   operands[1] = gen_lowpart (Pmode, operands[1]);
5420   operands[3] = gen_lowpart (Pmode, operands[3]);
5421   operands[4] = gen_lowpart (Pmode, operands[4]);
5422 }
5423   [(set_attr "type" "lea")
5424    (set_attr "mode" "SI")])
5425
5426 (define_insn "*adddi_1_rex64"
5427   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5428         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5429                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5430    (clobber (reg:CC FLAGS_REG))]
5431   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5432 {
5433   switch (get_attr_type (insn))
5434     {
5435     case TYPE_LEA:
5436       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5437       return "lea{q}\t{%a2, %0|%0, %a2}";
5438
5439     case TYPE_INCDEC:
5440       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5441       if (operands[2] == const1_rtx)
5442         return "inc{q}\t%0";
5443       else
5444         {
5445           gcc_assert (operands[2] == constm1_rtx);
5446           return "dec{q}\t%0";
5447         }
5448
5449     default:
5450       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5451
5452       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5453          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5454       if (CONST_INT_P (operands[2])
5455           /* Avoid overflows.  */
5456           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5457           && (INTVAL (operands[2]) == 128
5458               || (INTVAL (operands[2]) < 0
5459                   && INTVAL (operands[2]) != -128)))
5460         {
5461           operands[2] = GEN_INT (-INTVAL (operands[2]));
5462           return "sub{q}\t{%2, %0|%0, %2}";
5463         }
5464       return "add{q}\t{%2, %0|%0, %2}";
5465     }
5466 }
5467   [(set (attr "type")
5468      (cond [(eq_attr "alternative" "2")
5469               (const_string "lea")
5470             ; Current assemblers are broken and do not allow @GOTOFF in
5471             ; ought but a memory context.
5472             (match_operand:DI 2 "pic_symbolic_operand" "")
5473               (const_string "lea")
5474             (match_operand:DI 2 "incdec_operand" "")
5475               (const_string "incdec")
5476            ]
5477            (const_string "alu")))
5478    (set_attr "mode" "DI")])
5479
5480 ;; Convert lea to the lea pattern to avoid flags dependency.
5481 (define_split
5482   [(set (match_operand:DI 0 "register_operand" "")
5483         (plus:DI (match_operand:DI 1 "register_operand" "")
5484                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5485    (clobber (reg:CC FLAGS_REG))]
5486   "TARGET_64BIT && reload_completed
5487    && true_regnum (operands[0]) != true_regnum (operands[1])"
5488   [(set (match_dup 0)
5489         (plus:DI (match_dup 1)
5490                  (match_dup 2)))]
5491   "")
5492
5493 (define_insn "*adddi_2_rex64"
5494   [(set (reg FLAGS_REG)
5495         (compare
5496           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5497                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5498           (const_int 0)))
5499    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5500         (plus:DI (match_dup 1) (match_dup 2)))]
5501   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5502    && ix86_binary_operator_ok (PLUS, DImode, operands)
5503    /* Current assemblers are broken and do not allow @GOTOFF in
5504       ought but a memory context.  */
5505    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5506 {
5507   switch (get_attr_type (insn))
5508     {
5509     case TYPE_INCDEC:
5510       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5511       if (operands[2] == const1_rtx)
5512         return "inc{q}\t%0";
5513       else
5514         {
5515           gcc_assert (operands[2] == constm1_rtx);
5516           return "dec{q}\t%0";
5517         }
5518
5519     default:
5520       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5521       /* ???? We ought to handle there the 32bit case too
5522          - do we need new constraint?  */
5523       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5524          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5525       if (CONST_INT_P (operands[2])
5526           /* Avoid overflows.  */
5527           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5528           && (INTVAL (operands[2]) == 128
5529               || (INTVAL (operands[2]) < 0
5530                   && INTVAL (operands[2]) != -128)))
5531         {
5532           operands[2] = GEN_INT (-INTVAL (operands[2]));
5533           return "sub{q}\t{%2, %0|%0, %2}";
5534         }
5535       return "add{q}\t{%2, %0|%0, %2}";
5536     }
5537 }
5538   [(set (attr "type")
5539      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5540         (const_string "incdec")
5541         (const_string "alu")))
5542    (set_attr "mode" "DI")])
5543
5544 (define_insn "*adddi_3_rex64"
5545   [(set (reg FLAGS_REG)
5546         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5547                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5548    (clobber (match_scratch:DI 0 "=r"))]
5549   "TARGET_64BIT
5550    && ix86_match_ccmode (insn, CCZmode)
5551    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5552    /* Current assemblers are broken and do not allow @GOTOFF in
5553       ought but a memory context.  */
5554    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5555 {
5556   switch (get_attr_type (insn))
5557     {
5558     case TYPE_INCDEC:
5559       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5560       if (operands[2] == const1_rtx)
5561         return "inc{q}\t%0";
5562       else
5563         {
5564           gcc_assert (operands[2] == constm1_rtx);
5565           return "dec{q}\t%0";
5566         }
5567
5568     default:
5569       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5570       /* ???? We ought to handle there the 32bit case too
5571          - do we need new constraint?  */
5572       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5573          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5574       if (CONST_INT_P (operands[2])
5575           /* Avoid overflows.  */
5576           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5577           && (INTVAL (operands[2]) == 128
5578               || (INTVAL (operands[2]) < 0
5579                   && INTVAL (operands[2]) != -128)))
5580         {
5581           operands[2] = GEN_INT (-INTVAL (operands[2]));
5582           return "sub{q}\t{%2, %0|%0, %2}";
5583         }
5584       return "add{q}\t{%2, %0|%0, %2}";
5585     }
5586 }
5587   [(set (attr "type")
5588      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5589         (const_string "incdec")
5590         (const_string "alu")))
5591    (set_attr "mode" "DI")])
5592
5593 ; For comparisons against 1, -1 and 128, we may generate better code
5594 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5595 ; is matched then.  We can't accept general immediate, because for
5596 ; case of overflows,  the result is messed up.
5597 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5598 ; when negated.
5599 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5600 ; only for comparisons not depending on it.
5601 (define_insn "*adddi_4_rex64"
5602   [(set (reg FLAGS_REG)
5603         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5604                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5605    (clobber (match_scratch:DI 0 "=rm"))]
5606   "TARGET_64BIT
5607    &&  ix86_match_ccmode (insn, CCGCmode)"
5608 {
5609   switch (get_attr_type (insn))
5610     {
5611     case TYPE_INCDEC:
5612       if (operands[2] == constm1_rtx)
5613         return "inc{q}\t%0";
5614       else
5615         {
5616           gcc_assert (operands[2] == const1_rtx);
5617           return "dec{q}\t%0";
5618         }
5619
5620     default:
5621       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5622       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5623          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5624       if ((INTVAL (operands[2]) == -128
5625            || (INTVAL (operands[2]) > 0
5626                && INTVAL (operands[2]) != 128))
5627           /* Avoid overflows.  */
5628           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5629         return "sub{q}\t{%2, %0|%0, %2}";
5630       operands[2] = GEN_INT (-INTVAL (operands[2]));
5631       return "add{q}\t{%2, %0|%0, %2}";
5632     }
5633 }
5634   [(set (attr "type")
5635      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5636         (const_string "incdec")
5637         (const_string "alu")))
5638    (set_attr "mode" "DI")])
5639
5640 (define_insn "*adddi_5_rex64"
5641   [(set (reg FLAGS_REG)
5642         (compare
5643           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5644                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5645           (const_int 0)))
5646    (clobber (match_scratch:DI 0 "=r"))]
5647   "TARGET_64BIT
5648    && ix86_match_ccmode (insn, CCGOCmode)
5649    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5650    /* Current assemblers are broken and do not allow @GOTOFF in
5651       ought but a memory context.  */
5652    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5653 {
5654   switch (get_attr_type (insn))
5655     {
5656     case TYPE_INCDEC:
5657       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5658       if (operands[2] == const1_rtx)
5659         return "inc{q}\t%0";
5660       else
5661         {
5662           gcc_assert (operands[2] == constm1_rtx);
5663           return "dec{q}\t%0";
5664         }
5665
5666     default:
5667       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5668       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5669          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5670       if (CONST_INT_P (operands[2])
5671           /* Avoid overflows.  */
5672           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5673           && (INTVAL (operands[2]) == 128
5674               || (INTVAL (operands[2]) < 0
5675                   && INTVAL (operands[2]) != -128)))
5676         {
5677           operands[2] = GEN_INT (-INTVAL (operands[2]));
5678           return "sub{q}\t{%2, %0|%0, %2}";
5679         }
5680       return "add{q}\t{%2, %0|%0, %2}";
5681     }
5682 }
5683   [(set (attr "type")
5684      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5685         (const_string "incdec")
5686         (const_string "alu")))
5687    (set_attr "mode" "DI")])
5688
5689
5690 (define_insn "*addsi_1"
5691   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5692         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5693                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5694    (clobber (reg:CC FLAGS_REG))]
5695   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5696 {
5697   switch (get_attr_type (insn))
5698     {
5699     case TYPE_LEA:
5700       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5701       return "lea{l}\t{%a2, %0|%0, %a2}";
5702
5703     case TYPE_INCDEC:
5704       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5705       if (operands[2] == const1_rtx)
5706         return "inc{l}\t%0";
5707       else
5708         {
5709           gcc_assert (operands[2] == constm1_rtx);
5710           return "dec{l}\t%0";
5711         }
5712
5713     default:
5714       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5715
5716       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5717          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5718       if (CONST_INT_P (operands[2])
5719           && (INTVAL (operands[2]) == 128
5720               || (INTVAL (operands[2]) < 0
5721                   && INTVAL (operands[2]) != -128)))
5722         {
5723           operands[2] = GEN_INT (-INTVAL (operands[2]));
5724           return "sub{l}\t{%2, %0|%0, %2}";
5725         }
5726       return "add{l}\t{%2, %0|%0, %2}";
5727     }
5728 }
5729   [(set (attr "type")
5730      (cond [(eq_attr "alternative" "2")
5731               (const_string "lea")
5732             ; Current assemblers are broken and do not allow @GOTOFF in
5733             ; ought but a memory context.
5734             (match_operand:SI 2 "pic_symbolic_operand" "")
5735               (const_string "lea")
5736             (match_operand:SI 2 "incdec_operand" "")
5737               (const_string "incdec")
5738            ]
5739            (const_string "alu")))
5740    (set_attr "mode" "SI")])
5741
5742 ;; Convert lea to the lea pattern to avoid flags dependency.
5743 (define_split
5744   [(set (match_operand 0 "register_operand" "")
5745         (plus (match_operand 1 "register_operand" "")
5746               (match_operand 2 "nonmemory_operand" "")))
5747    (clobber (reg:CC FLAGS_REG))]
5748   "reload_completed
5749    && true_regnum (operands[0]) != true_regnum (operands[1])"
5750   [(const_int 0)]
5751 {
5752   rtx pat;
5753   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5754      may confuse gen_lowpart.  */
5755   if (GET_MODE (operands[0]) != Pmode)
5756     {
5757       operands[1] = gen_lowpart (Pmode, operands[1]);
5758       operands[2] = gen_lowpart (Pmode, operands[2]);
5759     }
5760   operands[0] = gen_lowpart (SImode, operands[0]);
5761   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5762   if (Pmode != SImode)
5763     pat = gen_rtx_SUBREG (SImode, pat, 0);
5764   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5765   DONE;
5766 })
5767
5768 ;; It may seem that nonimmediate operand is proper one for operand 1.
5769 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5770 ;; we take care in ix86_binary_operator_ok to not allow two memory
5771 ;; operands so proper swapping will be done in reload.  This allow
5772 ;; patterns constructed from addsi_1 to match.
5773 (define_insn "addsi_1_zext"
5774   [(set (match_operand:DI 0 "register_operand" "=r,r")
5775         (zero_extend:DI
5776           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5777                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5778    (clobber (reg:CC FLAGS_REG))]
5779   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5780 {
5781   switch (get_attr_type (insn))
5782     {
5783     case TYPE_LEA:
5784       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5785       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5786
5787     case TYPE_INCDEC:
5788       if (operands[2] == const1_rtx)
5789         return "inc{l}\t%k0";
5790       else
5791         {
5792           gcc_assert (operands[2] == constm1_rtx);
5793           return "dec{l}\t%k0";
5794         }
5795
5796     default:
5797       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5798          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5799       if (CONST_INT_P (operands[2])
5800           && (INTVAL (operands[2]) == 128
5801               || (INTVAL (operands[2]) < 0
5802                   && INTVAL (operands[2]) != -128)))
5803         {
5804           operands[2] = GEN_INT (-INTVAL (operands[2]));
5805           return "sub{l}\t{%2, %k0|%k0, %2}";
5806         }
5807       return "add{l}\t{%2, %k0|%k0, %2}";
5808     }
5809 }
5810   [(set (attr "type")
5811      (cond [(eq_attr "alternative" "1")
5812               (const_string "lea")
5813             ; Current assemblers are broken and do not allow @GOTOFF in
5814             ; ought but a memory context.
5815             (match_operand:SI 2 "pic_symbolic_operand" "")
5816               (const_string "lea")
5817             (match_operand:SI 2 "incdec_operand" "")
5818               (const_string "incdec")
5819            ]
5820            (const_string "alu")))
5821    (set_attr "mode" "SI")])
5822
5823 ;; Convert lea to the lea pattern to avoid flags dependency.
5824 (define_split
5825   [(set (match_operand:DI 0 "register_operand" "")
5826         (zero_extend:DI
5827           (plus:SI (match_operand:SI 1 "register_operand" "")
5828                    (match_operand:SI 2 "nonmemory_operand" ""))))
5829    (clobber (reg:CC FLAGS_REG))]
5830   "TARGET_64BIT && reload_completed
5831    && true_regnum (operands[0]) != true_regnum (operands[1])"
5832   [(set (match_dup 0)
5833         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5834 {
5835   operands[1] = gen_lowpart (Pmode, operands[1]);
5836   operands[2] = gen_lowpart (Pmode, operands[2]);
5837 })
5838
5839 (define_insn "*addsi_2"
5840   [(set (reg FLAGS_REG)
5841         (compare
5842           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5843                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5844           (const_int 0)))
5845    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5846         (plus:SI (match_dup 1) (match_dup 2)))]
5847   "ix86_match_ccmode (insn, CCGOCmode)
5848    && ix86_binary_operator_ok (PLUS, SImode, operands)
5849    /* Current assemblers are broken and do not allow @GOTOFF in
5850       ought but a memory context.  */
5851    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5852 {
5853   switch (get_attr_type (insn))
5854     {
5855     case TYPE_INCDEC:
5856       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5857       if (operands[2] == const1_rtx)
5858         return "inc{l}\t%0";
5859       else
5860         {
5861           gcc_assert (operands[2] == constm1_rtx);
5862           return "dec{l}\t%0";
5863         }
5864
5865     default:
5866       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5867       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5868          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5869       if (CONST_INT_P (operands[2])
5870           && (INTVAL (operands[2]) == 128
5871               || (INTVAL (operands[2]) < 0
5872                   && INTVAL (operands[2]) != -128)))
5873         {
5874           operands[2] = GEN_INT (-INTVAL (operands[2]));
5875           return "sub{l}\t{%2, %0|%0, %2}";
5876         }
5877       return "add{l}\t{%2, %0|%0, %2}";
5878     }
5879 }
5880   [(set (attr "type")
5881      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5882         (const_string "incdec")
5883         (const_string "alu")))
5884    (set_attr "mode" "SI")])
5885
5886 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5887 (define_insn "*addsi_2_zext"
5888   [(set (reg FLAGS_REG)
5889         (compare
5890           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5891                    (match_operand:SI 2 "general_operand" "rmni"))
5892           (const_int 0)))
5893    (set (match_operand:DI 0 "register_operand" "=r")
5894         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5895   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5896    && ix86_binary_operator_ok (PLUS, SImode, operands)
5897    /* Current assemblers are broken and do not allow @GOTOFF in
5898       ought but a memory context.  */
5899    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5900 {
5901   switch (get_attr_type (insn))
5902     {
5903     case TYPE_INCDEC:
5904       if (operands[2] == const1_rtx)
5905         return "inc{l}\t%k0";
5906       else
5907         {
5908           gcc_assert (operands[2] == constm1_rtx);
5909           return "dec{l}\t%k0";
5910         }
5911
5912     default:
5913       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5914          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5915       if (CONST_INT_P (operands[2])
5916           && (INTVAL (operands[2]) == 128
5917               || (INTVAL (operands[2]) < 0
5918                   && INTVAL (operands[2]) != -128)))
5919         {
5920           operands[2] = GEN_INT (-INTVAL (operands[2]));
5921           return "sub{l}\t{%2, %k0|%k0, %2}";
5922         }
5923       return "add{l}\t{%2, %k0|%k0, %2}";
5924     }
5925 }
5926   [(set (attr "type")
5927      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5928         (const_string "incdec")
5929         (const_string "alu")))
5930    (set_attr "mode" "SI")])
5931
5932 (define_insn "*addsi_3"
5933   [(set (reg FLAGS_REG)
5934         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5935                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5936    (clobber (match_scratch:SI 0 "=r"))]
5937   "ix86_match_ccmode (insn, CCZmode)
5938    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5939    /* Current assemblers are broken and do not allow @GOTOFF in
5940       ought but a memory context.  */
5941    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5942 {
5943   switch (get_attr_type (insn))
5944     {
5945     case TYPE_INCDEC:
5946       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5947       if (operands[2] == const1_rtx)
5948         return "inc{l}\t%0";
5949       else
5950         {
5951           gcc_assert (operands[2] == constm1_rtx);
5952           return "dec{l}\t%0";
5953         }
5954
5955     default:
5956       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5957       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5958          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5959       if (CONST_INT_P (operands[2])
5960           && (INTVAL (operands[2]) == 128
5961               || (INTVAL (operands[2]) < 0
5962                   && INTVAL (operands[2]) != -128)))
5963         {
5964           operands[2] = GEN_INT (-INTVAL (operands[2]));
5965           return "sub{l}\t{%2, %0|%0, %2}";
5966         }
5967       return "add{l}\t{%2, %0|%0, %2}";
5968     }
5969 }
5970   [(set (attr "type")
5971      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5972         (const_string "incdec")
5973         (const_string "alu")))
5974    (set_attr "mode" "SI")])
5975
5976 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5977 (define_insn "*addsi_3_zext"
5978   [(set (reg FLAGS_REG)
5979         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5980                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5981    (set (match_operand:DI 0 "register_operand" "=r")
5982         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5983   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5984    && ix86_binary_operator_ok (PLUS, SImode, operands)
5985    /* Current assemblers are broken and do not allow @GOTOFF in
5986       ought but a memory context.  */
5987    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5988 {
5989   switch (get_attr_type (insn))
5990     {
5991     case TYPE_INCDEC:
5992       if (operands[2] == const1_rtx)
5993         return "inc{l}\t%k0";
5994       else
5995         {
5996           gcc_assert (operands[2] == constm1_rtx);
5997           return "dec{l}\t%k0";
5998         }
5999
6000     default:
6001       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6002          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6003       if (CONST_INT_P (operands[2])
6004           && (INTVAL (operands[2]) == 128
6005               || (INTVAL (operands[2]) < 0
6006                   && INTVAL (operands[2]) != -128)))
6007         {
6008           operands[2] = GEN_INT (-INTVAL (operands[2]));
6009           return "sub{l}\t{%2, %k0|%k0, %2}";
6010         }
6011       return "add{l}\t{%2, %k0|%k0, %2}";
6012     }
6013 }
6014   [(set (attr "type")
6015      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6016         (const_string "incdec")
6017         (const_string "alu")))
6018    (set_attr "mode" "SI")])
6019
6020 ; For comparisons against 1, -1 and 128, we may generate better code
6021 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6022 ; is matched then.  We can't accept general immediate, because for
6023 ; case of overflows,  the result is messed up.
6024 ; This pattern also don't hold of 0x80000000, since the value overflows
6025 ; when negated.
6026 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6027 ; only for comparisons not depending on it.
6028 (define_insn "*addsi_4"
6029   [(set (reg FLAGS_REG)
6030         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6031                  (match_operand:SI 2 "const_int_operand" "n")))
6032    (clobber (match_scratch:SI 0 "=rm"))]
6033   "ix86_match_ccmode (insn, CCGCmode)
6034    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6035 {
6036   switch (get_attr_type (insn))
6037     {
6038     case TYPE_INCDEC:
6039       if (operands[2] == constm1_rtx)
6040         return "inc{l}\t%0";
6041       else
6042         {
6043           gcc_assert (operands[2] == const1_rtx);
6044           return "dec{l}\t%0";
6045         }
6046
6047     default:
6048       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6049       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6050          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6051       if ((INTVAL (operands[2]) == -128
6052            || (INTVAL (operands[2]) > 0
6053                && INTVAL (operands[2]) != 128)))
6054         return "sub{l}\t{%2, %0|%0, %2}";
6055       operands[2] = GEN_INT (-INTVAL (operands[2]));
6056       return "add{l}\t{%2, %0|%0, %2}";
6057     }
6058 }
6059   [(set (attr "type")
6060      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6061         (const_string "incdec")
6062         (const_string "alu")))
6063    (set_attr "mode" "SI")])
6064
6065 (define_insn "*addsi_5"
6066   [(set (reg FLAGS_REG)
6067         (compare
6068           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6069                    (match_operand:SI 2 "general_operand" "rmni"))
6070           (const_int 0)))
6071    (clobber (match_scratch:SI 0 "=r"))]
6072   "ix86_match_ccmode (insn, CCGOCmode)
6073    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6074    /* Current assemblers are broken and do not allow @GOTOFF in
6075       ought but a memory context.  */
6076    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6077 {
6078   switch (get_attr_type (insn))
6079     {
6080     case TYPE_INCDEC:
6081       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6082       if (operands[2] == const1_rtx)
6083         return "inc{l}\t%0";
6084       else
6085         {
6086           gcc_assert (operands[2] == constm1_rtx);
6087           return "dec{l}\t%0";
6088         }
6089
6090     default:
6091       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6092       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6093          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6094       if (CONST_INT_P (operands[2])
6095           && (INTVAL (operands[2]) == 128
6096               || (INTVAL (operands[2]) < 0
6097                   && INTVAL (operands[2]) != -128)))
6098         {
6099           operands[2] = GEN_INT (-INTVAL (operands[2]));
6100           return "sub{l}\t{%2, %0|%0, %2}";
6101         }
6102       return "add{l}\t{%2, %0|%0, %2}";
6103     }
6104 }
6105   [(set (attr "type")
6106      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6107         (const_string "incdec")
6108         (const_string "alu")))
6109    (set_attr "mode" "SI")])
6110
6111 (define_expand "addhi3"
6112   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6113                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6114                             (match_operand:HI 2 "general_operand" "")))
6115               (clobber (reg:CC FLAGS_REG))])]
6116   "TARGET_HIMODE_MATH"
6117   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6118
6119 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6120 ;; type optimizations enabled by define-splits.  This is not important
6121 ;; for PII, and in fact harmful because of partial register stalls.
6122
6123 (define_insn "*addhi_1_lea"
6124   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6125         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6126                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6127    (clobber (reg:CC FLAGS_REG))]
6128   "!TARGET_PARTIAL_REG_STALL
6129    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6130 {
6131   switch (get_attr_type (insn))
6132     {
6133     case TYPE_LEA:
6134       return "#";
6135     case TYPE_INCDEC:
6136       if (operands[2] == const1_rtx)
6137         return "inc{w}\t%0";
6138       else
6139         {
6140           gcc_assert (operands[2] == constm1_rtx);
6141           return "dec{w}\t%0";
6142         }
6143
6144     default:
6145       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6146          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6147       if (CONST_INT_P (operands[2])
6148           && (INTVAL (operands[2]) == 128
6149               || (INTVAL (operands[2]) < 0
6150                   && INTVAL (operands[2]) != -128)))
6151         {
6152           operands[2] = GEN_INT (-INTVAL (operands[2]));
6153           return "sub{w}\t{%2, %0|%0, %2}";
6154         }
6155       return "add{w}\t{%2, %0|%0, %2}";
6156     }
6157 }
6158   [(set (attr "type")
6159      (if_then_else (eq_attr "alternative" "2")
6160         (const_string "lea")
6161         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6162            (const_string "incdec")
6163            (const_string "alu"))))
6164    (set_attr "mode" "HI,HI,SI")])
6165
6166 (define_insn "*addhi_1"
6167   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6168         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6169                  (match_operand:HI 2 "general_operand" "ri,rm")))
6170    (clobber (reg:CC FLAGS_REG))]
6171   "TARGET_PARTIAL_REG_STALL
6172    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6173 {
6174   switch (get_attr_type (insn))
6175     {
6176     case TYPE_INCDEC:
6177       if (operands[2] == const1_rtx)
6178         return "inc{w}\t%0";
6179       else
6180         {
6181           gcc_assert (operands[2] == constm1_rtx);
6182           return "dec{w}\t%0";
6183         }
6184
6185     default:
6186       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6187          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6188       if (CONST_INT_P (operands[2])
6189           && (INTVAL (operands[2]) == 128
6190               || (INTVAL (operands[2]) < 0
6191                   && INTVAL (operands[2]) != -128)))
6192         {
6193           operands[2] = GEN_INT (-INTVAL (operands[2]));
6194           return "sub{w}\t{%2, %0|%0, %2}";
6195         }
6196       return "add{w}\t{%2, %0|%0, %2}";
6197     }
6198 }
6199   [(set (attr "type")
6200      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6201         (const_string "incdec")
6202         (const_string "alu")))
6203    (set_attr "mode" "HI")])
6204
6205 (define_insn "*addhi_2"
6206   [(set (reg FLAGS_REG)
6207         (compare
6208           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6209                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6210           (const_int 0)))
6211    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6212         (plus:HI (match_dup 1) (match_dup 2)))]
6213   "ix86_match_ccmode (insn, CCGOCmode)
6214    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6215 {
6216   switch (get_attr_type (insn))
6217     {
6218     case TYPE_INCDEC:
6219       if (operands[2] == const1_rtx)
6220         return "inc{w}\t%0";
6221       else
6222         {
6223           gcc_assert (operands[2] == constm1_rtx);
6224           return "dec{w}\t%0";
6225         }
6226
6227     default:
6228       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6229          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6230       if (CONST_INT_P (operands[2])
6231           && (INTVAL (operands[2]) == 128
6232               || (INTVAL (operands[2]) < 0
6233                   && INTVAL (operands[2]) != -128)))
6234         {
6235           operands[2] = GEN_INT (-INTVAL (operands[2]));
6236           return "sub{w}\t{%2, %0|%0, %2}";
6237         }
6238       return "add{w}\t{%2, %0|%0, %2}";
6239     }
6240 }
6241   [(set (attr "type")
6242      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6243         (const_string "incdec")
6244         (const_string "alu")))
6245    (set_attr "mode" "HI")])
6246
6247 (define_insn "*addhi_3"
6248   [(set (reg FLAGS_REG)
6249         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6250                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6251    (clobber (match_scratch:HI 0 "=r"))]
6252   "ix86_match_ccmode (insn, CCZmode)
6253    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6254 {
6255   switch (get_attr_type (insn))
6256     {
6257     case TYPE_INCDEC:
6258       if (operands[2] == const1_rtx)
6259         return "inc{w}\t%0";
6260       else
6261         {
6262           gcc_assert (operands[2] == constm1_rtx);
6263           return "dec{w}\t%0";
6264         }
6265
6266     default:
6267       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6268          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6269       if (CONST_INT_P (operands[2])
6270           && (INTVAL (operands[2]) == 128
6271               || (INTVAL (operands[2]) < 0
6272                   && INTVAL (operands[2]) != -128)))
6273         {
6274           operands[2] = GEN_INT (-INTVAL (operands[2]));
6275           return "sub{w}\t{%2, %0|%0, %2}";
6276         }
6277       return "add{w}\t{%2, %0|%0, %2}";
6278     }
6279 }
6280   [(set (attr "type")
6281      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6282         (const_string "incdec")
6283         (const_string "alu")))
6284    (set_attr "mode" "HI")])
6285
6286 ; See comments above addsi_4 for details.
6287 (define_insn "*addhi_4"
6288   [(set (reg FLAGS_REG)
6289         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6290                  (match_operand:HI 2 "const_int_operand" "n")))
6291    (clobber (match_scratch:HI 0 "=rm"))]
6292   "ix86_match_ccmode (insn, CCGCmode)
6293    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6294 {
6295   switch (get_attr_type (insn))
6296     {
6297     case TYPE_INCDEC:
6298       if (operands[2] == constm1_rtx)
6299         return "inc{w}\t%0";
6300       else
6301         {
6302           gcc_assert (operands[2] == const1_rtx);
6303           return "dec{w}\t%0";
6304         }
6305
6306     default:
6307       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6308       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6309          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6310       if ((INTVAL (operands[2]) == -128
6311            || (INTVAL (operands[2]) > 0
6312                && INTVAL (operands[2]) != 128)))
6313         return "sub{w}\t{%2, %0|%0, %2}";
6314       operands[2] = GEN_INT (-INTVAL (operands[2]));
6315       return "add{w}\t{%2, %0|%0, %2}";
6316     }
6317 }
6318   [(set (attr "type")
6319      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6320         (const_string "incdec")
6321         (const_string "alu")))
6322    (set_attr "mode" "SI")])
6323
6324
6325 (define_insn "*addhi_5"
6326   [(set (reg FLAGS_REG)
6327         (compare
6328           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6329                    (match_operand:HI 2 "general_operand" "rmni"))
6330           (const_int 0)))
6331    (clobber (match_scratch:HI 0 "=r"))]
6332   "ix86_match_ccmode (insn, CCGOCmode)
6333    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6334 {
6335   switch (get_attr_type (insn))
6336     {
6337     case TYPE_INCDEC:
6338       if (operands[2] == const1_rtx)
6339         return "inc{w}\t%0";
6340       else
6341         {
6342           gcc_assert (operands[2] == constm1_rtx);
6343           return "dec{w}\t%0";
6344         }
6345
6346     default:
6347       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6348          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6349       if (CONST_INT_P (operands[2])
6350           && (INTVAL (operands[2]) == 128
6351               || (INTVAL (operands[2]) < 0
6352                   && INTVAL (operands[2]) != -128)))
6353         {
6354           operands[2] = GEN_INT (-INTVAL (operands[2]));
6355           return "sub{w}\t{%2, %0|%0, %2}";
6356         }
6357       return "add{w}\t{%2, %0|%0, %2}";
6358     }
6359 }
6360   [(set (attr "type")
6361      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6362         (const_string "incdec")
6363         (const_string "alu")))
6364    (set_attr "mode" "HI")])
6365
6366 (define_expand "addqi3"
6367   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6368                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6369                             (match_operand:QI 2 "general_operand" "")))
6370               (clobber (reg:CC FLAGS_REG))])]
6371   "TARGET_QIMODE_MATH"
6372   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6373
6374 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6375 (define_insn "*addqi_1_lea"
6376   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6377         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6378                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6379    (clobber (reg:CC FLAGS_REG))]
6380   "!TARGET_PARTIAL_REG_STALL
6381    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6382 {
6383   int widen = (which_alternative == 2);
6384   switch (get_attr_type (insn))
6385     {
6386     case TYPE_LEA:
6387       return "#";
6388     case TYPE_INCDEC:
6389       if (operands[2] == const1_rtx)
6390         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6391       else
6392         {
6393           gcc_assert (operands[2] == constm1_rtx);
6394           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6395         }
6396
6397     default:
6398       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6399          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6400       if (CONST_INT_P (operands[2])
6401           && (INTVAL (operands[2]) == 128
6402               || (INTVAL (operands[2]) < 0
6403                   && INTVAL (operands[2]) != -128)))
6404         {
6405           operands[2] = GEN_INT (-INTVAL (operands[2]));
6406           if (widen)
6407             return "sub{l}\t{%2, %k0|%k0, %2}";
6408           else
6409             return "sub{b}\t{%2, %0|%0, %2}";
6410         }
6411       if (widen)
6412         return "add{l}\t{%k2, %k0|%k0, %k2}";
6413       else
6414         return "add{b}\t{%2, %0|%0, %2}";
6415     }
6416 }
6417   [(set (attr "type")
6418      (if_then_else (eq_attr "alternative" "3")
6419         (const_string "lea")
6420         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6421            (const_string "incdec")
6422            (const_string "alu"))))
6423    (set_attr "mode" "QI,QI,SI,SI")])
6424
6425 (define_insn "*addqi_1"
6426   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6427         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6428                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6429    (clobber (reg:CC FLAGS_REG))]
6430   "TARGET_PARTIAL_REG_STALL
6431    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6432 {
6433   int widen = (which_alternative == 2);
6434   switch (get_attr_type (insn))
6435     {
6436     case TYPE_INCDEC:
6437       if (operands[2] == const1_rtx)
6438         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6439       else
6440         {
6441           gcc_assert (operands[2] == constm1_rtx);
6442           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6443         }
6444
6445     default:
6446       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6447          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6448       if (CONST_INT_P (operands[2])
6449           && (INTVAL (operands[2]) == 128
6450               || (INTVAL (operands[2]) < 0
6451                   && INTVAL (operands[2]) != -128)))
6452         {
6453           operands[2] = GEN_INT (-INTVAL (operands[2]));
6454           if (widen)
6455             return "sub{l}\t{%2, %k0|%k0, %2}";
6456           else
6457             return "sub{b}\t{%2, %0|%0, %2}";
6458         }
6459       if (widen)
6460         return "add{l}\t{%k2, %k0|%k0, %k2}";
6461       else
6462         return "add{b}\t{%2, %0|%0, %2}";
6463     }
6464 }
6465   [(set (attr "type")
6466      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6467         (const_string "incdec")
6468         (const_string "alu")))
6469    (set_attr "mode" "QI,QI,SI")])
6470
6471 (define_insn "*addqi_1_slp"
6472   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6473         (plus:QI (match_dup 0)
6474                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6475    (clobber (reg:CC FLAGS_REG))]
6476   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6477    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6478 {
6479   switch (get_attr_type (insn))
6480     {
6481     case TYPE_INCDEC:
6482       if (operands[1] == const1_rtx)
6483         return "inc{b}\t%0";
6484       else
6485         {
6486           gcc_assert (operands[1] == constm1_rtx);
6487           return "dec{b}\t%0";
6488         }
6489
6490     default:
6491       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6492       if (CONST_INT_P (operands[1])
6493           && INTVAL (operands[1]) < 0)
6494         {
6495           operands[1] = GEN_INT (-INTVAL (operands[1]));
6496           return "sub{b}\t{%1, %0|%0, %1}";
6497         }
6498       return "add{b}\t{%1, %0|%0, %1}";
6499     }
6500 }
6501   [(set (attr "type")
6502      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6503         (const_string "incdec")
6504         (const_string "alu1")))
6505    (set (attr "memory")
6506      (if_then_else (match_operand 1 "memory_operand" "")
6507         (const_string "load")
6508         (const_string "none")))
6509    (set_attr "mode" "QI")])
6510
6511 (define_insn "*addqi_2"
6512   [(set (reg FLAGS_REG)
6513         (compare
6514           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6515                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6516           (const_int 0)))
6517    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6518         (plus:QI (match_dup 1) (match_dup 2)))]
6519   "ix86_match_ccmode (insn, CCGOCmode)
6520    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6521 {
6522   switch (get_attr_type (insn))
6523     {
6524     case TYPE_INCDEC:
6525       if (operands[2] == const1_rtx)
6526         return "inc{b}\t%0";
6527       else
6528         {
6529           gcc_assert (operands[2] == constm1_rtx
6530                       || (CONST_INT_P (operands[2])
6531                           && INTVAL (operands[2]) == 255));
6532           return "dec{b}\t%0";
6533         }
6534
6535     default:
6536       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6537       if (CONST_INT_P (operands[2])
6538           && INTVAL (operands[2]) < 0)
6539         {
6540           operands[2] = GEN_INT (-INTVAL (operands[2]));
6541           return "sub{b}\t{%2, %0|%0, %2}";
6542         }
6543       return "add{b}\t{%2, %0|%0, %2}";
6544     }
6545 }
6546   [(set (attr "type")
6547      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6548         (const_string "incdec")
6549         (const_string "alu")))
6550    (set_attr "mode" "QI")])
6551
6552 (define_insn "*addqi_3"
6553   [(set (reg FLAGS_REG)
6554         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6555                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6556    (clobber (match_scratch:QI 0 "=q"))]
6557   "ix86_match_ccmode (insn, CCZmode)
6558    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6559 {
6560   switch (get_attr_type (insn))
6561     {
6562     case TYPE_INCDEC:
6563       if (operands[2] == const1_rtx)
6564         return "inc{b}\t%0";
6565       else
6566         {
6567           gcc_assert (operands[2] == constm1_rtx
6568                       || (CONST_INT_P (operands[2])
6569                           && INTVAL (operands[2]) == 255));
6570           return "dec{b}\t%0";
6571         }
6572
6573     default:
6574       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6575       if (CONST_INT_P (operands[2])
6576           && INTVAL (operands[2]) < 0)
6577         {
6578           operands[2] = GEN_INT (-INTVAL (operands[2]));
6579           return "sub{b}\t{%2, %0|%0, %2}";
6580         }
6581       return "add{b}\t{%2, %0|%0, %2}";
6582     }
6583 }
6584   [(set (attr "type")
6585      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6586         (const_string "incdec")
6587         (const_string "alu")))
6588    (set_attr "mode" "QI")])
6589
6590 ; See comments above addsi_4 for details.
6591 (define_insn "*addqi_4"
6592   [(set (reg FLAGS_REG)
6593         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6594                  (match_operand:QI 2 "const_int_operand" "n")))
6595    (clobber (match_scratch:QI 0 "=qm"))]
6596   "ix86_match_ccmode (insn, CCGCmode)
6597    && (INTVAL (operands[2]) & 0xff) != 0x80"
6598 {
6599   switch (get_attr_type (insn))
6600     {
6601     case TYPE_INCDEC:
6602       if (operands[2] == constm1_rtx
6603           || (CONST_INT_P (operands[2])
6604               && INTVAL (operands[2]) == 255))
6605         return "inc{b}\t%0";
6606       else
6607         {
6608           gcc_assert (operands[2] == const1_rtx);
6609           return "dec{b}\t%0";
6610         }
6611
6612     default:
6613       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6614       if (INTVAL (operands[2]) < 0)
6615         {
6616           operands[2] = GEN_INT (-INTVAL (operands[2]));
6617           return "add{b}\t{%2, %0|%0, %2}";
6618         }
6619       return "sub{b}\t{%2, %0|%0, %2}";
6620     }
6621 }
6622   [(set (attr "type")
6623      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6624         (const_string "incdec")
6625         (const_string "alu")))
6626    (set_attr "mode" "QI")])
6627
6628
6629 (define_insn "*addqi_5"
6630   [(set (reg FLAGS_REG)
6631         (compare
6632           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6633                    (match_operand:QI 2 "general_operand" "qmni"))
6634           (const_int 0)))
6635    (clobber (match_scratch:QI 0 "=q"))]
6636   "ix86_match_ccmode (insn, CCGOCmode)
6637    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6638 {
6639   switch (get_attr_type (insn))
6640     {
6641     case TYPE_INCDEC:
6642       if (operands[2] == const1_rtx)
6643         return "inc{b}\t%0";
6644       else
6645         {
6646           gcc_assert (operands[2] == constm1_rtx
6647                       || (CONST_INT_P (operands[2])
6648                           && INTVAL (operands[2]) == 255));
6649           return "dec{b}\t%0";
6650         }
6651
6652     default:
6653       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6654       if (CONST_INT_P (operands[2])
6655           && INTVAL (operands[2]) < 0)
6656         {
6657           operands[2] = GEN_INT (-INTVAL (operands[2]));
6658           return "sub{b}\t{%2, %0|%0, %2}";
6659         }
6660       return "add{b}\t{%2, %0|%0, %2}";
6661     }
6662 }
6663   [(set (attr "type")
6664      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6665         (const_string "incdec")
6666         (const_string "alu")))
6667    (set_attr "mode" "QI")])
6668
6669
6670 (define_insn "addqi_ext_1"
6671   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6672                          (const_int 8)
6673                          (const_int 8))
6674         (plus:SI
6675           (zero_extract:SI
6676             (match_operand 1 "ext_register_operand" "0")
6677             (const_int 8)
6678             (const_int 8))
6679           (match_operand:QI 2 "general_operand" "Qmn")))
6680    (clobber (reg:CC FLAGS_REG))]
6681   "!TARGET_64BIT"
6682 {
6683   switch (get_attr_type (insn))
6684     {
6685     case TYPE_INCDEC:
6686       if (operands[2] == const1_rtx)
6687         return "inc{b}\t%h0";
6688       else
6689         {
6690           gcc_assert (operands[2] == constm1_rtx
6691                       || (CONST_INT_P (operands[2])
6692                           && INTVAL (operands[2]) == 255));
6693           return "dec{b}\t%h0";
6694         }
6695
6696     default:
6697       return "add{b}\t{%2, %h0|%h0, %2}";
6698     }
6699 }
6700   [(set (attr "type")
6701      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6702         (const_string "incdec")
6703         (const_string "alu")))
6704    (set_attr "mode" "QI")])
6705
6706 (define_insn "*addqi_ext_1_rex64"
6707   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6708                          (const_int 8)
6709                          (const_int 8))
6710         (plus:SI
6711           (zero_extract:SI
6712             (match_operand 1 "ext_register_operand" "0")
6713             (const_int 8)
6714             (const_int 8))
6715           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6716    (clobber (reg:CC FLAGS_REG))]
6717   "TARGET_64BIT"
6718 {
6719   switch (get_attr_type (insn))
6720     {
6721     case TYPE_INCDEC:
6722       if (operands[2] == const1_rtx)
6723         return "inc{b}\t%h0";
6724       else
6725         {
6726           gcc_assert (operands[2] == constm1_rtx
6727                       || (CONST_INT_P (operands[2])
6728                           && INTVAL (operands[2]) == 255));
6729           return "dec{b}\t%h0";
6730         }
6731
6732     default:
6733       return "add{b}\t{%2, %h0|%h0, %2}";
6734     }
6735 }
6736   [(set (attr "type")
6737      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6738         (const_string "incdec")
6739         (const_string "alu")))
6740    (set_attr "mode" "QI")])
6741
6742 (define_insn "*addqi_ext_2"
6743   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6744                          (const_int 8)
6745                          (const_int 8))
6746         (plus:SI
6747           (zero_extract:SI
6748             (match_operand 1 "ext_register_operand" "%0")
6749             (const_int 8)
6750             (const_int 8))
6751           (zero_extract:SI
6752             (match_operand 2 "ext_register_operand" "Q")
6753             (const_int 8)
6754             (const_int 8))))
6755    (clobber (reg:CC FLAGS_REG))]
6756   ""
6757   "add{b}\t{%h2, %h0|%h0, %h2}"
6758   [(set_attr "type" "alu")
6759    (set_attr "mode" "QI")])
6760
6761 ;; The patterns that match these are at the end of this file.
6762
6763 (define_expand "addxf3"
6764   [(set (match_operand:XF 0 "register_operand" "")
6765         (plus:XF (match_operand:XF 1 "register_operand" "")
6766                  (match_operand:XF 2 "register_operand" "")))]
6767   "TARGET_80387"
6768   "")
6769
6770 (define_expand "adddf3"
6771   [(set (match_operand:DF 0 "register_operand" "")
6772         (plus:DF (match_operand:DF 1 "register_operand" "")
6773                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6774   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6775   "")
6776
6777 (define_expand "addsf3"
6778   [(set (match_operand:SF 0 "register_operand" "")
6779         (plus:SF (match_operand:SF 1 "register_operand" "")
6780                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6781   "TARGET_80387 || TARGET_SSE_MATH"
6782   "")
6783 \f
6784 ;; Subtract instructions
6785
6786 ;; %%% splits for subditi3
6787
6788 (define_expand "subti3"
6789   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6790                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6791                              (match_operand:TI 2 "x86_64_general_operand" "")))
6792               (clobber (reg:CC FLAGS_REG))])]
6793   "TARGET_64BIT"
6794   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6795
6796 (define_insn "*subti3_1"
6797   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6798         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6799                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6800    (clobber (reg:CC FLAGS_REG))]
6801   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6802   "#")
6803
6804 (define_split
6805   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6806         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6807                   (match_operand:TI 2 "general_operand" "")))
6808    (clobber (reg:CC FLAGS_REG))]
6809   "TARGET_64BIT && reload_completed"
6810   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6811               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6812    (parallel [(set (match_dup 3)
6813                    (minus:DI (match_dup 4)
6814                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6815                                       (match_dup 5))))
6816               (clobber (reg:CC FLAGS_REG))])]
6817   "split_ti (operands+0, 1, operands+0, operands+3);
6818    split_ti (operands+1, 1, operands+1, operands+4);
6819    split_ti (operands+2, 1, operands+2, operands+5);")
6820
6821 ;; %%% splits for subsidi3
6822
6823 (define_expand "subdi3"
6824   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6825                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6826                              (match_operand:DI 2 "x86_64_general_operand" "")))
6827               (clobber (reg:CC FLAGS_REG))])]
6828   ""
6829   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6830
6831 (define_insn "*subdi3_1"
6832   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6833         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6834                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6835    (clobber (reg:CC FLAGS_REG))]
6836   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6837   "#")
6838
6839 (define_split
6840   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6841         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6842                   (match_operand:DI 2 "general_operand" "")))
6843    (clobber (reg:CC FLAGS_REG))]
6844   "!TARGET_64BIT && reload_completed"
6845   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6846               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6847    (parallel [(set (match_dup 3)
6848                    (minus:SI (match_dup 4)
6849                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6850                                       (match_dup 5))))
6851               (clobber (reg:CC FLAGS_REG))])]
6852   "split_di (operands+0, 1, operands+0, operands+3);
6853    split_di (operands+1, 1, operands+1, operands+4);
6854    split_di (operands+2, 1, operands+2, operands+5);")
6855
6856 (define_insn "subdi3_carry_rex64"
6857   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6858           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6859             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6860                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6861    (clobber (reg:CC FLAGS_REG))]
6862   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6863   "sbb{q}\t{%2, %0|%0, %2}"
6864   [(set_attr "type" "alu")
6865    (set_attr "pent_pair" "pu")
6866    (set_attr "mode" "DI")])
6867
6868 (define_insn "*subdi_1_rex64"
6869   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6870         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6871                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6872    (clobber (reg:CC FLAGS_REG))]
6873   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6874   "sub{q}\t{%2, %0|%0, %2}"
6875   [(set_attr "type" "alu")
6876    (set_attr "mode" "DI")])
6877
6878 (define_insn "*subdi_2_rex64"
6879   [(set (reg FLAGS_REG)
6880         (compare
6881           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6882                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6883           (const_int 0)))
6884    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6885         (minus:DI (match_dup 1) (match_dup 2)))]
6886   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6887    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6888   "sub{q}\t{%2, %0|%0, %2}"
6889   [(set_attr "type" "alu")
6890    (set_attr "mode" "DI")])
6891
6892 (define_insn "*subdi_3_rex63"
6893   [(set (reg FLAGS_REG)
6894         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6895                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6896    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6897         (minus:DI (match_dup 1) (match_dup 2)))]
6898   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6899    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6900   "sub{q}\t{%2, %0|%0, %2}"
6901   [(set_attr "type" "alu")
6902    (set_attr "mode" "DI")])
6903
6904 (define_insn "subqi3_carry"
6905   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6906           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6907             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6908                (match_operand:QI 2 "general_operand" "qi,qm"))))
6909    (clobber (reg:CC FLAGS_REG))]
6910   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6911   "sbb{b}\t{%2, %0|%0, %2}"
6912   [(set_attr "type" "alu")
6913    (set_attr "pent_pair" "pu")
6914    (set_attr "mode" "QI")])
6915
6916 (define_insn "subhi3_carry"
6917   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6918           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6919             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6920                (match_operand:HI 2 "general_operand" "ri,rm"))))
6921    (clobber (reg:CC FLAGS_REG))]
6922   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6923   "sbb{w}\t{%2, %0|%0, %2}"
6924   [(set_attr "type" "alu")
6925    (set_attr "pent_pair" "pu")
6926    (set_attr "mode" "HI")])
6927
6928 (define_insn "subsi3_carry"
6929   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6930           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6931             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6932                (match_operand:SI 2 "general_operand" "ri,rm"))))
6933    (clobber (reg:CC FLAGS_REG))]
6934   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6935   "sbb{l}\t{%2, %0|%0, %2}"
6936   [(set_attr "type" "alu")
6937    (set_attr "pent_pair" "pu")
6938    (set_attr "mode" "SI")])
6939
6940 (define_insn "subsi3_carry_zext"
6941   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6942           (zero_extend:DI
6943             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6944               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6945                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6946    (clobber (reg:CC FLAGS_REG))]
6947   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6948   "sbb{l}\t{%2, %k0|%k0, %2}"
6949   [(set_attr "type" "alu")
6950    (set_attr "pent_pair" "pu")
6951    (set_attr "mode" "SI")])
6952
6953 (define_expand "subsi3"
6954   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6955                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6956                              (match_operand:SI 2 "general_operand" "")))
6957               (clobber (reg:CC FLAGS_REG))])]
6958   ""
6959   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6960
6961 (define_insn "*subsi_1"
6962   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6963         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6964                   (match_operand:SI 2 "general_operand" "ri,rm")))
6965    (clobber (reg:CC FLAGS_REG))]
6966   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6967   "sub{l}\t{%2, %0|%0, %2}"
6968   [(set_attr "type" "alu")
6969    (set_attr "mode" "SI")])
6970
6971 (define_insn "*subsi_1_zext"
6972   [(set (match_operand:DI 0 "register_operand" "=r")
6973         (zero_extend:DI
6974           (minus:SI (match_operand:SI 1 "register_operand" "0")
6975                     (match_operand:SI 2 "general_operand" "rim"))))
6976    (clobber (reg:CC FLAGS_REG))]
6977   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6978   "sub{l}\t{%2, %k0|%k0, %2}"
6979   [(set_attr "type" "alu")
6980    (set_attr "mode" "SI")])
6981
6982 (define_insn "*subsi_2"
6983   [(set (reg FLAGS_REG)
6984         (compare
6985           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6986                     (match_operand:SI 2 "general_operand" "ri,rm"))
6987           (const_int 0)))
6988    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6989         (minus:SI (match_dup 1) (match_dup 2)))]
6990   "ix86_match_ccmode (insn, CCGOCmode)
6991    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6992   "sub{l}\t{%2, %0|%0, %2}"
6993   [(set_attr "type" "alu")
6994    (set_attr "mode" "SI")])
6995
6996 (define_insn "*subsi_2_zext"
6997   [(set (reg FLAGS_REG)
6998         (compare
6999           (minus:SI (match_operand:SI 1 "register_operand" "0")
7000                     (match_operand:SI 2 "general_operand" "rim"))
7001           (const_int 0)))
7002    (set (match_operand:DI 0 "register_operand" "=r")
7003         (zero_extend:DI
7004           (minus:SI (match_dup 1)
7005                     (match_dup 2))))]
7006   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7007    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7008   "sub{l}\t{%2, %k0|%k0, %2}"
7009   [(set_attr "type" "alu")
7010    (set_attr "mode" "SI")])
7011
7012 (define_insn "*subsi_3"
7013   [(set (reg FLAGS_REG)
7014         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7015                  (match_operand:SI 2 "general_operand" "ri,rm")))
7016    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7017         (minus:SI (match_dup 1) (match_dup 2)))]
7018   "ix86_match_ccmode (insn, CCmode)
7019    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7020   "sub{l}\t{%2, %0|%0, %2}"
7021   [(set_attr "type" "alu")
7022    (set_attr "mode" "SI")])
7023
7024 (define_insn "*subsi_3_zext"
7025   [(set (reg FLAGS_REG)
7026         (compare (match_operand:SI 1 "register_operand" "0")
7027                  (match_operand:SI 2 "general_operand" "rim")))
7028    (set (match_operand:DI 0 "register_operand" "=r")
7029         (zero_extend:DI
7030           (minus:SI (match_dup 1)
7031                     (match_dup 2))))]
7032   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7033    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7034   "sub{l}\t{%2, %1|%1, %2}"
7035   [(set_attr "type" "alu")
7036    (set_attr "mode" "DI")])
7037
7038 (define_expand "subhi3"
7039   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7040                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7041                              (match_operand:HI 2 "general_operand" "")))
7042               (clobber (reg:CC FLAGS_REG))])]
7043   "TARGET_HIMODE_MATH"
7044   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7045
7046 (define_insn "*subhi_1"
7047   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7048         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7049                   (match_operand:HI 2 "general_operand" "ri,rm")))
7050    (clobber (reg:CC FLAGS_REG))]
7051   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7052   "sub{w}\t{%2, %0|%0, %2}"
7053   [(set_attr "type" "alu")
7054    (set_attr "mode" "HI")])
7055
7056 (define_insn "*subhi_2"
7057   [(set (reg FLAGS_REG)
7058         (compare
7059           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7060                     (match_operand:HI 2 "general_operand" "ri,rm"))
7061           (const_int 0)))
7062    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7063         (minus:HI (match_dup 1) (match_dup 2)))]
7064   "ix86_match_ccmode (insn, CCGOCmode)
7065    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7066   "sub{w}\t{%2, %0|%0, %2}"
7067   [(set_attr "type" "alu")
7068    (set_attr "mode" "HI")])
7069
7070 (define_insn "*subhi_3"
7071   [(set (reg FLAGS_REG)
7072         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7073                  (match_operand:HI 2 "general_operand" "ri,rm")))
7074    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7075         (minus:HI (match_dup 1) (match_dup 2)))]
7076   "ix86_match_ccmode (insn, CCmode)
7077    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7078   "sub{w}\t{%2, %0|%0, %2}"
7079   [(set_attr "type" "alu")
7080    (set_attr "mode" "HI")])
7081
7082 (define_expand "subqi3"
7083   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7084                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7085                              (match_operand:QI 2 "general_operand" "")))
7086               (clobber (reg:CC FLAGS_REG))])]
7087   "TARGET_QIMODE_MATH"
7088   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7089
7090 (define_insn "*subqi_1"
7091   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7092         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7093                   (match_operand:QI 2 "general_operand" "qn,qmn")))
7094    (clobber (reg:CC FLAGS_REG))]
7095   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7096   "sub{b}\t{%2, %0|%0, %2}"
7097   [(set_attr "type" "alu")
7098    (set_attr "mode" "QI")])
7099
7100 (define_insn "*subqi_1_slp"
7101   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7102         (minus:QI (match_dup 0)
7103                   (match_operand:QI 1 "general_operand" "qn,qmn")))
7104    (clobber (reg:CC FLAGS_REG))]
7105   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7106    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7107   "sub{b}\t{%1, %0|%0, %1}"
7108   [(set_attr "type" "alu1")
7109    (set_attr "mode" "QI")])
7110
7111 (define_insn "*subqi_2"
7112   [(set (reg FLAGS_REG)
7113         (compare
7114           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7115                     (match_operand:QI 2 "general_operand" "qi,qm"))
7116           (const_int 0)))
7117    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7118         (minus:HI (match_dup 1) (match_dup 2)))]
7119   "ix86_match_ccmode (insn, CCGOCmode)
7120    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7121   "sub{b}\t{%2, %0|%0, %2}"
7122   [(set_attr "type" "alu")
7123    (set_attr "mode" "QI")])
7124
7125 (define_insn "*subqi_3"
7126   [(set (reg FLAGS_REG)
7127         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7128                  (match_operand:QI 2 "general_operand" "qi,qm")))
7129    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7130         (minus:HI (match_dup 1) (match_dup 2)))]
7131   "ix86_match_ccmode (insn, CCmode)
7132    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7133   "sub{b}\t{%2, %0|%0, %2}"
7134   [(set_attr "type" "alu")
7135    (set_attr "mode" "QI")])
7136
7137 ;; The patterns that match these are at the end of this file.
7138
7139 (define_expand "subxf3"
7140   [(set (match_operand:XF 0 "register_operand" "")
7141         (minus:XF (match_operand:XF 1 "register_operand" "")
7142                   (match_operand:XF 2 "register_operand" "")))]
7143   "TARGET_80387"
7144   "")
7145
7146 (define_expand "subdf3"
7147   [(set (match_operand:DF 0 "register_operand" "")
7148         (minus:DF (match_operand:DF 1 "register_operand" "")
7149                   (match_operand:DF 2 "nonimmediate_operand" "")))]
7150   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7151   "")
7152
7153 (define_expand "subsf3"
7154   [(set (match_operand:SF 0 "register_operand" "")
7155         (minus:SF (match_operand:SF 1 "register_operand" "")
7156                   (match_operand:SF 2 "nonimmediate_operand" "")))]
7157   "TARGET_80387 || TARGET_SSE_MATH"
7158   "")
7159 \f
7160 ;; Multiply instructions
7161
7162 (define_expand "muldi3"
7163   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7164                    (mult:DI (match_operand:DI 1 "register_operand" "")
7165                             (match_operand:DI 2 "x86_64_general_operand" "")))
7166               (clobber (reg:CC FLAGS_REG))])]
7167   "TARGET_64BIT"
7168   "")
7169
7170 ;; On AMDFAM10 
7171 ;; IMUL reg64, reg64, imm8      Direct
7172 ;; IMUL reg64, mem64, imm8      VectorPath
7173 ;; IMUL reg64, reg64, imm32     Direct
7174 ;; IMUL reg64, mem64, imm32     VectorPath 
7175 ;; IMUL reg64, reg64            Direct
7176 ;; IMUL reg64, mem64            Direct
7177
7178 (define_insn "*muldi3_1_rex64"
7179   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7180         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7181                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7182    (clobber (reg:CC FLAGS_REG))]
7183   "TARGET_64BIT
7184    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7185   "@
7186    imul{q}\t{%2, %1, %0|%0, %1, %2}
7187    imul{q}\t{%2, %1, %0|%0, %1, %2}
7188    imul{q}\t{%2, %0|%0, %2}"
7189   [(set_attr "type" "imul")
7190    (set_attr "prefix_0f" "0,0,1")
7191    (set (attr "athlon_decode")
7192         (cond [(eq_attr "cpu" "athlon")
7193                   (const_string "vector")
7194                (eq_attr "alternative" "1")
7195                   (const_string "vector")
7196                (and (eq_attr "alternative" "2")
7197                     (match_operand 1 "memory_operand" ""))
7198                   (const_string "vector")]
7199               (const_string "direct")))
7200    (set (attr "amdfam10_decode")
7201         (cond [(and (eq_attr "alternative" "0,1")
7202                     (match_operand 1 "memory_operand" ""))
7203                   (const_string "vector")]
7204               (const_string "direct")))       
7205    (set_attr "mode" "DI")])
7206
7207 (define_expand "mulsi3"
7208   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7209                    (mult:SI (match_operand:SI 1 "register_operand" "")
7210                             (match_operand:SI 2 "general_operand" "")))
7211               (clobber (reg:CC FLAGS_REG))])]
7212   ""
7213   "")
7214
7215 ;; On AMDFAM10 
7216 ;; IMUL reg32, reg32, imm8      Direct
7217 ;; IMUL reg32, mem32, imm8      VectorPath
7218 ;; IMUL reg32, reg32, imm32     Direct
7219 ;; IMUL reg32, mem32, imm32     VectorPath
7220 ;; IMUL reg32, reg32            Direct
7221 ;; IMUL reg32, mem32            Direct
7222
7223 (define_insn "*mulsi3_1"
7224   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7225         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7226                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7227    (clobber (reg:CC FLAGS_REG))]
7228   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7229   "@
7230    imul{l}\t{%2, %1, %0|%0, %1, %2}
7231    imul{l}\t{%2, %1, %0|%0, %1, %2}
7232    imul{l}\t{%2, %0|%0, %2}"
7233   [(set_attr "type" "imul")
7234    (set_attr "prefix_0f" "0,0,1")
7235    (set (attr "athlon_decode")
7236         (cond [(eq_attr "cpu" "athlon")
7237                   (const_string "vector")
7238                (eq_attr "alternative" "1")
7239                   (const_string "vector")
7240                (and (eq_attr "alternative" "2")
7241                     (match_operand 1 "memory_operand" ""))
7242                   (const_string "vector")]
7243               (const_string "direct")))
7244    (set (attr "amdfam10_decode")
7245         (cond [(and (eq_attr "alternative" "0,1")
7246                     (match_operand 1 "memory_operand" ""))
7247                   (const_string "vector")]
7248               (const_string "direct")))       
7249    (set_attr "mode" "SI")])
7250
7251 (define_insn "*mulsi3_1_zext"
7252   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7253         (zero_extend:DI
7254           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7255                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7256    (clobber (reg:CC FLAGS_REG))]
7257   "TARGET_64BIT
7258    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7259   "@
7260    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7261    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7262    imul{l}\t{%2, %k0|%k0, %2}"
7263   [(set_attr "type" "imul")
7264    (set_attr "prefix_0f" "0,0,1")
7265    (set (attr "athlon_decode")
7266         (cond [(eq_attr "cpu" "athlon")
7267                   (const_string "vector")
7268                (eq_attr "alternative" "1")
7269                   (const_string "vector")
7270                (and (eq_attr "alternative" "2")
7271                     (match_operand 1 "memory_operand" ""))
7272                   (const_string "vector")]
7273               (const_string "direct")))
7274    (set (attr "amdfam10_decode")
7275         (cond [(and (eq_attr "alternative" "0,1")
7276                     (match_operand 1 "memory_operand" ""))
7277                   (const_string "vector")]
7278               (const_string "direct")))       
7279    (set_attr "mode" "SI")])
7280
7281 (define_expand "mulhi3"
7282   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7283                    (mult:HI (match_operand:HI 1 "register_operand" "")
7284                             (match_operand:HI 2 "general_operand" "")))
7285               (clobber (reg:CC FLAGS_REG))])]
7286   "TARGET_HIMODE_MATH"
7287   "")
7288
7289 ;; On AMDFAM10
7290 ;; IMUL reg16, reg16, imm8      VectorPath
7291 ;; IMUL reg16, mem16, imm8      VectorPath
7292 ;; IMUL reg16, reg16, imm16     VectorPath
7293 ;; IMUL reg16, mem16, imm16     VectorPath
7294 ;; IMUL reg16, reg16            Direct
7295 ;; IMUL reg16, mem16            Direct
7296 (define_insn "*mulhi3_1"
7297   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7298         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7299                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7300    (clobber (reg:CC FLAGS_REG))]
7301   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7302   "@
7303    imul{w}\t{%2, %1, %0|%0, %1, %2}
7304    imul{w}\t{%2, %1, %0|%0, %1, %2}
7305    imul{w}\t{%2, %0|%0, %2}"
7306   [(set_attr "type" "imul")
7307    (set_attr "prefix_0f" "0,0,1")
7308    (set (attr "athlon_decode")
7309         (cond [(eq_attr "cpu" "athlon")
7310                   (const_string "vector")
7311                (eq_attr "alternative" "1,2")
7312                   (const_string "vector")]
7313               (const_string "direct")))
7314    (set (attr "amdfam10_decode")
7315         (cond [(eq_attr "alternative" "0,1")
7316                   (const_string "vector")]
7317               (const_string "direct")))
7318    (set_attr "mode" "HI")])
7319
7320 (define_expand "mulqi3"
7321   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7322                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7323                             (match_operand:QI 2 "register_operand" "")))
7324               (clobber (reg:CC FLAGS_REG))])]
7325   "TARGET_QIMODE_MATH"
7326   "")
7327
7328 ;;On AMDFAM10
7329 ;; MUL reg8     Direct
7330 ;; MUL mem8     Direct
7331
7332 (define_insn "*mulqi3_1"
7333   [(set (match_operand:QI 0 "register_operand" "=a")
7334         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7335                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7336    (clobber (reg:CC FLAGS_REG))]
7337   "TARGET_QIMODE_MATH
7338    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7339   "mul{b}\t%2"
7340   [(set_attr "type" "imul")
7341    (set_attr "length_immediate" "0")
7342    (set (attr "athlon_decode")
7343      (if_then_else (eq_attr "cpu" "athlon")
7344         (const_string "vector")
7345         (const_string "direct")))
7346    (set_attr "amdfam10_decode" "direct")        
7347    (set_attr "mode" "QI")])
7348
7349 (define_expand "umulqihi3"
7350   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7351                    (mult:HI (zero_extend:HI
7352                               (match_operand:QI 1 "nonimmediate_operand" ""))
7353                             (zero_extend:HI
7354                               (match_operand:QI 2 "register_operand" ""))))
7355               (clobber (reg:CC FLAGS_REG))])]
7356   "TARGET_QIMODE_MATH"
7357   "")
7358
7359 (define_insn "*umulqihi3_1"
7360   [(set (match_operand:HI 0 "register_operand" "=a")
7361         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7362                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7363    (clobber (reg:CC FLAGS_REG))]
7364   "TARGET_QIMODE_MATH
7365    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7366   "mul{b}\t%2"
7367   [(set_attr "type" "imul")
7368    (set_attr "length_immediate" "0")
7369    (set (attr "athlon_decode")
7370      (if_then_else (eq_attr "cpu" "athlon")
7371         (const_string "vector")
7372         (const_string "direct")))
7373    (set_attr "amdfam10_decode" "direct")        
7374    (set_attr "mode" "QI")])
7375
7376 (define_expand "mulqihi3"
7377   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7378                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7379                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7380               (clobber (reg:CC FLAGS_REG))])]
7381   "TARGET_QIMODE_MATH"
7382   "")
7383
7384 (define_insn "*mulqihi3_insn"
7385   [(set (match_operand:HI 0 "register_operand" "=a")
7386         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7387                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7388    (clobber (reg:CC FLAGS_REG))]
7389   "TARGET_QIMODE_MATH
7390    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7391   "imul{b}\t%2"
7392   [(set_attr "type" "imul")
7393    (set_attr "length_immediate" "0")
7394    (set (attr "athlon_decode")
7395      (if_then_else (eq_attr "cpu" "athlon")
7396         (const_string "vector")
7397         (const_string "direct")))
7398    (set_attr "amdfam10_decode" "direct")        
7399    (set_attr "mode" "QI")])
7400
7401 (define_expand "umulditi3"
7402   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7403                    (mult:TI (zero_extend:TI
7404                               (match_operand:DI 1 "nonimmediate_operand" ""))
7405                             (zero_extend:TI
7406                               (match_operand:DI 2 "register_operand" ""))))
7407               (clobber (reg:CC FLAGS_REG))])]
7408   "TARGET_64BIT"
7409   "")
7410
7411 (define_insn "*umulditi3_insn"
7412   [(set (match_operand:TI 0 "register_operand" "=A")
7413         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7414                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7415    (clobber (reg:CC FLAGS_REG))]
7416   "TARGET_64BIT
7417    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7418   "mul{q}\t%2"
7419   [(set_attr "type" "imul")
7420    (set_attr "length_immediate" "0")
7421    (set (attr "athlon_decode")
7422      (if_then_else (eq_attr "cpu" "athlon")
7423         (const_string "vector")
7424         (const_string "double")))
7425    (set_attr "amdfam10_decode" "double")        
7426    (set_attr "mode" "DI")])
7427
7428 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7429 (define_expand "umulsidi3"
7430   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7431                    (mult:DI (zero_extend:DI
7432                               (match_operand:SI 1 "nonimmediate_operand" ""))
7433                             (zero_extend:DI
7434                               (match_operand:SI 2 "register_operand" ""))))
7435               (clobber (reg:CC FLAGS_REG))])]
7436   "!TARGET_64BIT"
7437   "")
7438
7439 (define_insn "*umulsidi3_insn"
7440   [(set (match_operand:DI 0 "register_operand" "=A")
7441         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7442                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7443    (clobber (reg:CC FLAGS_REG))]
7444   "!TARGET_64BIT
7445    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7446   "mul{l}\t%2"
7447   [(set_attr "type" "imul")
7448    (set_attr "length_immediate" "0")
7449    (set (attr "athlon_decode")
7450      (if_then_else (eq_attr "cpu" "athlon")
7451         (const_string "vector")
7452         (const_string "double")))
7453    (set_attr "amdfam10_decode" "double")        
7454    (set_attr "mode" "SI")])
7455
7456 (define_expand "mulditi3"
7457   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7458                    (mult:TI (sign_extend:TI
7459                               (match_operand:DI 1 "nonimmediate_operand" ""))
7460                             (sign_extend:TI
7461                               (match_operand:DI 2 "register_operand" ""))))
7462               (clobber (reg:CC FLAGS_REG))])]
7463   "TARGET_64BIT"
7464   "")
7465
7466 (define_insn "*mulditi3_insn"
7467   [(set (match_operand:TI 0 "register_operand" "=A")
7468         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7469                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7470    (clobber (reg:CC FLAGS_REG))]
7471   "TARGET_64BIT
7472    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7473   "imul{q}\t%2"
7474   [(set_attr "type" "imul")
7475    (set_attr "length_immediate" "0")
7476    (set (attr "athlon_decode")
7477      (if_then_else (eq_attr "cpu" "athlon")
7478         (const_string "vector")
7479         (const_string "double")))
7480    (set_attr "amdfam10_decode" "double")
7481    (set_attr "mode" "DI")])
7482
7483 (define_expand "mulsidi3"
7484   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7485                    (mult:DI (sign_extend:DI
7486                               (match_operand:SI 1 "nonimmediate_operand" ""))
7487                             (sign_extend:DI
7488                               (match_operand:SI 2 "register_operand" ""))))
7489               (clobber (reg:CC FLAGS_REG))])]
7490   "!TARGET_64BIT"
7491   "")
7492
7493 (define_insn "*mulsidi3_insn"
7494   [(set (match_operand:DI 0 "register_operand" "=A")
7495         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7496                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7497    (clobber (reg:CC FLAGS_REG))]
7498   "!TARGET_64BIT
7499    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7500   "imul{l}\t%2"
7501   [(set_attr "type" "imul")
7502    (set_attr "length_immediate" "0")
7503    (set (attr "athlon_decode")
7504      (if_then_else (eq_attr "cpu" "athlon")
7505         (const_string "vector")
7506         (const_string "double")))
7507    (set_attr "amdfam10_decode" "double")        
7508    (set_attr "mode" "SI")])
7509
7510 (define_expand "umuldi3_highpart"
7511   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7512                    (truncate:DI
7513                      (lshiftrt:TI
7514                        (mult:TI (zero_extend:TI
7515                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7516                                 (zero_extend:TI
7517                                   (match_operand:DI 2 "register_operand" "")))
7518                        (const_int 64))))
7519               (clobber (match_scratch:DI 3 ""))
7520               (clobber (reg:CC FLAGS_REG))])]
7521   "TARGET_64BIT"
7522   "")
7523
7524 (define_insn "*umuldi3_highpart_rex64"
7525   [(set (match_operand:DI 0 "register_operand" "=d")
7526         (truncate:DI
7527           (lshiftrt:TI
7528             (mult:TI (zero_extend:TI
7529                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7530                      (zero_extend:TI
7531                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7532             (const_int 64))))
7533    (clobber (match_scratch:DI 3 "=1"))
7534    (clobber (reg:CC FLAGS_REG))]
7535   "TARGET_64BIT
7536    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7537   "mul{q}\t%2"
7538   [(set_attr "type" "imul")
7539    (set_attr "length_immediate" "0")
7540    (set (attr "athlon_decode")
7541      (if_then_else (eq_attr "cpu" "athlon")
7542         (const_string "vector")
7543         (const_string "double")))
7544    (set_attr "amdfam10_decode" "double")        
7545    (set_attr "mode" "DI")])
7546
7547 (define_expand "umulsi3_highpart"
7548   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7549                    (truncate:SI
7550                      (lshiftrt:DI
7551                        (mult:DI (zero_extend:DI
7552                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7553                                 (zero_extend:DI
7554                                   (match_operand:SI 2 "register_operand" "")))
7555                        (const_int 32))))
7556               (clobber (match_scratch:SI 3 ""))
7557               (clobber (reg:CC FLAGS_REG))])]
7558   ""
7559   "")
7560
7561 (define_insn "*umulsi3_highpart_insn"
7562   [(set (match_operand:SI 0 "register_operand" "=d")
7563         (truncate:SI
7564           (lshiftrt:DI
7565             (mult:DI (zero_extend:DI
7566                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7567                      (zero_extend:DI
7568                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7569             (const_int 32))))
7570    (clobber (match_scratch:SI 3 "=1"))
7571    (clobber (reg:CC FLAGS_REG))]
7572   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7573   "mul{l}\t%2"
7574   [(set_attr "type" "imul")
7575    (set_attr "length_immediate" "0")
7576    (set (attr "athlon_decode")
7577      (if_then_else (eq_attr "cpu" "athlon")
7578         (const_string "vector")
7579         (const_string "double")))
7580    (set_attr "amdfam10_decode" "double")
7581    (set_attr "mode" "SI")])
7582
7583 (define_insn "*umulsi3_highpart_zext"
7584   [(set (match_operand:DI 0 "register_operand" "=d")
7585         (zero_extend:DI (truncate:SI
7586           (lshiftrt:DI
7587             (mult:DI (zero_extend:DI
7588                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7589                      (zero_extend:DI
7590                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7591             (const_int 32)))))
7592    (clobber (match_scratch:SI 3 "=1"))
7593    (clobber (reg:CC FLAGS_REG))]
7594   "TARGET_64BIT
7595    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7596   "mul{l}\t%2"
7597   [(set_attr "type" "imul")
7598    (set_attr "length_immediate" "0")
7599    (set (attr "athlon_decode")
7600      (if_then_else (eq_attr "cpu" "athlon")
7601         (const_string "vector")
7602         (const_string "double")))
7603    (set_attr "amdfam10_decode" "double")
7604    (set_attr "mode" "SI")])
7605
7606 (define_expand "smuldi3_highpart"
7607   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7608                    (truncate:DI
7609                      (lshiftrt:TI
7610                        (mult:TI (sign_extend:TI
7611                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7612                                 (sign_extend:TI
7613                                   (match_operand:DI 2 "register_operand" "")))
7614                        (const_int 64))))
7615               (clobber (match_scratch:DI 3 ""))
7616               (clobber (reg:CC FLAGS_REG))])]
7617   "TARGET_64BIT"
7618   "")
7619
7620 (define_insn "*smuldi3_highpart_rex64"
7621   [(set (match_operand:DI 0 "register_operand" "=d")
7622         (truncate:DI
7623           (lshiftrt:TI
7624             (mult:TI (sign_extend:TI
7625                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7626                      (sign_extend:TI
7627                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7628             (const_int 64))))
7629    (clobber (match_scratch:DI 3 "=1"))
7630    (clobber (reg:CC FLAGS_REG))]
7631   "TARGET_64BIT
7632    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7633   "imul{q}\t%2"
7634   [(set_attr "type" "imul")
7635    (set (attr "athlon_decode")
7636      (if_then_else (eq_attr "cpu" "athlon")
7637         (const_string "vector")
7638         (const_string "double")))
7639    (set_attr "amdfam10_decode" "double")
7640    (set_attr "mode" "DI")])
7641
7642 (define_expand "smulsi3_highpart"
7643   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7644                    (truncate:SI
7645                      (lshiftrt:DI
7646                        (mult:DI (sign_extend:DI
7647                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7648                                 (sign_extend:DI
7649                                   (match_operand:SI 2 "register_operand" "")))
7650                        (const_int 32))))
7651               (clobber (match_scratch:SI 3 ""))
7652               (clobber (reg:CC FLAGS_REG))])]
7653   ""
7654   "")
7655
7656 (define_insn "*smulsi3_highpart_insn"
7657   [(set (match_operand:SI 0 "register_operand" "=d")
7658         (truncate:SI
7659           (lshiftrt:DI
7660             (mult:DI (sign_extend:DI
7661                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7662                      (sign_extend:DI
7663                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7664             (const_int 32))))
7665    (clobber (match_scratch:SI 3 "=1"))
7666    (clobber (reg:CC FLAGS_REG))]
7667   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7668   "imul{l}\t%2"
7669   [(set_attr "type" "imul")
7670    (set (attr "athlon_decode")
7671      (if_then_else (eq_attr "cpu" "athlon")
7672         (const_string "vector")
7673         (const_string "double")))
7674    (set_attr "amdfam10_decode" "double")
7675    (set_attr "mode" "SI")])
7676
7677 (define_insn "*smulsi3_highpart_zext"
7678   [(set (match_operand:DI 0 "register_operand" "=d")
7679         (zero_extend:DI (truncate:SI
7680           (lshiftrt:DI
7681             (mult:DI (sign_extend:DI
7682                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7683                      (sign_extend:DI
7684                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7685             (const_int 32)))))
7686    (clobber (match_scratch:SI 3 "=1"))
7687    (clobber (reg:CC FLAGS_REG))]
7688   "TARGET_64BIT
7689    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7690   "imul{l}\t%2"
7691   [(set_attr "type" "imul")
7692    (set (attr "athlon_decode")
7693      (if_then_else (eq_attr "cpu" "athlon")
7694         (const_string "vector")
7695         (const_string "double")))
7696    (set_attr "amdfam10_decode" "double")
7697    (set_attr "mode" "SI")])
7698
7699 ;; The patterns that match these are at the end of this file.
7700
7701 (define_expand "mulxf3"
7702   [(set (match_operand:XF 0 "register_operand" "")
7703         (mult:XF (match_operand:XF 1 "register_operand" "")
7704                  (match_operand:XF 2 "register_operand" "")))]
7705   "TARGET_80387"
7706   "")
7707
7708 (define_expand "muldf3"
7709   [(set (match_operand:DF 0 "register_operand" "")
7710         (mult:DF (match_operand:DF 1 "register_operand" "")
7711                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7712   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7713   "")
7714
7715 (define_expand "mulsf3"
7716   [(set (match_operand:SF 0 "register_operand" "")
7717         (mult:SF (match_operand:SF 1 "register_operand" "")
7718                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7719   "TARGET_80387 || TARGET_SSE_MATH"
7720   "")
7721 \f
7722 ;; Divide instructions
7723
7724 (define_insn "divqi3"
7725   [(set (match_operand:QI 0 "register_operand" "=a")
7726         (div:QI (match_operand:HI 1 "register_operand" "0")
7727                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7728    (clobber (reg:CC FLAGS_REG))]
7729   "TARGET_QIMODE_MATH"
7730   "idiv{b}\t%2"
7731   [(set_attr "type" "idiv")
7732    (set_attr "mode" "QI")])
7733
7734 (define_insn "udivqi3"
7735   [(set (match_operand:QI 0 "register_operand" "=a")
7736         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7737                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7738    (clobber (reg:CC FLAGS_REG))]
7739   "TARGET_QIMODE_MATH"
7740   "div{b}\t%2"
7741   [(set_attr "type" "idiv")
7742    (set_attr "mode" "QI")])
7743
7744 ;; The patterns that match these are at the end of this file.
7745
7746 (define_expand "divxf3"
7747   [(set (match_operand:XF 0 "register_operand" "")
7748         (div:XF (match_operand:XF 1 "register_operand" "")
7749                 (match_operand:XF 2 "register_operand" "")))]
7750   "TARGET_80387"
7751   "")
7752
7753 (define_expand "divdf3"
7754   [(set (match_operand:DF 0 "register_operand" "")
7755         (div:DF (match_operand:DF 1 "register_operand" "")
7756                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7757    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7758    "")
7759
7760 (define_expand "divsf3"
7761   [(set (match_operand:SF 0 "register_operand" "")
7762         (div:SF (match_operand:SF 1 "register_operand" "")
7763                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7764   "TARGET_80387 || TARGET_SSE_MATH"
7765   "")
7766 \f
7767 ;; Remainder instructions.
7768
7769 (define_expand "divmoddi4"
7770   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7771                    (div:DI (match_operand:DI 1 "register_operand" "")
7772                            (match_operand:DI 2 "nonimmediate_operand" "")))
7773               (set (match_operand:DI 3 "register_operand" "")
7774                    (mod:DI (match_dup 1) (match_dup 2)))
7775               (clobber (reg:CC FLAGS_REG))])]
7776   "TARGET_64BIT"
7777   "")
7778
7779 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7780 ;; Penalize eax case slightly because it results in worse scheduling
7781 ;; of code.
7782 (define_insn "*divmoddi4_nocltd_rex64"
7783   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7784         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7785                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7786    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7787         (mod:DI (match_dup 2) (match_dup 3)))
7788    (clobber (reg:CC FLAGS_REG))]
7789   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7790   "#"
7791   [(set_attr "type" "multi")])
7792
7793 (define_insn "*divmoddi4_cltd_rex64"
7794   [(set (match_operand:DI 0 "register_operand" "=a")
7795         (div:DI (match_operand:DI 2 "register_operand" "a")
7796                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7797    (set (match_operand:DI 1 "register_operand" "=&d")
7798         (mod:DI (match_dup 2) (match_dup 3)))
7799    (clobber (reg:CC FLAGS_REG))]
7800   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7801   "#"
7802   [(set_attr "type" "multi")])
7803
7804 (define_insn "*divmoddi_noext_rex64"
7805   [(set (match_operand:DI 0 "register_operand" "=a")
7806         (div:DI (match_operand:DI 1 "register_operand" "0")
7807                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7808    (set (match_operand:DI 3 "register_operand" "=d")
7809         (mod:DI (match_dup 1) (match_dup 2)))
7810    (use (match_operand:DI 4 "register_operand" "3"))
7811    (clobber (reg:CC FLAGS_REG))]
7812   "TARGET_64BIT"
7813   "idiv{q}\t%2"
7814   [(set_attr "type" "idiv")
7815    (set_attr "mode" "DI")])
7816
7817 (define_split
7818   [(set (match_operand:DI 0 "register_operand" "")
7819         (div:DI (match_operand:DI 1 "register_operand" "")
7820                 (match_operand:DI 2 "nonimmediate_operand" "")))
7821    (set (match_operand:DI 3 "register_operand" "")
7822         (mod:DI (match_dup 1) (match_dup 2)))
7823    (clobber (reg:CC FLAGS_REG))]
7824   "TARGET_64BIT && reload_completed"
7825   [(parallel [(set (match_dup 3)
7826                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7827               (clobber (reg:CC FLAGS_REG))])
7828    (parallel [(set (match_dup 0)
7829                    (div:DI (reg:DI 0) (match_dup 2)))
7830               (set (match_dup 3)
7831                    (mod:DI (reg:DI 0) (match_dup 2)))
7832               (use (match_dup 3))
7833               (clobber (reg:CC FLAGS_REG))])]
7834 {
7835   /* Avoid use of cltd in favor of a mov+shift.  */
7836   if (!TARGET_USE_CLTD && !optimize_size)
7837     {
7838       if (true_regnum (operands[1]))
7839         emit_move_insn (operands[0], operands[1]);
7840       else
7841         emit_move_insn (operands[3], operands[1]);
7842       operands[4] = operands[3];
7843     }
7844   else
7845     {
7846       gcc_assert (!true_regnum (operands[1]));
7847       operands[4] = operands[1];
7848     }
7849 })
7850
7851
7852 (define_expand "divmodsi4"
7853   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7854                    (div:SI (match_operand:SI 1 "register_operand" "")
7855                            (match_operand:SI 2 "nonimmediate_operand" "")))
7856               (set (match_operand:SI 3 "register_operand" "")
7857                    (mod:SI (match_dup 1) (match_dup 2)))
7858               (clobber (reg:CC FLAGS_REG))])]
7859   ""
7860   "")
7861
7862 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7863 ;; Penalize eax case slightly because it results in worse scheduling
7864 ;; of code.
7865 (define_insn "*divmodsi4_nocltd"
7866   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7867         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7868                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7869    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7870         (mod:SI (match_dup 2) (match_dup 3)))
7871    (clobber (reg:CC FLAGS_REG))]
7872   "!optimize_size && !TARGET_USE_CLTD"
7873   "#"
7874   [(set_attr "type" "multi")])
7875
7876 (define_insn "*divmodsi4_cltd"
7877   [(set (match_operand:SI 0 "register_operand" "=a")
7878         (div:SI (match_operand:SI 2 "register_operand" "a")
7879                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7880    (set (match_operand:SI 1 "register_operand" "=&d")
7881         (mod:SI (match_dup 2) (match_dup 3)))
7882    (clobber (reg:CC FLAGS_REG))]
7883   "optimize_size || TARGET_USE_CLTD"
7884   "#"
7885   [(set_attr "type" "multi")])
7886
7887 (define_insn "*divmodsi_noext"
7888   [(set (match_operand:SI 0 "register_operand" "=a")
7889         (div:SI (match_operand:SI 1 "register_operand" "0")
7890                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7891    (set (match_operand:SI 3 "register_operand" "=d")
7892         (mod:SI (match_dup 1) (match_dup 2)))
7893    (use (match_operand:SI 4 "register_operand" "3"))
7894    (clobber (reg:CC FLAGS_REG))]
7895   ""
7896   "idiv{l}\t%2"
7897   [(set_attr "type" "idiv")
7898    (set_attr "mode" "SI")])
7899
7900 (define_split
7901   [(set (match_operand:SI 0 "register_operand" "")
7902         (div:SI (match_operand:SI 1 "register_operand" "")
7903                 (match_operand:SI 2 "nonimmediate_operand" "")))
7904    (set (match_operand:SI 3 "register_operand" "")
7905         (mod:SI (match_dup 1) (match_dup 2)))
7906    (clobber (reg:CC FLAGS_REG))]
7907   "reload_completed"
7908   [(parallel [(set (match_dup 3)
7909                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7910               (clobber (reg:CC FLAGS_REG))])
7911    (parallel [(set (match_dup 0)
7912                    (div:SI (reg:SI 0) (match_dup 2)))
7913               (set (match_dup 3)
7914                    (mod:SI (reg:SI 0) (match_dup 2)))
7915               (use (match_dup 3))
7916               (clobber (reg:CC FLAGS_REG))])]
7917 {
7918   /* Avoid use of cltd in favor of a mov+shift.  */
7919   if (!TARGET_USE_CLTD && !optimize_size)
7920     {
7921       if (true_regnum (operands[1]))
7922         emit_move_insn (operands[0], operands[1]);
7923       else
7924         emit_move_insn (operands[3], operands[1]);
7925       operands[4] = operands[3];
7926     }
7927   else
7928     {
7929       gcc_assert (!true_regnum (operands[1]));
7930       operands[4] = operands[1];
7931     }
7932 })
7933 ;; %%% Split me.
7934 (define_insn "divmodhi4"
7935   [(set (match_operand:HI 0 "register_operand" "=a")
7936         (div:HI (match_operand:HI 1 "register_operand" "0")
7937                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7938    (set (match_operand:HI 3 "register_operand" "=&d")
7939         (mod:HI (match_dup 1) (match_dup 2)))
7940    (clobber (reg:CC FLAGS_REG))]
7941   "TARGET_HIMODE_MATH"
7942   "cwtd\;idiv{w}\t%2"
7943   [(set_attr "type" "multi")
7944    (set_attr "length_immediate" "0")
7945    (set_attr "mode" "SI")])
7946
7947 (define_insn "udivmoddi4"
7948   [(set (match_operand:DI 0 "register_operand" "=a")
7949         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7950                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7951    (set (match_operand:DI 3 "register_operand" "=&d")
7952         (umod:DI (match_dup 1) (match_dup 2)))
7953    (clobber (reg:CC FLAGS_REG))]
7954   "TARGET_64BIT"
7955   "xor{q}\t%3, %3\;div{q}\t%2"
7956   [(set_attr "type" "multi")
7957    (set_attr "length_immediate" "0")
7958    (set_attr "mode" "DI")])
7959
7960 (define_insn "*udivmoddi4_noext"
7961   [(set (match_operand:DI 0 "register_operand" "=a")
7962         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7963                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7964    (set (match_operand:DI 3 "register_operand" "=d")
7965         (umod:DI (match_dup 1) (match_dup 2)))
7966    (use (match_dup 3))
7967    (clobber (reg:CC FLAGS_REG))]
7968   "TARGET_64BIT"
7969   "div{q}\t%2"
7970   [(set_attr "type" "idiv")
7971    (set_attr "mode" "DI")])
7972
7973 (define_split
7974   [(set (match_operand:DI 0 "register_operand" "")
7975         (udiv:DI (match_operand:DI 1 "register_operand" "")
7976                  (match_operand:DI 2 "nonimmediate_operand" "")))
7977    (set (match_operand:DI 3 "register_operand" "")
7978         (umod:DI (match_dup 1) (match_dup 2)))
7979    (clobber (reg:CC FLAGS_REG))]
7980   "TARGET_64BIT && reload_completed"
7981   [(set (match_dup 3) (const_int 0))
7982    (parallel [(set (match_dup 0)
7983                    (udiv:DI (match_dup 1) (match_dup 2)))
7984               (set (match_dup 3)
7985                    (umod:DI (match_dup 1) (match_dup 2)))
7986               (use (match_dup 3))
7987               (clobber (reg:CC FLAGS_REG))])]
7988   "")
7989
7990 (define_insn "udivmodsi4"
7991   [(set (match_operand:SI 0 "register_operand" "=a")
7992         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7993                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7994    (set (match_operand:SI 3 "register_operand" "=&d")
7995         (umod:SI (match_dup 1) (match_dup 2)))
7996    (clobber (reg:CC FLAGS_REG))]
7997   ""
7998   "xor{l}\t%3, %3\;div{l}\t%2"
7999   [(set_attr "type" "multi")
8000    (set_attr "length_immediate" "0")
8001    (set_attr "mode" "SI")])
8002
8003 (define_insn "*udivmodsi4_noext"
8004   [(set (match_operand:SI 0 "register_operand" "=a")
8005         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8006                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8007    (set (match_operand:SI 3 "register_operand" "=d")
8008         (umod:SI (match_dup 1) (match_dup 2)))
8009    (use (match_dup 3))
8010    (clobber (reg:CC FLAGS_REG))]
8011   ""
8012   "div{l}\t%2"
8013   [(set_attr "type" "idiv")
8014    (set_attr "mode" "SI")])
8015
8016 (define_split
8017   [(set (match_operand:SI 0 "register_operand" "")
8018         (udiv:SI (match_operand:SI 1 "register_operand" "")
8019                  (match_operand:SI 2 "nonimmediate_operand" "")))
8020    (set (match_operand:SI 3 "register_operand" "")
8021         (umod:SI (match_dup 1) (match_dup 2)))
8022    (clobber (reg:CC FLAGS_REG))]
8023   "reload_completed"
8024   [(set (match_dup 3) (const_int 0))
8025    (parallel [(set (match_dup 0)
8026                    (udiv:SI (match_dup 1) (match_dup 2)))
8027               (set (match_dup 3)
8028                    (umod:SI (match_dup 1) (match_dup 2)))
8029               (use (match_dup 3))
8030               (clobber (reg:CC FLAGS_REG))])]
8031   "")
8032
8033 (define_expand "udivmodhi4"
8034   [(set (match_dup 4) (const_int 0))
8035    (parallel [(set (match_operand:HI 0 "register_operand" "")
8036                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8037                             (match_operand:HI 2 "nonimmediate_operand" "")))
8038               (set (match_operand:HI 3 "register_operand" "")
8039                    (umod:HI (match_dup 1) (match_dup 2)))
8040               (use (match_dup 4))
8041               (clobber (reg:CC FLAGS_REG))])]
8042   "TARGET_HIMODE_MATH"
8043   "operands[4] = gen_reg_rtx (HImode);")
8044
8045 (define_insn "*udivmodhi_noext"
8046   [(set (match_operand:HI 0 "register_operand" "=a")
8047         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8048                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8049    (set (match_operand:HI 3 "register_operand" "=d")
8050         (umod:HI (match_dup 1) (match_dup 2)))
8051    (use (match_operand:HI 4 "register_operand" "3"))
8052    (clobber (reg:CC FLAGS_REG))]
8053   ""
8054   "div{w}\t%2"
8055   [(set_attr "type" "idiv")
8056    (set_attr "mode" "HI")])
8057
8058 ;; We cannot use div/idiv for double division, because it causes
8059 ;; "division by zero" on the overflow and that's not what we expect
8060 ;; from truncate.  Because true (non truncating) double division is
8061 ;; never generated, we can't create this insn anyway.
8062 ;
8063 ;(define_insn ""
8064 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8065 ;       (truncate:SI
8066 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8067 ;                  (zero_extend:DI
8068 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8069 ;   (set (match_operand:SI 3 "register_operand" "=d")
8070 ;       (truncate:SI
8071 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8072 ;   (clobber (reg:CC FLAGS_REG))]
8073 ;  ""
8074 ;  "div{l}\t{%2, %0|%0, %2}"
8075 ;  [(set_attr "type" "idiv")])
8076 \f
8077 ;;- Logical AND instructions
8078
8079 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8080 ;; Note that this excludes ah.
8081
8082 (define_insn "*testdi_1_rex64"
8083   [(set (reg FLAGS_REG)
8084         (compare
8085           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8086                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8087           (const_int 0)))]
8088   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8089    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8090   "@
8091    test{l}\t{%k1, %k0|%k0, %k1}
8092    test{l}\t{%k1, %k0|%k0, %k1}
8093    test{q}\t{%1, %0|%0, %1}
8094    test{q}\t{%1, %0|%0, %1}
8095    test{q}\t{%1, %0|%0, %1}"
8096   [(set_attr "type" "test")
8097    (set_attr "modrm" "0,1,0,1,1")
8098    (set_attr "mode" "SI,SI,DI,DI,DI")
8099    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8100
8101 (define_insn "testsi_1"
8102   [(set (reg FLAGS_REG)
8103         (compare
8104           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8105                   (match_operand:SI 1 "general_operand" "in,in,rin"))
8106           (const_int 0)))]
8107   "ix86_match_ccmode (insn, CCNOmode)
8108    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8109   "test{l}\t{%1, %0|%0, %1}"
8110   [(set_attr "type" "test")
8111    (set_attr "modrm" "0,1,1")
8112    (set_attr "mode" "SI")
8113    (set_attr "pent_pair" "uv,np,uv")])
8114
8115 (define_expand "testsi_ccno_1"
8116   [(set (reg:CCNO FLAGS_REG)
8117         (compare:CCNO
8118           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8119                   (match_operand:SI 1 "nonmemory_operand" ""))
8120           (const_int 0)))]
8121   ""
8122   "")
8123
8124 (define_insn "*testhi_1"
8125   [(set (reg FLAGS_REG)
8126         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8127                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8128                  (const_int 0)))]
8129   "ix86_match_ccmode (insn, CCNOmode)
8130    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8131   "test{w}\t{%1, %0|%0, %1}"
8132   [(set_attr "type" "test")
8133    (set_attr "modrm" "0,1,1")
8134    (set_attr "mode" "HI")
8135    (set_attr "pent_pair" "uv,np,uv")])
8136
8137 (define_expand "testqi_ccz_1"
8138   [(set (reg:CCZ FLAGS_REG)
8139         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8140                              (match_operand:QI 1 "nonmemory_operand" ""))
8141                  (const_int 0)))]
8142   ""
8143   "")
8144
8145 (define_insn "*testqi_1_maybe_si"
8146   [(set (reg FLAGS_REG)
8147         (compare
8148           (and:QI
8149             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8150             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8151           (const_int 0)))]
8152    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8153     && ix86_match_ccmode (insn,
8154                          CONST_INT_P (operands[1])
8155                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8156 {
8157   if (which_alternative == 3)
8158     {
8159       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8160         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8161       return "test{l}\t{%1, %k0|%k0, %1}";
8162     }
8163   return "test{b}\t{%1, %0|%0, %1}";
8164 }
8165   [(set_attr "type" "test")
8166    (set_attr "modrm" "0,1,1,1")
8167    (set_attr "mode" "QI,QI,QI,SI")
8168    (set_attr "pent_pair" "uv,np,uv,np")])
8169
8170 (define_insn "*testqi_1"
8171   [(set (reg FLAGS_REG)
8172         (compare
8173           (and:QI
8174             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8175             (match_operand:QI 1 "general_operand" "n,n,qn"))
8176           (const_int 0)))]
8177   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8178    && ix86_match_ccmode (insn, CCNOmode)"
8179   "test{b}\t{%1, %0|%0, %1}"
8180   [(set_attr "type" "test")
8181    (set_attr "modrm" "0,1,1")
8182    (set_attr "mode" "QI")
8183    (set_attr "pent_pair" "uv,np,uv")])
8184
8185 (define_expand "testqi_ext_ccno_0"
8186   [(set (reg:CCNO FLAGS_REG)
8187         (compare:CCNO
8188           (and:SI
8189             (zero_extract:SI
8190               (match_operand 0 "ext_register_operand" "")
8191               (const_int 8)
8192               (const_int 8))
8193             (match_operand 1 "const_int_operand" ""))
8194           (const_int 0)))]
8195   ""
8196   "")
8197
8198 (define_insn "*testqi_ext_0"
8199   [(set (reg FLAGS_REG)
8200         (compare
8201           (and:SI
8202             (zero_extract:SI
8203               (match_operand 0 "ext_register_operand" "Q")
8204               (const_int 8)
8205               (const_int 8))
8206             (match_operand 1 "const_int_operand" "n"))
8207           (const_int 0)))]
8208   "ix86_match_ccmode (insn, CCNOmode)"
8209   "test{b}\t{%1, %h0|%h0, %1}"
8210   [(set_attr "type" "test")
8211    (set_attr "mode" "QI")
8212    (set_attr "length_immediate" "1")
8213    (set_attr "pent_pair" "np")])
8214
8215 (define_insn "*testqi_ext_1"
8216   [(set (reg FLAGS_REG)
8217         (compare
8218           (and:SI
8219             (zero_extract:SI
8220               (match_operand 0 "ext_register_operand" "Q")
8221               (const_int 8)
8222               (const_int 8))
8223             (zero_extend:SI
8224               (match_operand:QI 1 "general_operand" "Qm")))
8225           (const_int 0)))]
8226   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8227    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8228   "test{b}\t{%1, %h0|%h0, %1}"
8229   [(set_attr "type" "test")
8230    (set_attr "mode" "QI")])
8231
8232 (define_insn "*testqi_ext_1_rex64"
8233   [(set (reg FLAGS_REG)
8234         (compare
8235           (and:SI
8236             (zero_extract:SI
8237               (match_operand 0 "ext_register_operand" "Q")
8238               (const_int 8)
8239               (const_int 8))
8240             (zero_extend:SI
8241               (match_operand:QI 1 "register_operand" "Q")))
8242           (const_int 0)))]
8243   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8244   "test{b}\t{%1, %h0|%h0, %1}"
8245   [(set_attr "type" "test")
8246    (set_attr "mode" "QI")])
8247
8248 (define_insn "*testqi_ext_2"
8249   [(set (reg FLAGS_REG)
8250         (compare
8251           (and:SI
8252             (zero_extract:SI
8253               (match_operand 0 "ext_register_operand" "Q")
8254               (const_int 8)
8255               (const_int 8))
8256             (zero_extract:SI
8257               (match_operand 1 "ext_register_operand" "Q")
8258               (const_int 8)
8259               (const_int 8)))
8260           (const_int 0)))]
8261   "ix86_match_ccmode (insn, CCNOmode)"
8262   "test{b}\t{%h1, %h0|%h0, %h1}"
8263   [(set_attr "type" "test")
8264    (set_attr "mode" "QI")])
8265
8266 ;; Combine likes to form bit extractions for some tests.  Humor it.
8267 (define_insn "*testqi_ext_3"
8268   [(set (reg FLAGS_REG)
8269         (compare (zero_extract:SI
8270                    (match_operand 0 "nonimmediate_operand" "rm")
8271                    (match_operand:SI 1 "const_int_operand" "")
8272                    (match_operand:SI 2 "const_int_operand" ""))
8273                  (const_int 0)))]
8274   "ix86_match_ccmode (insn, CCNOmode)
8275    && INTVAL (operands[1]) > 0
8276    && INTVAL (operands[2]) >= 0
8277    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8278    && (GET_MODE (operands[0]) == SImode
8279        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8280        || GET_MODE (operands[0]) == HImode
8281        || GET_MODE (operands[0]) == QImode)"
8282   "#")
8283
8284 (define_insn "*testqi_ext_3_rex64"
8285   [(set (reg FLAGS_REG)
8286         (compare (zero_extract:DI
8287                    (match_operand 0 "nonimmediate_operand" "rm")
8288                    (match_operand:DI 1 "const_int_operand" "")
8289                    (match_operand:DI 2 "const_int_operand" ""))
8290                  (const_int 0)))]
8291   "TARGET_64BIT
8292    && ix86_match_ccmode (insn, CCNOmode)
8293    && INTVAL (operands[1]) > 0
8294    && INTVAL (operands[2]) >= 0
8295    /* Ensure that resulting mask is zero or sign extended operand.  */
8296    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8297        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8298            && INTVAL (operands[1]) > 32))
8299    && (GET_MODE (operands[0]) == SImode
8300        || GET_MODE (operands[0]) == DImode
8301        || GET_MODE (operands[0]) == HImode
8302        || GET_MODE (operands[0]) == QImode)"
8303   "#")
8304
8305 (define_split
8306   [(set (match_operand 0 "flags_reg_operand" "")
8307         (match_operator 1 "compare_operator"
8308           [(zero_extract
8309              (match_operand 2 "nonimmediate_operand" "")
8310              (match_operand 3 "const_int_operand" "")
8311              (match_operand 4 "const_int_operand" ""))
8312            (const_int 0)]))]
8313   "ix86_match_ccmode (insn, CCNOmode)"
8314   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8315 {
8316   rtx val = operands[2];
8317   HOST_WIDE_INT len = INTVAL (operands[3]);
8318   HOST_WIDE_INT pos = INTVAL (operands[4]);
8319   HOST_WIDE_INT mask;
8320   enum machine_mode mode, submode;
8321
8322   mode = GET_MODE (val);
8323   if (MEM_P (val))
8324     {
8325       /* ??? Combine likes to put non-volatile mem extractions in QImode
8326          no matter the size of the test.  So find a mode that works.  */
8327       if (! MEM_VOLATILE_P (val))
8328         {
8329           mode = smallest_mode_for_size (pos + len, MODE_INT);
8330           val = adjust_address (val, mode, 0);
8331         }
8332     }
8333   else if (GET_CODE (val) == SUBREG
8334            && (submode = GET_MODE (SUBREG_REG (val)),
8335                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8336            && pos + len <= GET_MODE_BITSIZE (submode))
8337     {
8338       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8339       mode = submode;
8340       val = SUBREG_REG (val);
8341     }
8342   else if (mode == HImode && pos + len <= 8)
8343     {
8344       /* Small HImode tests can be converted to QImode.  */
8345       mode = QImode;
8346       val = gen_lowpart (QImode, val);
8347     }
8348
8349   if (len == HOST_BITS_PER_WIDE_INT)
8350     mask = -1;
8351   else
8352     mask = ((HOST_WIDE_INT)1 << len) - 1;
8353   mask <<= pos;
8354
8355   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8356 })
8357
8358 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8359 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8360 ;; this is relatively important trick.
8361 ;; Do the conversion only post-reload to avoid limiting of the register class
8362 ;; to QI regs.
8363 (define_split
8364   [(set (match_operand 0 "flags_reg_operand" "")
8365         (match_operator 1 "compare_operator"
8366           [(and (match_operand 2 "register_operand" "")
8367                 (match_operand 3 "const_int_operand" ""))
8368            (const_int 0)]))]
8369    "reload_completed
8370     && QI_REG_P (operands[2])
8371     && GET_MODE (operands[2]) != QImode
8372     && ((ix86_match_ccmode (insn, CCZmode)
8373          && !(INTVAL (operands[3]) & ~(255 << 8)))
8374         || (ix86_match_ccmode (insn, CCNOmode)
8375             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8376   [(set (match_dup 0)
8377         (match_op_dup 1
8378           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8379                    (match_dup 3))
8380            (const_int 0)]))]
8381   "operands[2] = gen_lowpart (SImode, operands[2]);
8382    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8383
8384 (define_split
8385   [(set (match_operand 0 "flags_reg_operand" "")
8386         (match_operator 1 "compare_operator"
8387           [(and (match_operand 2 "nonimmediate_operand" "")
8388                 (match_operand 3 "const_int_operand" ""))
8389            (const_int 0)]))]
8390    "reload_completed
8391     && GET_MODE (operands[2]) != QImode
8392     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8393     && ((ix86_match_ccmode (insn, CCZmode)
8394          && !(INTVAL (operands[3]) & ~255))
8395         || (ix86_match_ccmode (insn, CCNOmode)
8396             && !(INTVAL (operands[3]) & ~127)))"
8397   [(set (match_dup 0)
8398         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8399                          (const_int 0)]))]
8400   "operands[2] = gen_lowpart (QImode, operands[2]);
8401    operands[3] = gen_lowpart (QImode, operands[3]);")
8402
8403
8404 ;; %%% This used to optimize known byte-wide and operations to memory,
8405 ;; and sometimes to QImode registers.  If this is considered useful,
8406 ;; it should be done with splitters.
8407
8408 (define_expand "anddi3"
8409   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8410         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8411                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8412    (clobber (reg:CC FLAGS_REG))]
8413   "TARGET_64BIT"
8414   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8415
8416 (define_insn "*anddi_1_rex64"
8417   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8418         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8419                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8420    (clobber (reg:CC FLAGS_REG))]
8421   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8422 {
8423   switch (get_attr_type (insn))
8424     {
8425     case TYPE_IMOVX:
8426       {
8427         enum machine_mode mode;
8428
8429         gcc_assert (CONST_INT_P (operands[2]));
8430         if (INTVAL (operands[2]) == 0xff)
8431           mode = QImode;
8432         else
8433           {
8434             gcc_assert (INTVAL (operands[2]) == 0xffff);
8435             mode = HImode;
8436           }
8437
8438         operands[1] = gen_lowpart (mode, operands[1]);
8439         if (mode == QImode)
8440           return "movz{bq|x}\t{%1,%0|%0, %1}";
8441         else
8442           return "movz{wq|x}\t{%1,%0|%0, %1}";
8443       }
8444
8445     default:
8446       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8447       if (get_attr_mode (insn) == MODE_SI)
8448         return "and{l}\t{%k2, %k0|%k0, %k2}";
8449       else
8450         return "and{q}\t{%2, %0|%0, %2}";
8451     }
8452 }
8453   [(set_attr "type" "alu,alu,alu,imovx")
8454    (set_attr "length_immediate" "*,*,*,0")
8455    (set_attr "mode" "SI,DI,DI,DI")])
8456
8457 (define_insn "*anddi_2"
8458   [(set (reg FLAGS_REG)
8459         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8460                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8461                  (const_int 0)))
8462    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8463         (and:DI (match_dup 1) (match_dup 2)))]
8464   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8465    && ix86_binary_operator_ok (AND, DImode, operands)"
8466   "@
8467    and{l}\t{%k2, %k0|%k0, %k2}
8468    and{q}\t{%2, %0|%0, %2}
8469    and{q}\t{%2, %0|%0, %2}"
8470   [(set_attr "type" "alu")
8471    (set_attr "mode" "SI,DI,DI")])
8472
8473 (define_expand "andsi3"
8474   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8475         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8476                 (match_operand:SI 2 "general_operand" "")))
8477    (clobber (reg:CC FLAGS_REG))]
8478   ""
8479   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8480
8481 (define_insn "*andsi_1"
8482   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8483         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8484                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8485    (clobber (reg:CC FLAGS_REG))]
8486   "ix86_binary_operator_ok (AND, SImode, operands)"
8487 {
8488   switch (get_attr_type (insn))
8489     {
8490     case TYPE_IMOVX:
8491       {
8492         enum machine_mode mode;
8493
8494         gcc_assert (CONST_INT_P (operands[2]));
8495         if (INTVAL (operands[2]) == 0xff)
8496           mode = QImode;
8497         else
8498           {
8499             gcc_assert (INTVAL (operands[2]) == 0xffff);
8500             mode = HImode;
8501           }
8502
8503         operands[1] = gen_lowpart (mode, operands[1]);
8504         if (mode == QImode)
8505           return "movz{bl|x}\t{%1,%0|%0, %1}";
8506         else
8507           return "movz{wl|x}\t{%1,%0|%0, %1}";
8508       }
8509
8510     default:
8511       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8512       return "and{l}\t{%2, %0|%0, %2}";
8513     }
8514 }
8515   [(set_attr "type" "alu,alu,imovx")
8516    (set_attr "length_immediate" "*,*,0")
8517    (set_attr "mode" "SI")])
8518
8519 (define_split
8520   [(set (match_operand 0 "register_operand" "")
8521         (and (match_dup 0)
8522              (const_int -65536)))
8523    (clobber (reg:CC FLAGS_REG))]
8524   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8525   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8526   "operands[1] = gen_lowpart (HImode, operands[0]);")
8527
8528 (define_split
8529   [(set (match_operand 0 "ext_register_operand" "")
8530         (and (match_dup 0)
8531              (const_int -256)))
8532    (clobber (reg:CC FLAGS_REG))]
8533   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8534   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8535   "operands[1] = gen_lowpart (QImode, operands[0]);")
8536
8537 (define_split
8538   [(set (match_operand 0 "ext_register_operand" "")
8539         (and (match_dup 0)
8540              (const_int -65281)))
8541    (clobber (reg:CC FLAGS_REG))]
8542   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8543   [(parallel [(set (zero_extract:SI (match_dup 0)
8544                                     (const_int 8)
8545                                     (const_int 8))
8546                    (xor:SI
8547                      (zero_extract:SI (match_dup 0)
8548                                       (const_int 8)
8549                                       (const_int 8))
8550                      (zero_extract:SI (match_dup 0)
8551                                       (const_int 8)
8552                                       (const_int 8))))
8553               (clobber (reg:CC FLAGS_REG))])]
8554   "operands[0] = gen_lowpart (SImode, operands[0]);")
8555
8556 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8557 (define_insn "*andsi_1_zext"
8558   [(set (match_operand:DI 0 "register_operand" "=r")
8559         (zero_extend:DI
8560           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8561                   (match_operand:SI 2 "general_operand" "rim"))))
8562    (clobber (reg:CC FLAGS_REG))]
8563   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8564   "and{l}\t{%2, %k0|%k0, %2}"
8565   [(set_attr "type" "alu")
8566    (set_attr "mode" "SI")])
8567
8568 (define_insn "*andsi_2"
8569   [(set (reg FLAGS_REG)
8570         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8571                          (match_operand:SI 2 "general_operand" "rim,ri"))
8572                  (const_int 0)))
8573    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8574         (and:SI (match_dup 1) (match_dup 2)))]
8575   "ix86_match_ccmode (insn, CCNOmode)
8576    && ix86_binary_operator_ok (AND, SImode, operands)"
8577   "and{l}\t{%2, %0|%0, %2}"
8578   [(set_attr "type" "alu")
8579    (set_attr "mode" "SI")])
8580
8581 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8582 (define_insn "*andsi_2_zext"
8583   [(set (reg FLAGS_REG)
8584         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8585                          (match_operand:SI 2 "general_operand" "rim"))
8586                  (const_int 0)))
8587    (set (match_operand:DI 0 "register_operand" "=r")
8588         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8589   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8590    && ix86_binary_operator_ok (AND, SImode, operands)"
8591   "and{l}\t{%2, %k0|%k0, %2}"
8592   [(set_attr "type" "alu")
8593    (set_attr "mode" "SI")])
8594
8595 (define_expand "andhi3"
8596   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8597         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8598                 (match_operand:HI 2 "general_operand" "")))
8599    (clobber (reg:CC FLAGS_REG))]
8600   "TARGET_HIMODE_MATH"
8601   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8602
8603 (define_insn "*andhi_1"
8604   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8605         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8606                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8607    (clobber (reg:CC FLAGS_REG))]
8608   "ix86_binary_operator_ok (AND, HImode, operands)"
8609 {
8610   switch (get_attr_type (insn))
8611     {
8612     case TYPE_IMOVX:
8613       gcc_assert (CONST_INT_P (operands[2]));
8614       gcc_assert (INTVAL (operands[2]) == 0xff);
8615       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8616
8617     default:
8618       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8619
8620       return "and{w}\t{%2, %0|%0, %2}";
8621     }
8622 }
8623   [(set_attr "type" "alu,alu,imovx")
8624    (set_attr "length_immediate" "*,*,0")
8625    (set_attr "mode" "HI,HI,SI")])
8626
8627 (define_insn "*andhi_2"
8628   [(set (reg FLAGS_REG)
8629         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8630                          (match_operand:HI 2 "general_operand" "rim,ri"))
8631                  (const_int 0)))
8632    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8633         (and:HI (match_dup 1) (match_dup 2)))]
8634   "ix86_match_ccmode (insn, CCNOmode)
8635    && ix86_binary_operator_ok (AND, HImode, operands)"
8636   "and{w}\t{%2, %0|%0, %2}"
8637   [(set_attr "type" "alu")
8638    (set_attr "mode" "HI")])
8639
8640 (define_expand "andqi3"
8641   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8642         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8643                 (match_operand:QI 2 "general_operand" "")))
8644    (clobber (reg:CC FLAGS_REG))]
8645   "TARGET_QIMODE_MATH"
8646   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8647
8648 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8649 (define_insn "*andqi_1"
8650   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8651         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8652                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8653    (clobber (reg:CC FLAGS_REG))]
8654   "ix86_binary_operator_ok (AND, QImode, operands)"
8655   "@
8656    and{b}\t{%2, %0|%0, %2}
8657    and{b}\t{%2, %0|%0, %2}
8658    and{l}\t{%k2, %k0|%k0, %k2}"
8659   [(set_attr "type" "alu")
8660    (set_attr "mode" "QI,QI,SI")])
8661
8662 (define_insn "*andqi_1_slp"
8663   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8664         (and:QI (match_dup 0)
8665                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8666    (clobber (reg:CC FLAGS_REG))]
8667   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8668    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8669   "and{b}\t{%1, %0|%0, %1}"
8670   [(set_attr "type" "alu1")
8671    (set_attr "mode" "QI")])
8672
8673 (define_insn "*andqi_2_maybe_si"
8674   [(set (reg FLAGS_REG)
8675         (compare (and:QI
8676                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8677                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8678                  (const_int 0)))
8679    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8680         (and:QI (match_dup 1) (match_dup 2)))]
8681   "ix86_binary_operator_ok (AND, QImode, operands)
8682    && ix86_match_ccmode (insn,
8683                          CONST_INT_P (operands[2])
8684                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8685 {
8686   if (which_alternative == 2)
8687     {
8688       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8689         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8690       return "and{l}\t{%2, %k0|%k0, %2}";
8691     }
8692   return "and{b}\t{%2, %0|%0, %2}";
8693 }
8694   [(set_attr "type" "alu")
8695    (set_attr "mode" "QI,QI,SI")])
8696
8697 (define_insn "*andqi_2"
8698   [(set (reg FLAGS_REG)
8699         (compare (and:QI
8700                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8701                    (match_operand:QI 2 "general_operand" "qim,qi"))
8702                  (const_int 0)))
8703    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8704         (and:QI (match_dup 1) (match_dup 2)))]
8705   "ix86_match_ccmode (insn, CCNOmode)
8706    && ix86_binary_operator_ok (AND, QImode, operands)"
8707   "and{b}\t{%2, %0|%0, %2}"
8708   [(set_attr "type" "alu")
8709    (set_attr "mode" "QI")])
8710
8711 (define_insn "*andqi_2_slp"
8712   [(set (reg FLAGS_REG)
8713         (compare (and:QI
8714                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8715                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8716                  (const_int 0)))
8717    (set (strict_low_part (match_dup 0))
8718         (and:QI (match_dup 0) (match_dup 1)))]
8719   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8720    && ix86_match_ccmode (insn, CCNOmode)
8721    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8722   "and{b}\t{%1, %0|%0, %1}"
8723   [(set_attr "type" "alu1")
8724    (set_attr "mode" "QI")])
8725
8726 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8727 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8728 ;; for a QImode operand, which of course failed.
8729
8730 (define_insn "andqi_ext_0"
8731   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8732                          (const_int 8)
8733                          (const_int 8))
8734         (and:SI
8735           (zero_extract:SI
8736             (match_operand 1 "ext_register_operand" "0")
8737             (const_int 8)
8738             (const_int 8))
8739           (match_operand 2 "const_int_operand" "n")))
8740    (clobber (reg:CC FLAGS_REG))]
8741   ""
8742   "and{b}\t{%2, %h0|%h0, %2}"
8743   [(set_attr "type" "alu")
8744    (set_attr "length_immediate" "1")
8745    (set_attr "mode" "QI")])
8746
8747 ;; Generated by peephole translating test to and.  This shows up
8748 ;; often in fp comparisons.
8749
8750 (define_insn "*andqi_ext_0_cc"
8751   [(set (reg FLAGS_REG)
8752         (compare
8753           (and:SI
8754             (zero_extract:SI
8755               (match_operand 1 "ext_register_operand" "0")
8756               (const_int 8)
8757               (const_int 8))
8758             (match_operand 2 "const_int_operand" "n"))
8759           (const_int 0)))
8760    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8761                          (const_int 8)
8762                          (const_int 8))
8763         (and:SI
8764           (zero_extract:SI
8765             (match_dup 1)
8766             (const_int 8)
8767             (const_int 8))
8768           (match_dup 2)))]
8769   "ix86_match_ccmode (insn, CCNOmode)"
8770   "and{b}\t{%2, %h0|%h0, %2}"
8771   [(set_attr "type" "alu")
8772    (set_attr "length_immediate" "1")
8773    (set_attr "mode" "QI")])
8774
8775 (define_insn "*andqi_ext_1"
8776   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8777                          (const_int 8)
8778                          (const_int 8))
8779         (and:SI
8780           (zero_extract:SI
8781             (match_operand 1 "ext_register_operand" "0")
8782             (const_int 8)
8783             (const_int 8))
8784           (zero_extend:SI
8785             (match_operand:QI 2 "general_operand" "Qm"))))
8786    (clobber (reg:CC FLAGS_REG))]
8787   "!TARGET_64BIT"
8788   "and{b}\t{%2, %h0|%h0, %2}"
8789   [(set_attr "type" "alu")
8790    (set_attr "length_immediate" "0")
8791    (set_attr "mode" "QI")])
8792
8793 (define_insn "*andqi_ext_1_rex64"
8794   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8795                          (const_int 8)
8796                          (const_int 8))
8797         (and:SI
8798           (zero_extract:SI
8799             (match_operand 1 "ext_register_operand" "0")
8800             (const_int 8)
8801             (const_int 8))
8802           (zero_extend:SI
8803             (match_operand 2 "ext_register_operand" "Q"))))
8804    (clobber (reg:CC FLAGS_REG))]
8805   "TARGET_64BIT"
8806   "and{b}\t{%2, %h0|%h0, %2}"
8807   [(set_attr "type" "alu")
8808    (set_attr "length_immediate" "0")
8809    (set_attr "mode" "QI")])
8810
8811 (define_insn "*andqi_ext_2"
8812   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8813                          (const_int 8)
8814                          (const_int 8))
8815         (and:SI
8816           (zero_extract:SI
8817             (match_operand 1 "ext_register_operand" "%0")
8818             (const_int 8)
8819             (const_int 8))
8820           (zero_extract:SI
8821             (match_operand 2 "ext_register_operand" "Q")
8822             (const_int 8)
8823             (const_int 8))))
8824    (clobber (reg:CC FLAGS_REG))]
8825   ""
8826   "and{b}\t{%h2, %h0|%h0, %h2}"
8827   [(set_attr "type" "alu")
8828    (set_attr "length_immediate" "0")
8829    (set_attr "mode" "QI")])
8830
8831 ;; Convert wide AND instructions with immediate operand to shorter QImode
8832 ;; equivalents when possible.
8833 ;; Don't do the splitting with memory operands, since it introduces risk
8834 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8835 ;; for size, but that can (should?) be handled by generic code instead.
8836 (define_split
8837   [(set (match_operand 0 "register_operand" "")
8838         (and (match_operand 1 "register_operand" "")
8839              (match_operand 2 "const_int_operand" "")))
8840    (clobber (reg:CC FLAGS_REG))]
8841    "reload_completed
8842     && QI_REG_P (operands[0])
8843     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8844     && !(~INTVAL (operands[2]) & ~(255 << 8))
8845     && GET_MODE (operands[0]) != QImode"
8846   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8847                    (and:SI (zero_extract:SI (match_dup 1)
8848                                             (const_int 8) (const_int 8))
8849                            (match_dup 2)))
8850               (clobber (reg:CC FLAGS_REG))])]
8851   "operands[0] = gen_lowpart (SImode, operands[0]);
8852    operands[1] = gen_lowpart (SImode, operands[1]);
8853    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8854
8855 ;; Since AND can be encoded with sign extended immediate, this is only
8856 ;; profitable when 7th bit is not set.
8857 (define_split
8858   [(set (match_operand 0 "register_operand" "")
8859         (and (match_operand 1 "general_operand" "")
8860              (match_operand 2 "const_int_operand" "")))
8861    (clobber (reg:CC FLAGS_REG))]
8862    "reload_completed
8863     && ANY_QI_REG_P (operands[0])
8864     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8865     && !(~INTVAL (operands[2]) & ~255)
8866     && !(INTVAL (operands[2]) & 128)
8867     && GET_MODE (operands[0]) != QImode"
8868   [(parallel [(set (strict_low_part (match_dup 0))
8869                    (and:QI (match_dup 1)
8870                            (match_dup 2)))
8871               (clobber (reg:CC FLAGS_REG))])]
8872   "operands[0] = gen_lowpart (QImode, operands[0]);
8873    operands[1] = gen_lowpart (QImode, operands[1]);
8874    operands[2] = gen_lowpart (QImode, operands[2]);")
8875 \f
8876 ;; Logical inclusive OR instructions
8877
8878 ;; %%% This used to optimize known byte-wide and operations to memory.
8879 ;; If this is considered useful, it should be done with splitters.
8880
8881 (define_expand "iordi3"
8882   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8883         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8884                 (match_operand:DI 2 "x86_64_general_operand" "")))
8885    (clobber (reg:CC FLAGS_REG))]
8886   "TARGET_64BIT"
8887   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8888
8889 (define_insn "*iordi_1_rex64"
8890   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8891         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8892                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8893    (clobber (reg:CC FLAGS_REG))]
8894   "TARGET_64BIT
8895    && ix86_binary_operator_ok (IOR, DImode, operands)"
8896   "or{q}\t{%2, %0|%0, %2}"
8897   [(set_attr "type" "alu")
8898    (set_attr "mode" "DI")])
8899
8900 (define_insn "*iordi_2_rex64"
8901   [(set (reg FLAGS_REG)
8902         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8903                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8904                  (const_int 0)))
8905    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8906         (ior:DI (match_dup 1) (match_dup 2)))]
8907   "TARGET_64BIT
8908    && ix86_match_ccmode (insn, CCNOmode)
8909    && ix86_binary_operator_ok (IOR, DImode, operands)"
8910   "or{q}\t{%2, %0|%0, %2}"
8911   [(set_attr "type" "alu")
8912    (set_attr "mode" "DI")])
8913
8914 (define_insn "*iordi_3_rex64"
8915   [(set (reg FLAGS_REG)
8916         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8917                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8918                  (const_int 0)))
8919    (clobber (match_scratch:DI 0 "=r"))]
8920   "TARGET_64BIT
8921    && ix86_match_ccmode (insn, CCNOmode)
8922    && ix86_binary_operator_ok (IOR, DImode, operands)"
8923   "or{q}\t{%2, %0|%0, %2}"
8924   [(set_attr "type" "alu")
8925    (set_attr "mode" "DI")])
8926
8927
8928 (define_expand "iorsi3"
8929   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8930         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8931                 (match_operand:SI 2 "general_operand" "")))
8932    (clobber (reg:CC FLAGS_REG))]
8933   ""
8934   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8935
8936 (define_insn "*iorsi_1"
8937   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8938         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8939                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8940    (clobber (reg:CC FLAGS_REG))]
8941   "ix86_binary_operator_ok (IOR, SImode, operands)"
8942   "or{l}\t{%2, %0|%0, %2}"
8943   [(set_attr "type" "alu")
8944    (set_attr "mode" "SI")])
8945
8946 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8947 (define_insn "*iorsi_1_zext"
8948   [(set (match_operand:DI 0 "register_operand" "=rm")
8949         (zero_extend:DI
8950           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8951                   (match_operand:SI 2 "general_operand" "rim"))))
8952    (clobber (reg:CC FLAGS_REG))]
8953   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8954   "or{l}\t{%2, %k0|%k0, %2}"
8955   [(set_attr "type" "alu")
8956    (set_attr "mode" "SI")])
8957
8958 (define_insn "*iorsi_1_zext_imm"
8959   [(set (match_operand:DI 0 "register_operand" "=rm")
8960         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8961                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8962    (clobber (reg:CC FLAGS_REG))]
8963   "TARGET_64BIT"
8964   "or{l}\t{%2, %k0|%k0, %2}"
8965   [(set_attr "type" "alu")
8966    (set_attr "mode" "SI")])
8967
8968 (define_insn "*iorsi_2"
8969   [(set (reg FLAGS_REG)
8970         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8971                          (match_operand:SI 2 "general_operand" "rim,ri"))
8972                  (const_int 0)))
8973    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8974         (ior:SI (match_dup 1) (match_dup 2)))]
8975   "ix86_match_ccmode (insn, CCNOmode)
8976    && ix86_binary_operator_ok (IOR, SImode, operands)"
8977   "or{l}\t{%2, %0|%0, %2}"
8978   [(set_attr "type" "alu")
8979    (set_attr "mode" "SI")])
8980
8981 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8982 ;; ??? Special case for immediate operand is missing - it is tricky.
8983 (define_insn "*iorsi_2_zext"
8984   [(set (reg FLAGS_REG)
8985         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8986                          (match_operand:SI 2 "general_operand" "rim"))
8987                  (const_int 0)))
8988    (set (match_operand:DI 0 "register_operand" "=r")
8989         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8990   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8991    && ix86_binary_operator_ok (IOR, SImode, operands)"
8992   "or{l}\t{%2, %k0|%k0, %2}"
8993   [(set_attr "type" "alu")
8994    (set_attr "mode" "SI")])
8995
8996 (define_insn "*iorsi_2_zext_imm"
8997   [(set (reg FLAGS_REG)
8998         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8999                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9000                  (const_int 0)))
9001    (set (match_operand:DI 0 "register_operand" "=r")
9002         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9003   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9004    && ix86_binary_operator_ok (IOR, SImode, operands)"
9005   "or{l}\t{%2, %k0|%k0, %2}"
9006   [(set_attr "type" "alu")
9007    (set_attr "mode" "SI")])
9008
9009 (define_insn "*iorsi_3"
9010   [(set (reg FLAGS_REG)
9011         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9012                          (match_operand:SI 2 "general_operand" "rim"))
9013                  (const_int 0)))
9014    (clobber (match_scratch:SI 0 "=r"))]
9015   "ix86_match_ccmode (insn, CCNOmode)
9016    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9017   "or{l}\t{%2, %0|%0, %2}"
9018   [(set_attr "type" "alu")
9019    (set_attr "mode" "SI")])
9020
9021 (define_expand "iorhi3"
9022   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9023         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9024                 (match_operand:HI 2 "general_operand" "")))
9025    (clobber (reg:CC FLAGS_REG))]
9026   "TARGET_HIMODE_MATH"
9027   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9028
9029 (define_insn "*iorhi_1"
9030   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9031         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9032                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9033    (clobber (reg:CC FLAGS_REG))]
9034   "ix86_binary_operator_ok (IOR, HImode, operands)"
9035   "or{w}\t{%2, %0|%0, %2}"
9036   [(set_attr "type" "alu")
9037    (set_attr "mode" "HI")])
9038
9039 (define_insn "*iorhi_2"
9040   [(set (reg FLAGS_REG)
9041         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9042                          (match_operand:HI 2 "general_operand" "rim,ri"))
9043                  (const_int 0)))
9044    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9045         (ior:HI (match_dup 1) (match_dup 2)))]
9046   "ix86_match_ccmode (insn, CCNOmode)
9047    && ix86_binary_operator_ok (IOR, HImode, operands)"
9048   "or{w}\t{%2, %0|%0, %2}"
9049   [(set_attr "type" "alu")
9050    (set_attr "mode" "HI")])
9051
9052 (define_insn "*iorhi_3"
9053   [(set (reg FLAGS_REG)
9054         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9055                          (match_operand:HI 2 "general_operand" "rim"))
9056                  (const_int 0)))
9057    (clobber (match_scratch:HI 0 "=r"))]
9058   "ix86_match_ccmode (insn, CCNOmode)
9059    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9060   "or{w}\t{%2, %0|%0, %2}"
9061   [(set_attr "type" "alu")
9062    (set_attr "mode" "HI")])
9063
9064 (define_expand "iorqi3"
9065   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9066         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9067                 (match_operand:QI 2 "general_operand" "")))
9068    (clobber (reg:CC FLAGS_REG))]
9069   "TARGET_QIMODE_MATH"
9070   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9071
9072 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9073 (define_insn "*iorqi_1"
9074   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9075         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9076                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9077    (clobber (reg:CC FLAGS_REG))]
9078   "ix86_binary_operator_ok (IOR, QImode, operands)"
9079   "@
9080    or{b}\t{%2, %0|%0, %2}
9081    or{b}\t{%2, %0|%0, %2}
9082    or{l}\t{%k2, %k0|%k0, %k2}"
9083   [(set_attr "type" "alu")
9084    (set_attr "mode" "QI,QI,SI")])
9085
9086 (define_insn "*iorqi_1_slp"
9087   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9088         (ior:QI (match_dup 0)
9089                 (match_operand:QI 1 "general_operand" "qmi,qi")))
9090    (clobber (reg:CC FLAGS_REG))]
9091   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9092    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9093   "or{b}\t{%1, %0|%0, %1}"
9094   [(set_attr "type" "alu1")
9095    (set_attr "mode" "QI")])
9096
9097 (define_insn "*iorqi_2"
9098   [(set (reg FLAGS_REG)
9099         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9100                          (match_operand:QI 2 "general_operand" "qim,qi"))
9101                  (const_int 0)))
9102    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9103         (ior:QI (match_dup 1) (match_dup 2)))]
9104   "ix86_match_ccmode (insn, CCNOmode)
9105    && ix86_binary_operator_ok (IOR, QImode, operands)"
9106   "or{b}\t{%2, %0|%0, %2}"
9107   [(set_attr "type" "alu")
9108    (set_attr "mode" "QI")])
9109
9110 (define_insn "*iorqi_2_slp"
9111   [(set (reg FLAGS_REG)
9112         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9113                          (match_operand:QI 1 "general_operand" "qim,qi"))
9114                  (const_int 0)))
9115    (set (strict_low_part (match_dup 0))
9116         (ior:QI (match_dup 0) (match_dup 1)))]
9117   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9118    && ix86_match_ccmode (insn, CCNOmode)
9119    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9120   "or{b}\t{%1, %0|%0, %1}"
9121   [(set_attr "type" "alu1")
9122    (set_attr "mode" "QI")])
9123
9124 (define_insn "*iorqi_3"
9125   [(set (reg FLAGS_REG)
9126         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9127                          (match_operand:QI 2 "general_operand" "qim"))
9128                  (const_int 0)))
9129    (clobber (match_scratch:QI 0 "=q"))]
9130   "ix86_match_ccmode (insn, CCNOmode)
9131    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9132   "or{b}\t{%2, %0|%0, %2}"
9133   [(set_attr "type" "alu")
9134    (set_attr "mode" "QI")])
9135
9136 (define_insn "iorqi_ext_0"
9137   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9138                          (const_int 8)
9139                          (const_int 8))
9140         (ior:SI
9141           (zero_extract:SI
9142             (match_operand 1 "ext_register_operand" "0")
9143             (const_int 8)
9144             (const_int 8))
9145           (match_operand 2 "const_int_operand" "n")))
9146    (clobber (reg:CC FLAGS_REG))]
9147   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9148   "or{b}\t{%2, %h0|%h0, %2}"
9149   [(set_attr "type" "alu")
9150    (set_attr "length_immediate" "1")
9151    (set_attr "mode" "QI")])
9152
9153 (define_insn "*iorqi_ext_1"
9154   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9155                          (const_int 8)
9156                          (const_int 8))
9157         (ior:SI
9158           (zero_extract:SI
9159             (match_operand 1 "ext_register_operand" "0")
9160             (const_int 8)
9161             (const_int 8))
9162           (zero_extend:SI
9163             (match_operand:QI 2 "general_operand" "Qm"))))
9164    (clobber (reg:CC FLAGS_REG))]
9165   "!TARGET_64BIT
9166    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9167   "or{b}\t{%2, %h0|%h0, %2}"
9168   [(set_attr "type" "alu")
9169    (set_attr "length_immediate" "0")
9170    (set_attr "mode" "QI")])
9171
9172 (define_insn "*iorqi_ext_1_rex64"
9173   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9174                          (const_int 8)
9175                          (const_int 8))
9176         (ior:SI
9177           (zero_extract:SI
9178             (match_operand 1 "ext_register_operand" "0")
9179             (const_int 8)
9180             (const_int 8))
9181           (zero_extend:SI
9182             (match_operand 2 "ext_register_operand" "Q"))))
9183    (clobber (reg:CC FLAGS_REG))]
9184   "TARGET_64BIT
9185    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9186   "or{b}\t{%2, %h0|%h0, %2}"
9187   [(set_attr "type" "alu")
9188    (set_attr "length_immediate" "0")
9189    (set_attr "mode" "QI")])
9190
9191 (define_insn "*iorqi_ext_2"
9192   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9193                          (const_int 8)
9194                          (const_int 8))
9195         (ior:SI
9196           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9197                            (const_int 8)
9198                            (const_int 8))
9199           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9200                            (const_int 8)
9201                            (const_int 8))))
9202    (clobber (reg:CC FLAGS_REG))]
9203   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9204   "ior{b}\t{%h2, %h0|%h0, %h2}"
9205   [(set_attr "type" "alu")
9206    (set_attr "length_immediate" "0")
9207    (set_attr "mode" "QI")])
9208
9209 (define_split
9210   [(set (match_operand 0 "register_operand" "")
9211         (ior (match_operand 1 "register_operand" "")
9212              (match_operand 2 "const_int_operand" "")))
9213    (clobber (reg:CC FLAGS_REG))]
9214    "reload_completed
9215     && QI_REG_P (operands[0])
9216     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9217     && !(INTVAL (operands[2]) & ~(255 << 8))
9218     && GET_MODE (operands[0]) != QImode"
9219   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9220                    (ior:SI (zero_extract:SI (match_dup 1)
9221                                             (const_int 8) (const_int 8))
9222                            (match_dup 2)))
9223               (clobber (reg:CC FLAGS_REG))])]
9224   "operands[0] = gen_lowpart (SImode, operands[0]);
9225    operands[1] = gen_lowpart (SImode, operands[1]);
9226    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9227
9228 ;; Since OR can be encoded with sign extended immediate, this is only
9229 ;; profitable when 7th bit is set.
9230 (define_split
9231   [(set (match_operand 0 "register_operand" "")
9232         (ior (match_operand 1 "general_operand" "")
9233              (match_operand 2 "const_int_operand" "")))
9234    (clobber (reg:CC FLAGS_REG))]
9235    "reload_completed
9236     && ANY_QI_REG_P (operands[0])
9237     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9238     && !(INTVAL (operands[2]) & ~255)
9239     && (INTVAL (operands[2]) & 128)
9240     && GET_MODE (operands[0]) != QImode"
9241   [(parallel [(set (strict_low_part (match_dup 0))
9242                    (ior:QI (match_dup 1)
9243                            (match_dup 2)))
9244               (clobber (reg:CC FLAGS_REG))])]
9245   "operands[0] = gen_lowpart (QImode, operands[0]);
9246    operands[1] = gen_lowpart (QImode, operands[1]);
9247    operands[2] = gen_lowpart (QImode, operands[2]);")
9248 \f
9249 ;; Logical XOR instructions
9250
9251 ;; %%% This used to optimize known byte-wide and operations to memory.
9252 ;; If this is considered useful, it should be done with splitters.
9253
9254 (define_expand "xordi3"
9255   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9256         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9257                 (match_operand:DI 2 "x86_64_general_operand" "")))
9258    (clobber (reg:CC FLAGS_REG))]
9259   "TARGET_64BIT"
9260   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9261
9262 (define_insn "*xordi_1_rex64"
9263   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9264         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9265                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9266    (clobber (reg:CC FLAGS_REG))]
9267   "TARGET_64BIT
9268    && ix86_binary_operator_ok (XOR, DImode, operands)"
9269   "@
9270    xor{q}\t{%2, %0|%0, %2}
9271    xor{q}\t{%2, %0|%0, %2}"
9272   [(set_attr "type" "alu")
9273    (set_attr "mode" "DI,DI")])
9274
9275 (define_insn "*xordi_2_rex64"
9276   [(set (reg FLAGS_REG)
9277         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9278                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9279                  (const_int 0)))
9280    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9281         (xor:DI (match_dup 1) (match_dup 2)))]
9282   "TARGET_64BIT
9283    && ix86_match_ccmode (insn, CCNOmode)
9284    && ix86_binary_operator_ok (XOR, DImode, operands)"
9285   "@
9286    xor{q}\t{%2, %0|%0, %2}
9287    xor{q}\t{%2, %0|%0, %2}"
9288   [(set_attr "type" "alu")
9289    (set_attr "mode" "DI,DI")])
9290
9291 (define_insn "*xordi_3_rex64"
9292   [(set (reg FLAGS_REG)
9293         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9294                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9295                  (const_int 0)))
9296    (clobber (match_scratch:DI 0 "=r"))]
9297   "TARGET_64BIT
9298    && ix86_match_ccmode (insn, CCNOmode)
9299    && ix86_binary_operator_ok (XOR, DImode, operands)"
9300   "xor{q}\t{%2, %0|%0, %2}"
9301   [(set_attr "type" "alu")
9302    (set_attr "mode" "DI")])
9303
9304 (define_expand "xorsi3"
9305   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9306         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9307                 (match_operand:SI 2 "general_operand" "")))
9308    (clobber (reg:CC FLAGS_REG))]
9309   ""
9310   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9311
9312 (define_insn "*xorsi_1"
9313   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9314         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9315                 (match_operand:SI 2 "general_operand" "ri,rm")))
9316    (clobber (reg:CC FLAGS_REG))]
9317   "ix86_binary_operator_ok (XOR, SImode, operands)"
9318   "xor{l}\t{%2, %0|%0, %2}"
9319   [(set_attr "type" "alu")
9320    (set_attr "mode" "SI")])
9321
9322 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9323 ;; Add speccase for immediates
9324 (define_insn "*xorsi_1_zext"
9325   [(set (match_operand:DI 0 "register_operand" "=r")
9326         (zero_extend:DI
9327           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9328                   (match_operand:SI 2 "general_operand" "rim"))))
9329    (clobber (reg:CC FLAGS_REG))]
9330   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9331   "xor{l}\t{%2, %k0|%k0, %2}"
9332   [(set_attr "type" "alu")
9333    (set_attr "mode" "SI")])
9334
9335 (define_insn "*xorsi_1_zext_imm"
9336   [(set (match_operand:DI 0 "register_operand" "=r")
9337         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9338                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9339    (clobber (reg:CC FLAGS_REG))]
9340   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9341   "xor{l}\t{%2, %k0|%k0, %2}"
9342   [(set_attr "type" "alu")
9343    (set_attr "mode" "SI")])
9344
9345 (define_insn "*xorsi_2"
9346   [(set (reg FLAGS_REG)
9347         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9348                          (match_operand:SI 2 "general_operand" "rim,ri"))
9349                  (const_int 0)))
9350    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9351         (xor:SI (match_dup 1) (match_dup 2)))]
9352   "ix86_match_ccmode (insn, CCNOmode)
9353    && ix86_binary_operator_ok (XOR, SImode, operands)"
9354   "xor{l}\t{%2, %0|%0, %2}"
9355   [(set_attr "type" "alu")
9356    (set_attr "mode" "SI")])
9357
9358 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9359 ;; ??? Special case for immediate operand is missing - it is tricky.
9360 (define_insn "*xorsi_2_zext"
9361   [(set (reg FLAGS_REG)
9362         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9363                          (match_operand:SI 2 "general_operand" "rim"))
9364                  (const_int 0)))
9365    (set (match_operand:DI 0 "register_operand" "=r")
9366         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9367   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9368    && ix86_binary_operator_ok (XOR, SImode, operands)"
9369   "xor{l}\t{%2, %k0|%k0, %2}"
9370   [(set_attr "type" "alu")
9371    (set_attr "mode" "SI")])
9372
9373 (define_insn "*xorsi_2_zext_imm"
9374   [(set (reg FLAGS_REG)
9375         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9376                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9377                  (const_int 0)))
9378    (set (match_operand:DI 0 "register_operand" "=r")
9379         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9380   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9381    && ix86_binary_operator_ok (XOR, SImode, operands)"
9382   "xor{l}\t{%2, %k0|%k0, %2}"
9383   [(set_attr "type" "alu")
9384    (set_attr "mode" "SI")])
9385
9386 (define_insn "*xorsi_3"
9387   [(set (reg FLAGS_REG)
9388         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9389                          (match_operand:SI 2 "general_operand" "rim"))
9390                  (const_int 0)))
9391    (clobber (match_scratch:SI 0 "=r"))]
9392   "ix86_match_ccmode (insn, CCNOmode)
9393    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9394   "xor{l}\t{%2, %0|%0, %2}"
9395   [(set_attr "type" "alu")
9396    (set_attr "mode" "SI")])
9397
9398 (define_expand "xorhi3"
9399   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9400         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9401                 (match_operand:HI 2 "general_operand" "")))
9402    (clobber (reg:CC FLAGS_REG))]
9403   "TARGET_HIMODE_MATH"
9404   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9405
9406 (define_insn "*xorhi_1"
9407   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9408         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9409                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9410    (clobber (reg:CC FLAGS_REG))]
9411   "ix86_binary_operator_ok (XOR, HImode, operands)"
9412   "xor{w}\t{%2, %0|%0, %2}"
9413   [(set_attr "type" "alu")
9414    (set_attr "mode" "HI")])
9415
9416 (define_insn "*xorhi_2"
9417   [(set (reg FLAGS_REG)
9418         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9419                          (match_operand:HI 2 "general_operand" "rim,ri"))
9420                  (const_int 0)))
9421    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9422         (xor:HI (match_dup 1) (match_dup 2)))]
9423   "ix86_match_ccmode (insn, CCNOmode)
9424    && ix86_binary_operator_ok (XOR, HImode, operands)"
9425   "xor{w}\t{%2, %0|%0, %2}"
9426   [(set_attr "type" "alu")
9427    (set_attr "mode" "HI")])
9428
9429 (define_insn "*xorhi_3"
9430   [(set (reg FLAGS_REG)
9431         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9432                          (match_operand:HI 2 "general_operand" "rim"))
9433                  (const_int 0)))
9434    (clobber (match_scratch:HI 0 "=r"))]
9435   "ix86_match_ccmode (insn, CCNOmode)
9436    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9437   "xor{w}\t{%2, %0|%0, %2}"
9438   [(set_attr "type" "alu")
9439    (set_attr "mode" "HI")])
9440
9441 (define_expand "xorqi3"
9442   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9443         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9444                 (match_operand:QI 2 "general_operand" "")))
9445    (clobber (reg:CC FLAGS_REG))]
9446   "TARGET_QIMODE_MATH"
9447   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9448
9449 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9450 (define_insn "*xorqi_1"
9451   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9452         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9453                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9454    (clobber (reg:CC FLAGS_REG))]
9455   "ix86_binary_operator_ok (XOR, QImode, operands)"
9456   "@
9457    xor{b}\t{%2, %0|%0, %2}
9458    xor{b}\t{%2, %0|%0, %2}
9459    xor{l}\t{%k2, %k0|%k0, %k2}"
9460   [(set_attr "type" "alu")
9461    (set_attr "mode" "QI,QI,SI")])
9462
9463 (define_insn "*xorqi_1_slp"
9464   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9465         (xor:QI (match_dup 0)
9466                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9467    (clobber (reg:CC FLAGS_REG))]
9468   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9469    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9470   "xor{b}\t{%1, %0|%0, %1}"
9471   [(set_attr "type" "alu1")
9472    (set_attr "mode" "QI")])
9473
9474 (define_insn "xorqi_ext_0"
9475   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9476                          (const_int 8)
9477                          (const_int 8))
9478         (xor:SI
9479           (zero_extract:SI
9480             (match_operand 1 "ext_register_operand" "0")
9481             (const_int 8)
9482             (const_int 8))
9483           (match_operand 2 "const_int_operand" "n")))
9484    (clobber (reg:CC FLAGS_REG))]
9485   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9486   "xor{b}\t{%2, %h0|%h0, %2}"
9487   [(set_attr "type" "alu")
9488    (set_attr "length_immediate" "1")
9489    (set_attr "mode" "QI")])
9490
9491 (define_insn "*xorqi_ext_1"
9492   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9493                          (const_int 8)
9494                          (const_int 8))
9495         (xor:SI
9496           (zero_extract:SI
9497             (match_operand 1 "ext_register_operand" "0")
9498             (const_int 8)
9499             (const_int 8))
9500           (zero_extend:SI
9501             (match_operand:QI 2 "general_operand" "Qm"))))
9502    (clobber (reg:CC FLAGS_REG))]
9503   "!TARGET_64BIT
9504    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9505   "xor{b}\t{%2, %h0|%h0, %2}"
9506   [(set_attr "type" "alu")
9507    (set_attr "length_immediate" "0")
9508    (set_attr "mode" "QI")])
9509
9510 (define_insn "*xorqi_ext_1_rex64"
9511   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9512                          (const_int 8)
9513                          (const_int 8))
9514         (xor:SI
9515           (zero_extract:SI
9516             (match_operand 1 "ext_register_operand" "0")
9517             (const_int 8)
9518             (const_int 8))
9519           (zero_extend:SI
9520             (match_operand 2 "ext_register_operand" "Q"))))
9521    (clobber (reg:CC FLAGS_REG))]
9522   "TARGET_64BIT
9523    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9524   "xor{b}\t{%2, %h0|%h0, %2}"
9525   [(set_attr "type" "alu")
9526    (set_attr "length_immediate" "0")
9527    (set_attr "mode" "QI")])
9528
9529 (define_insn "*xorqi_ext_2"
9530   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9531                          (const_int 8)
9532                          (const_int 8))
9533         (xor:SI
9534           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9535                            (const_int 8)
9536                            (const_int 8))
9537           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9538                            (const_int 8)
9539                            (const_int 8))))
9540    (clobber (reg:CC FLAGS_REG))]
9541   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9542   "xor{b}\t{%h2, %h0|%h0, %h2}"
9543   [(set_attr "type" "alu")
9544    (set_attr "length_immediate" "0")
9545    (set_attr "mode" "QI")])
9546
9547 (define_insn "*xorqi_cc_1"
9548   [(set (reg FLAGS_REG)
9549         (compare
9550           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9551                   (match_operand:QI 2 "general_operand" "qim,qi"))
9552           (const_int 0)))
9553    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9554         (xor:QI (match_dup 1) (match_dup 2)))]
9555   "ix86_match_ccmode (insn, CCNOmode)
9556    && ix86_binary_operator_ok (XOR, QImode, operands)"
9557   "xor{b}\t{%2, %0|%0, %2}"
9558   [(set_attr "type" "alu")
9559    (set_attr "mode" "QI")])
9560
9561 (define_insn "*xorqi_2_slp"
9562   [(set (reg FLAGS_REG)
9563         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9564                          (match_operand:QI 1 "general_operand" "qim,qi"))
9565                  (const_int 0)))
9566    (set (strict_low_part (match_dup 0))
9567         (xor:QI (match_dup 0) (match_dup 1)))]
9568   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9569    && ix86_match_ccmode (insn, CCNOmode)
9570    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9571   "xor{b}\t{%1, %0|%0, %1}"
9572   [(set_attr "type" "alu1")
9573    (set_attr "mode" "QI")])
9574
9575 (define_insn "*xorqi_cc_2"
9576   [(set (reg FLAGS_REG)
9577         (compare
9578           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9579                   (match_operand:QI 2 "general_operand" "qim"))
9580           (const_int 0)))
9581    (clobber (match_scratch:QI 0 "=q"))]
9582   "ix86_match_ccmode (insn, CCNOmode)
9583    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9584   "xor{b}\t{%2, %0|%0, %2}"
9585   [(set_attr "type" "alu")
9586    (set_attr "mode" "QI")])
9587
9588 (define_insn "*xorqi_cc_ext_1"
9589   [(set (reg FLAGS_REG)
9590         (compare
9591           (xor:SI
9592             (zero_extract:SI
9593               (match_operand 1 "ext_register_operand" "0")
9594               (const_int 8)
9595               (const_int 8))
9596             (match_operand:QI 2 "general_operand" "qmn"))
9597           (const_int 0)))
9598    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9599                          (const_int 8)
9600                          (const_int 8))
9601         (xor:SI
9602           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9603           (match_dup 2)))]
9604   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9605   "xor{b}\t{%2, %h0|%h0, %2}"
9606   [(set_attr "type" "alu")
9607    (set_attr "mode" "QI")])
9608
9609 (define_insn "*xorqi_cc_ext_1_rex64"
9610   [(set (reg FLAGS_REG)
9611         (compare
9612           (xor:SI
9613             (zero_extract:SI
9614               (match_operand 1 "ext_register_operand" "0")
9615               (const_int 8)
9616               (const_int 8))
9617             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9618           (const_int 0)))
9619    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9620                          (const_int 8)
9621                          (const_int 8))
9622         (xor:SI
9623           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9624           (match_dup 2)))]
9625   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9626   "xor{b}\t{%2, %h0|%h0, %2}"
9627   [(set_attr "type" "alu")
9628    (set_attr "mode" "QI")])
9629
9630 (define_expand "xorqi_cc_ext_1"
9631   [(parallel [
9632      (set (reg:CCNO FLAGS_REG)
9633           (compare:CCNO
9634             (xor:SI
9635               (zero_extract:SI
9636                 (match_operand 1 "ext_register_operand" "")
9637                 (const_int 8)
9638                 (const_int 8))
9639               (match_operand:QI 2 "general_operand" ""))
9640             (const_int 0)))
9641      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9642                            (const_int 8)
9643                            (const_int 8))
9644           (xor:SI
9645             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9646             (match_dup 2)))])]
9647   ""
9648   "")
9649
9650 (define_split
9651   [(set (match_operand 0 "register_operand" "")
9652         (xor (match_operand 1 "register_operand" "")
9653              (match_operand 2 "const_int_operand" "")))
9654    (clobber (reg:CC FLAGS_REG))]
9655    "reload_completed
9656     && QI_REG_P (operands[0])
9657     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9658     && !(INTVAL (operands[2]) & ~(255 << 8))
9659     && GET_MODE (operands[0]) != QImode"
9660   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9661                    (xor:SI (zero_extract:SI (match_dup 1)
9662                                             (const_int 8) (const_int 8))
9663                            (match_dup 2)))
9664               (clobber (reg:CC FLAGS_REG))])]
9665   "operands[0] = gen_lowpart (SImode, operands[0]);
9666    operands[1] = gen_lowpart (SImode, operands[1]);
9667    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9668
9669 ;; Since XOR can be encoded with sign extended immediate, this is only
9670 ;; profitable when 7th bit is set.
9671 (define_split
9672   [(set (match_operand 0 "register_operand" "")
9673         (xor (match_operand 1 "general_operand" "")
9674              (match_operand 2 "const_int_operand" "")))
9675    (clobber (reg:CC FLAGS_REG))]
9676    "reload_completed
9677     && ANY_QI_REG_P (operands[0])
9678     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9679     && !(INTVAL (operands[2]) & ~255)
9680     && (INTVAL (operands[2]) & 128)
9681     && GET_MODE (operands[0]) != QImode"
9682   [(parallel [(set (strict_low_part (match_dup 0))
9683                    (xor:QI (match_dup 1)
9684                            (match_dup 2)))
9685               (clobber (reg:CC FLAGS_REG))])]
9686   "operands[0] = gen_lowpart (QImode, operands[0]);
9687    operands[1] = gen_lowpart (QImode, operands[1]);
9688    operands[2] = gen_lowpart (QImode, operands[2]);")
9689 \f
9690 ;; Negation instructions
9691
9692 (define_expand "negti2"
9693   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9694                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9695               (clobber (reg:CC FLAGS_REG))])]
9696   "TARGET_64BIT"
9697   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9698
9699 (define_insn "*negti2_1"
9700   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9701         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9702    (clobber (reg:CC FLAGS_REG))]
9703   "TARGET_64BIT
9704    && ix86_unary_operator_ok (NEG, TImode, operands)"
9705   "#")
9706
9707 (define_split
9708   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9709         (neg:TI (match_operand:TI 1 "general_operand" "")))
9710    (clobber (reg:CC FLAGS_REG))]
9711   "TARGET_64BIT && reload_completed"
9712   [(parallel
9713     [(set (reg:CCZ FLAGS_REG)
9714           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9715      (set (match_dup 0) (neg:DI (match_dup 2)))])
9716    (parallel
9717     [(set (match_dup 1)
9718           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9719                             (match_dup 3))
9720                    (const_int 0)))
9721      (clobber (reg:CC FLAGS_REG))])
9722    (parallel
9723     [(set (match_dup 1)
9724           (neg:DI (match_dup 1)))
9725      (clobber (reg:CC FLAGS_REG))])]
9726   "split_ti (operands+1, 1, operands+2, operands+3);
9727    split_ti (operands+0, 1, operands+0, operands+1);")
9728
9729 (define_expand "negdi2"
9730   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9731                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9732               (clobber (reg:CC FLAGS_REG))])]
9733   ""
9734   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9735
9736 (define_insn "*negdi2_1"
9737   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9738         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9739    (clobber (reg:CC FLAGS_REG))]
9740   "!TARGET_64BIT
9741    && ix86_unary_operator_ok (NEG, DImode, operands)"
9742   "#")
9743
9744 (define_split
9745   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9746         (neg:DI (match_operand:DI 1 "general_operand" "")))
9747    (clobber (reg:CC FLAGS_REG))]
9748   "!TARGET_64BIT && reload_completed"
9749   [(parallel
9750     [(set (reg:CCZ FLAGS_REG)
9751           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9752      (set (match_dup 0) (neg:SI (match_dup 2)))])
9753    (parallel
9754     [(set (match_dup 1)
9755           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9756                             (match_dup 3))
9757                    (const_int 0)))
9758      (clobber (reg:CC FLAGS_REG))])
9759    (parallel
9760     [(set (match_dup 1)
9761           (neg:SI (match_dup 1)))
9762      (clobber (reg:CC FLAGS_REG))])]
9763   "split_di (operands+1, 1, operands+2, operands+3);
9764    split_di (operands+0, 1, operands+0, operands+1);")
9765
9766 (define_insn "*negdi2_1_rex64"
9767   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9768         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9769    (clobber (reg:CC FLAGS_REG))]
9770   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9771   "neg{q}\t%0"
9772   [(set_attr "type" "negnot")
9773    (set_attr "mode" "DI")])
9774
9775 ;; The problem with neg is that it does not perform (compare x 0),
9776 ;; it really performs (compare 0 x), which leaves us with the zero
9777 ;; flag being the only useful item.
9778
9779 (define_insn "*negdi2_cmpz_rex64"
9780   [(set (reg:CCZ FLAGS_REG)
9781         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9782                      (const_int 0)))
9783    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9784         (neg:DI (match_dup 1)))]
9785   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9786   "neg{q}\t%0"
9787   [(set_attr "type" "negnot")
9788    (set_attr "mode" "DI")])
9789
9790
9791 (define_expand "negsi2"
9792   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9793                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9794               (clobber (reg:CC FLAGS_REG))])]
9795   ""
9796   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9797
9798 (define_insn "*negsi2_1"
9799   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9800         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9801    (clobber (reg:CC FLAGS_REG))]
9802   "ix86_unary_operator_ok (NEG, SImode, operands)"
9803   "neg{l}\t%0"
9804   [(set_attr "type" "negnot")
9805    (set_attr "mode" "SI")])
9806
9807 ;; Combine is quite creative about this pattern.
9808 (define_insn "*negsi2_1_zext"
9809   [(set (match_operand:DI 0 "register_operand" "=r")
9810         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9811                                         (const_int 32)))
9812                      (const_int 32)))
9813    (clobber (reg:CC FLAGS_REG))]
9814   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9815   "neg{l}\t%k0"
9816   [(set_attr "type" "negnot")
9817    (set_attr "mode" "SI")])
9818
9819 ;; The problem with neg is that it does not perform (compare x 0),
9820 ;; it really performs (compare 0 x), which leaves us with the zero
9821 ;; flag being the only useful item.
9822
9823 (define_insn "*negsi2_cmpz"
9824   [(set (reg:CCZ FLAGS_REG)
9825         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9826                      (const_int 0)))
9827    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9828         (neg:SI (match_dup 1)))]
9829   "ix86_unary_operator_ok (NEG, SImode, operands)"
9830   "neg{l}\t%0"
9831   [(set_attr "type" "negnot")
9832    (set_attr "mode" "SI")])
9833
9834 (define_insn "*negsi2_cmpz_zext"
9835   [(set (reg:CCZ FLAGS_REG)
9836         (compare:CCZ (lshiftrt:DI
9837                        (neg:DI (ashift:DI
9838                                  (match_operand:DI 1 "register_operand" "0")
9839                                  (const_int 32)))
9840                        (const_int 32))
9841                      (const_int 0)))
9842    (set (match_operand:DI 0 "register_operand" "=r")
9843         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9844                                         (const_int 32)))
9845                      (const_int 32)))]
9846   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9847   "neg{l}\t%k0"
9848   [(set_attr "type" "negnot")
9849    (set_attr "mode" "SI")])
9850
9851 (define_expand "neghi2"
9852   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9853                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9854               (clobber (reg:CC FLAGS_REG))])]
9855   "TARGET_HIMODE_MATH"
9856   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9857
9858 (define_insn "*neghi2_1"
9859   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9860         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9861    (clobber (reg:CC FLAGS_REG))]
9862   "ix86_unary_operator_ok (NEG, HImode, operands)"
9863   "neg{w}\t%0"
9864   [(set_attr "type" "negnot")
9865    (set_attr "mode" "HI")])
9866
9867 (define_insn "*neghi2_cmpz"
9868   [(set (reg:CCZ FLAGS_REG)
9869         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9870                      (const_int 0)))
9871    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9872         (neg:HI (match_dup 1)))]
9873   "ix86_unary_operator_ok (NEG, HImode, operands)"
9874   "neg{w}\t%0"
9875   [(set_attr "type" "negnot")
9876    (set_attr "mode" "HI")])
9877
9878 (define_expand "negqi2"
9879   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9880                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9881               (clobber (reg:CC FLAGS_REG))])]
9882   "TARGET_QIMODE_MATH"
9883   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9884
9885 (define_insn "*negqi2_1"
9886   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9887         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9888    (clobber (reg:CC FLAGS_REG))]
9889   "ix86_unary_operator_ok (NEG, QImode, operands)"
9890   "neg{b}\t%0"
9891   [(set_attr "type" "negnot")
9892    (set_attr "mode" "QI")])
9893
9894 (define_insn "*negqi2_cmpz"
9895   [(set (reg:CCZ FLAGS_REG)
9896         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9897                      (const_int 0)))
9898    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9899         (neg:QI (match_dup 1)))]
9900   "ix86_unary_operator_ok (NEG, QImode, operands)"
9901   "neg{b}\t%0"
9902   [(set_attr "type" "negnot")
9903    (set_attr "mode" "QI")])
9904
9905 ;; Changing of sign for FP values is doable using integer unit too.
9906
9907 (define_expand "negsf2"
9908   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9909         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9910   "TARGET_80387 || TARGET_SSE_MATH"
9911   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9912
9913 (define_expand "abssf2"
9914   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9915         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9916   "TARGET_80387 || TARGET_SSE_MATH"
9917   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9918
9919 (define_insn "*absnegsf2_mixed"
9920   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9921         (match_operator:SF 3 "absneg_operator"
9922           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9923    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9924    (clobber (reg:CC FLAGS_REG))]
9925   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9926    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9927   "#")
9928
9929 (define_insn "*absnegsf2_sse"
9930   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9931         (match_operator:SF 3 "absneg_operator"
9932           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9933    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9934    (clobber (reg:CC FLAGS_REG))]
9935   "TARGET_SSE_MATH
9936    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9937   "#")
9938
9939 (define_insn "*absnegsf2_i387"
9940   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9941         (match_operator:SF 3 "absneg_operator"
9942           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9943    (use (match_operand 2 "" ""))
9944    (clobber (reg:CC FLAGS_REG))]
9945   "TARGET_80387 && !TARGET_SSE_MATH
9946    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9947   "#")
9948
9949 (define_expand "copysignsf3"
9950   [(match_operand:SF 0 "register_operand" "")
9951    (match_operand:SF 1 "nonmemory_operand" "")
9952    (match_operand:SF 2 "register_operand" "")]
9953   "TARGET_SSE_MATH"
9954 {
9955   ix86_expand_copysign (operands);
9956   DONE;
9957 })
9958
9959 (define_insn_and_split "copysignsf3_const"
9960   [(set (match_operand:SF 0 "register_operand"          "=x")
9961         (unspec:SF
9962           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9963            (match_operand:SF 2 "register_operand"       "0")
9964            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9965           UNSPEC_COPYSIGN))]
9966   "TARGET_SSE_MATH"
9967   "#"
9968   "&& reload_completed"
9969   [(const_int 0)]
9970 {
9971   ix86_split_copysign_const (operands);
9972   DONE;
9973 })
9974
9975 (define_insn "copysignsf3_var"
9976   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9977         (unspec:SF
9978           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9979            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9980            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9981            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9982           UNSPEC_COPYSIGN))
9983    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9984   "TARGET_SSE_MATH"
9985   "#")
9986
9987 (define_split
9988   [(set (match_operand:SF 0 "register_operand" "")
9989         (unspec:SF
9990           [(match_operand:SF 2 "register_operand" "")
9991            (match_operand:SF 3 "register_operand" "")
9992            (match_operand:V4SF 4 "" "")
9993            (match_operand:V4SF 5 "" "")]
9994           UNSPEC_COPYSIGN))
9995    (clobber (match_scratch:V4SF 1 ""))]
9996   "TARGET_SSE_MATH && reload_completed"
9997   [(const_int 0)]
9998 {
9999   ix86_split_copysign_var (operands);
10000   DONE;
10001 })
10002
10003 (define_expand "negdf2"
10004   [(set (match_operand:DF 0 "nonimmediate_operand" "")
10005         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
10006   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
10007   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
10008
10009 (define_expand "absdf2"
10010   [(set (match_operand:DF 0 "nonimmediate_operand" "")
10011         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
10012   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
10013   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
10014
10015 (define_insn "*absnegdf2_mixed"
10016   [(set (match_operand:DF 0 "nonimmediate_operand"    "=x,x,f,rm")
10017         (match_operator:DF 3 "absneg_operator"
10018           [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0,0")]))
10019    (use (match_operand:V2DF 2 "nonimmediate_operand"  "xm,0,X,X"))
10020    (clobber (reg:CC FLAGS_REG))]
10021   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
10022    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10023   "#")
10024
10025 (define_insn "*absnegdf2_sse"
10026   [(set (match_operand:DF 0 "nonimmediate_operand"    "=x,x,rm")
10027         (match_operator:DF 3 "absneg_operator"
10028           [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0 ")]))
10029    (use (match_operand:V2DF 2 "nonimmediate_operand"  "xm,0,X "))
10030    (clobber (reg:CC FLAGS_REG))]
10031   "TARGET_SSE2 && TARGET_SSE_MATH
10032    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10033   "#")
10034
10035 (define_insn "*absnegdf2_i387"
10036   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
10037         (match_operator:DF 3 "absneg_operator"
10038           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
10039    (use (match_operand 2 "" ""))
10040    (clobber (reg:CC FLAGS_REG))]
10041   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
10042    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10043   "#")
10044
10045 (define_expand "copysigndf3"
10046   [(match_operand:DF 0 "register_operand" "")
10047    (match_operand:DF 1 "nonmemory_operand" "")
10048    (match_operand:DF 2 "register_operand" "")]
10049   "TARGET_SSE2 && TARGET_SSE_MATH"
10050 {
10051   ix86_expand_copysign (operands);
10052   DONE;
10053 })
10054
10055 (define_insn_and_split "copysigndf3_const"
10056   [(set (match_operand:DF 0 "register_operand"          "=x")
10057         (unspec:DF
10058           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
10059            (match_operand:DF 2 "register_operand"       "0")
10060            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
10061           UNSPEC_COPYSIGN))]
10062   "TARGET_SSE2 && TARGET_SSE_MATH"
10063   "#"
10064   "&& reload_completed"
10065   [(const_int 0)]
10066 {
10067   ix86_split_copysign_const (operands);
10068   DONE;
10069 })
10070
10071 (define_insn "copysigndf3_var"
10072   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
10073         (unspec:DF
10074           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
10075            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
10076            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
10077            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
10078           UNSPEC_COPYSIGN))
10079    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
10080   "TARGET_SSE2 && TARGET_SSE_MATH"
10081   "#")
10082
10083 (define_split
10084   [(set (match_operand:DF 0 "register_operand" "")
10085         (unspec:DF
10086           [(match_operand:DF 2 "register_operand" "")
10087            (match_operand:DF 3 "register_operand" "")
10088            (match_operand:V2DF 4 "" "")
10089            (match_operand:V2DF 5 "" "")]
10090           UNSPEC_COPYSIGN))
10091    (clobber (match_scratch:V2DF 1 ""))]
10092   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
10093   [(const_int 0)]
10094 {
10095   ix86_split_copysign_var (operands);
10096   DONE;
10097 })
10098
10099 (define_expand "negxf2"
10100   [(set (match_operand:XF 0 "nonimmediate_operand" "")
10101         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10102   "TARGET_80387"
10103   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
10104
10105 (define_expand "absxf2"
10106   [(set (match_operand:XF 0 "nonimmediate_operand" "")
10107         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10108   "TARGET_80387"
10109   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
10110
10111 (define_insn "*absnegxf2_i387"
10112   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
10113         (match_operator:XF 3 "absneg_operator"
10114           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
10115    (use (match_operand 2 "" ""))
10116    (clobber (reg:CC FLAGS_REG))]
10117   "TARGET_80387
10118    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
10119   "#")
10120
10121 ;; Splitters for fp abs and neg.
10122
10123 (define_split
10124   [(set (match_operand 0 "fp_register_operand" "")
10125         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10126    (use (match_operand 2 "" ""))
10127    (clobber (reg:CC FLAGS_REG))]
10128   "reload_completed"
10129   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10130
10131 (define_split
10132   [(set (match_operand 0 "register_operand" "")
10133         (match_operator 3 "absneg_operator"
10134           [(match_operand 1 "register_operand" "")]))
10135    (use (match_operand 2 "nonimmediate_operand" ""))
10136    (clobber (reg:CC FLAGS_REG))]
10137   "reload_completed && SSE_REG_P (operands[0])"
10138   [(set (match_dup 0) (match_dup 3))]
10139 {
10140   enum machine_mode mode = GET_MODE (operands[0]);
10141   enum machine_mode vmode = GET_MODE (operands[2]);
10142   rtx tmp;
10143
10144   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10145   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10146   if (operands_match_p (operands[0], operands[2]))
10147     {
10148       tmp = operands[1];
10149       operands[1] = operands[2];
10150       operands[2] = tmp;
10151     }
10152   if (GET_CODE (operands[3]) == ABS)
10153     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10154   else
10155     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10156   operands[3] = tmp;
10157 })
10158
10159 (define_split
10160   [(set (match_operand:SF 0 "register_operand" "")
10161         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10162    (use (match_operand:V4SF 2 "" ""))
10163    (clobber (reg:CC FLAGS_REG))]
10164   "reload_completed"
10165   [(parallel [(set (match_dup 0) (match_dup 1))
10166               (clobber (reg:CC FLAGS_REG))])]
10167 {
10168   rtx tmp;
10169   operands[0] = gen_lowpart (SImode, operands[0]);
10170   if (GET_CODE (operands[1]) == ABS)
10171     {
10172       tmp = gen_int_mode (0x7fffffff, SImode);
10173       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10174     }
10175   else
10176     {
10177       tmp = gen_int_mode (0x80000000, SImode);
10178       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10179     }
10180   operands[1] = tmp;
10181 })
10182
10183 (define_split
10184   [(set (match_operand:DF 0 "register_operand" "")
10185         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10186    (use (match_operand 2 "" ""))
10187    (clobber (reg:CC FLAGS_REG))]
10188   "reload_completed"
10189   [(parallel [(set (match_dup 0) (match_dup 1))
10190               (clobber (reg:CC FLAGS_REG))])]
10191 {
10192   rtx tmp;
10193   if (TARGET_64BIT)
10194     {
10195       tmp = gen_lowpart (DImode, operands[0]);
10196       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10197       operands[0] = tmp;
10198
10199       if (GET_CODE (operands[1]) == ABS)
10200         tmp = const0_rtx;
10201       else
10202         tmp = gen_rtx_NOT (DImode, tmp);
10203     }
10204   else
10205     {
10206       operands[0] = gen_highpart (SImode, operands[0]);
10207       if (GET_CODE (operands[1]) == ABS)
10208         {
10209           tmp = gen_int_mode (0x7fffffff, SImode);
10210           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10211         }
10212       else
10213         {
10214           tmp = gen_int_mode (0x80000000, SImode);
10215           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10216         }
10217     }
10218   operands[1] = tmp;
10219 })
10220
10221 (define_split
10222   [(set (match_operand:XF 0 "register_operand" "")
10223         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10224    (use (match_operand 2 "" ""))
10225    (clobber (reg:CC FLAGS_REG))]
10226   "reload_completed"
10227   [(parallel [(set (match_dup 0) (match_dup 1))
10228               (clobber (reg:CC FLAGS_REG))])]
10229 {
10230   rtx tmp;
10231   operands[0] = gen_rtx_REG (SImode,
10232                              true_regnum (operands[0])
10233                              + (TARGET_64BIT ? 1 : 2));
10234   if (GET_CODE (operands[1]) == ABS)
10235     {
10236       tmp = GEN_INT (0x7fff);
10237       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10238     }
10239   else
10240     {
10241       tmp = GEN_INT (0x8000);
10242       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10243     }
10244   operands[1] = tmp;
10245 })
10246
10247 (define_split
10248   [(set (match_operand 0 "memory_operand" "")
10249         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10250    (use (match_operand 2 "" ""))
10251    (clobber (reg:CC FLAGS_REG))]
10252   "reload_completed"
10253   [(parallel [(set (match_dup 0) (match_dup 1))
10254               (clobber (reg:CC FLAGS_REG))])]
10255 {
10256   enum machine_mode mode = GET_MODE (operands[0]);
10257   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
10258   rtx tmp;
10259
10260   operands[0] = adjust_address (operands[0], QImode, size - 1);
10261   if (GET_CODE (operands[1]) == ABS)
10262     {
10263       tmp = gen_int_mode (0x7f, QImode);
10264       tmp = gen_rtx_AND (QImode, operands[0], tmp);
10265     }
10266   else
10267     {
10268       tmp = gen_int_mode (0x80, QImode);
10269       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
10270     }
10271   operands[1] = tmp;
10272 })
10273
10274 ;; Conditionalize these after reload. If they match before reload, we
10275 ;; lose the clobber and ability to use integer instructions.
10276
10277 (define_insn "*negsf2_1"
10278   [(set (match_operand:SF 0 "register_operand" "=f")
10279         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10280   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10281   "fchs"
10282   [(set_attr "type" "fsgn")
10283    (set_attr "mode" "SF")])
10284
10285 (define_insn "*negdf2_1"
10286   [(set (match_operand:DF 0 "register_operand" "=f")
10287         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10288   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10289   "fchs"
10290   [(set_attr "type" "fsgn")
10291    (set_attr "mode" "DF")])
10292
10293 (define_insn "*negxf2_1"
10294   [(set (match_operand:XF 0 "register_operand" "=f")
10295         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10296   "TARGET_80387"
10297   "fchs"
10298   [(set_attr "type" "fsgn")
10299    (set_attr "mode" "XF")])
10300
10301 (define_insn "*abssf2_1"
10302   [(set (match_operand:SF 0 "register_operand" "=f")
10303         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10304   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10305   "fabs"
10306   [(set_attr "type" "fsgn")
10307    (set_attr "mode" "SF")])
10308
10309 (define_insn "*absdf2_1"
10310   [(set (match_operand:DF 0 "register_operand" "=f")
10311         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10312   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10313   "fabs"
10314   [(set_attr "type" "fsgn")
10315    (set_attr "mode" "DF")])
10316
10317 (define_insn "*absxf2_1"
10318   [(set (match_operand:XF 0 "register_operand" "=f")
10319         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10320   "TARGET_80387"
10321   "fabs"
10322   [(set_attr "type" "fsgn")
10323    (set_attr "mode" "DF")])
10324
10325 (define_insn "*negextendsfdf2"
10326   [(set (match_operand:DF 0 "register_operand" "=f")
10327         (neg:DF (float_extend:DF
10328                   (match_operand:SF 1 "register_operand" "0"))))]
10329   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10330   "fchs"
10331   [(set_attr "type" "fsgn")
10332    (set_attr "mode" "DF")])
10333
10334 (define_insn "*negextenddfxf2"
10335   [(set (match_operand:XF 0 "register_operand" "=f")
10336         (neg:XF (float_extend:XF
10337                   (match_operand:DF 1 "register_operand" "0"))))]
10338   "TARGET_80387"
10339   "fchs"
10340   [(set_attr "type" "fsgn")
10341    (set_attr "mode" "XF")])
10342
10343 (define_insn "*negextendsfxf2"
10344   [(set (match_operand:XF 0 "register_operand" "=f")
10345         (neg:XF (float_extend:XF
10346                   (match_operand:SF 1 "register_operand" "0"))))]
10347   "TARGET_80387"
10348   "fchs"
10349   [(set_attr "type" "fsgn")
10350    (set_attr "mode" "XF")])
10351
10352 (define_insn "*absextendsfdf2"
10353   [(set (match_operand:DF 0 "register_operand" "=f")
10354         (abs:DF (float_extend:DF
10355                   (match_operand:SF 1 "register_operand" "0"))))]
10356   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10357   "fabs"
10358   [(set_attr "type" "fsgn")
10359    (set_attr "mode" "DF")])
10360
10361 (define_insn "*absextenddfxf2"
10362   [(set (match_operand:XF 0 "register_operand" "=f")
10363         (abs:XF (float_extend:XF
10364           (match_operand:DF 1 "register_operand" "0"))))]
10365   "TARGET_80387"
10366   "fabs"
10367   [(set_attr "type" "fsgn")
10368    (set_attr "mode" "XF")])
10369
10370 (define_insn "*absextendsfxf2"
10371   [(set (match_operand:XF 0 "register_operand" "=f")
10372         (abs:XF (float_extend:XF
10373           (match_operand:SF 1 "register_operand" "0"))))]
10374   "TARGET_80387"
10375   "fabs"
10376   [(set_attr "type" "fsgn")
10377    (set_attr "mode" "XF")])
10378 \f
10379 ;; One complement instructions
10380
10381 (define_expand "one_cmpldi2"
10382   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10383         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10384   "TARGET_64BIT"
10385   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10386
10387 (define_insn "*one_cmpldi2_1_rex64"
10388   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10389         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10390   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10391   "not{q}\t%0"
10392   [(set_attr "type" "negnot")
10393    (set_attr "mode" "DI")])
10394
10395 (define_insn "*one_cmpldi2_2_rex64"
10396   [(set (reg FLAGS_REG)
10397         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10398                  (const_int 0)))
10399    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10400         (not:DI (match_dup 1)))]
10401   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10402    && ix86_unary_operator_ok (NOT, DImode, operands)"
10403   "#"
10404   [(set_attr "type" "alu1")
10405    (set_attr "mode" "DI")])
10406
10407 (define_split
10408   [(set (match_operand 0 "flags_reg_operand" "")
10409         (match_operator 2 "compare_operator"
10410           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10411            (const_int 0)]))
10412    (set (match_operand:DI 1 "nonimmediate_operand" "")
10413         (not:DI (match_dup 3)))]
10414   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10415   [(parallel [(set (match_dup 0)
10416                    (match_op_dup 2
10417                      [(xor:DI (match_dup 3) (const_int -1))
10418                       (const_int 0)]))
10419               (set (match_dup 1)
10420                    (xor:DI (match_dup 3) (const_int -1)))])]
10421   "")
10422
10423 (define_expand "one_cmplsi2"
10424   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10425         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10426   ""
10427   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10428
10429 (define_insn "*one_cmplsi2_1"
10430   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10431         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10432   "ix86_unary_operator_ok (NOT, SImode, operands)"
10433   "not{l}\t%0"
10434   [(set_attr "type" "negnot")
10435    (set_attr "mode" "SI")])
10436
10437 ;; ??? Currently never generated - xor is used instead.
10438 (define_insn "*one_cmplsi2_1_zext"
10439   [(set (match_operand:DI 0 "register_operand" "=r")
10440         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10441   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10442   "not{l}\t%k0"
10443   [(set_attr "type" "negnot")
10444    (set_attr "mode" "SI")])
10445
10446 (define_insn "*one_cmplsi2_2"
10447   [(set (reg FLAGS_REG)
10448         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10449                  (const_int 0)))
10450    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10451         (not:SI (match_dup 1)))]
10452   "ix86_match_ccmode (insn, CCNOmode)
10453    && ix86_unary_operator_ok (NOT, SImode, operands)"
10454   "#"
10455   [(set_attr "type" "alu1")
10456    (set_attr "mode" "SI")])
10457
10458 (define_split
10459   [(set (match_operand 0 "flags_reg_operand" "")
10460         (match_operator 2 "compare_operator"
10461           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10462            (const_int 0)]))
10463    (set (match_operand:SI 1 "nonimmediate_operand" "")
10464         (not:SI (match_dup 3)))]
10465   "ix86_match_ccmode (insn, CCNOmode)"
10466   [(parallel [(set (match_dup 0)
10467                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10468                                     (const_int 0)]))
10469               (set (match_dup 1)
10470                    (xor:SI (match_dup 3) (const_int -1)))])]
10471   "")
10472
10473 ;; ??? Currently never generated - xor is used instead.
10474 (define_insn "*one_cmplsi2_2_zext"
10475   [(set (reg FLAGS_REG)
10476         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10477                  (const_int 0)))
10478    (set (match_operand:DI 0 "register_operand" "=r")
10479         (zero_extend:DI (not:SI (match_dup 1))))]
10480   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10481    && ix86_unary_operator_ok (NOT, SImode, operands)"
10482   "#"
10483   [(set_attr "type" "alu1")
10484    (set_attr "mode" "SI")])
10485
10486 (define_split
10487   [(set (match_operand 0 "flags_reg_operand" "")
10488         (match_operator 2 "compare_operator"
10489           [(not:SI (match_operand:SI 3 "register_operand" ""))
10490            (const_int 0)]))
10491    (set (match_operand:DI 1 "register_operand" "")
10492         (zero_extend:DI (not:SI (match_dup 3))))]
10493   "ix86_match_ccmode (insn, CCNOmode)"
10494   [(parallel [(set (match_dup 0)
10495                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10496                                     (const_int 0)]))
10497               (set (match_dup 1)
10498                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10499   "")
10500
10501 (define_expand "one_cmplhi2"
10502   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10503         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10504   "TARGET_HIMODE_MATH"
10505   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10506
10507 (define_insn "*one_cmplhi2_1"
10508   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10509         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10510   "ix86_unary_operator_ok (NOT, HImode, operands)"
10511   "not{w}\t%0"
10512   [(set_attr "type" "negnot")
10513    (set_attr "mode" "HI")])
10514
10515 (define_insn "*one_cmplhi2_2"
10516   [(set (reg FLAGS_REG)
10517         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10518                  (const_int 0)))
10519    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10520         (not:HI (match_dup 1)))]
10521   "ix86_match_ccmode (insn, CCNOmode)
10522    && ix86_unary_operator_ok (NEG, HImode, operands)"
10523   "#"
10524   [(set_attr "type" "alu1")
10525    (set_attr "mode" "HI")])
10526
10527 (define_split
10528   [(set (match_operand 0 "flags_reg_operand" "")
10529         (match_operator 2 "compare_operator"
10530           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10531            (const_int 0)]))
10532    (set (match_operand:HI 1 "nonimmediate_operand" "")
10533         (not:HI (match_dup 3)))]
10534   "ix86_match_ccmode (insn, CCNOmode)"
10535   [(parallel [(set (match_dup 0)
10536                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10537                                     (const_int 0)]))
10538               (set (match_dup 1)
10539                    (xor:HI (match_dup 3) (const_int -1)))])]
10540   "")
10541
10542 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10543 (define_expand "one_cmplqi2"
10544   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10545         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10546   "TARGET_QIMODE_MATH"
10547   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10548
10549 (define_insn "*one_cmplqi2_1"
10550   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10551         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10552   "ix86_unary_operator_ok (NOT, QImode, operands)"
10553   "@
10554    not{b}\t%0
10555    not{l}\t%k0"
10556   [(set_attr "type" "negnot")
10557    (set_attr "mode" "QI,SI")])
10558
10559 (define_insn "*one_cmplqi2_2"
10560   [(set (reg FLAGS_REG)
10561         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10562                  (const_int 0)))
10563    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10564         (not:QI (match_dup 1)))]
10565   "ix86_match_ccmode (insn, CCNOmode)
10566    && ix86_unary_operator_ok (NOT, QImode, operands)"
10567   "#"
10568   [(set_attr "type" "alu1")
10569    (set_attr "mode" "QI")])
10570
10571 (define_split
10572   [(set (match_operand 0 "flags_reg_operand" "")
10573         (match_operator 2 "compare_operator"
10574           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10575            (const_int 0)]))
10576    (set (match_operand:QI 1 "nonimmediate_operand" "")
10577         (not:QI (match_dup 3)))]
10578   "ix86_match_ccmode (insn, CCNOmode)"
10579   [(parallel [(set (match_dup 0)
10580                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10581                                     (const_int 0)]))
10582               (set (match_dup 1)
10583                    (xor:QI (match_dup 3) (const_int -1)))])]
10584   "")
10585 \f
10586 ;; Arithmetic shift instructions
10587
10588 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10589 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10590 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10591 ;; from the assembler input.
10592 ;;
10593 ;; This instruction shifts the target reg/mem as usual, but instead of
10594 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10595 ;; is a left shift double, bits are taken from the high order bits of
10596 ;; reg, else if the insn is a shift right double, bits are taken from the
10597 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10598 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10599 ;;
10600 ;; Since sh[lr]d does not change the `reg' operand, that is done
10601 ;; separately, making all shifts emit pairs of shift double and normal
10602 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10603 ;; support a 63 bit shift, each shift where the count is in a reg expands
10604 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10605 ;;
10606 ;; If the shift count is a constant, we need never emit more than one
10607 ;; shift pair, instead using moves and sign extension for counts greater
10608 ;; than 31.
10609
10610 (define_expand "ashlti3"
10611   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10612                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10613                               (match_operand:QI 2 "nonmemory_operand" "")))
10614               (clobber (reg:CC FLAGS_REG))])]
10615   "TARGET_64BIT"
10616 {
10617   if (! immediate_operand (operands[2], QImode))
10618     {
10619       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10620       DONE;
10621     }
10622   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10623   DONE;
10624 })
10625
10626 (define_insn "ashlti3_1"
10627   [(set (match_operand:TI 0 "register_operand" "=r")
10628         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10629                    (match_operand:QI 2 "register_operand" "c")))
10630    (clobber (match_scratch:DI 3 "=&r"))
10631    (clobber (reg:CC FLAGS_REG))]
10632   "TARGET_64BIT"
10633   "#"
10634   [(set_attr "type" "multi")])
10635
10636 (define_insn "*ashlti3_2"
10637   [(set (match_operand:TI 0 "register_operand" "=r")
10638         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10639                    (match_operand:QI 2 "immediate_operand" "O")))
10640    (clobber (reg:CC FLAGS_REG))]
10641   "TARGET_64BIT"
10642   "#"
10643   [(set_attr "type" "multi")])
10644
10645 (define_split
10646   [(set (match_operand:TI 0 "register_operand" "")
10647         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10648                    (match_operand:QI 2 "register_operand" "")))
10649    (clobber (match_scratch:DI 3 ""))
10650    (clobber (reg:CC FLAGS_REG))]
10651   "TARGET_64BIT && reload_completed"
10652   [(const_int 0)]
10653   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10654
10655 (define_split
10656   [(set (match_operand:TI 0 "register_operand" "")
10657         (ashift:TI (match_operand:TI 1 "register_operand" "")
10658                    (match_operand:QI 2 "immediate_operand" "")))
10659    (clobber (reg:CC FLAGS_REG))]
10660   "TARGET_64BIT && reload_completed"
10661   [(const_int 0)]
10662   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10663
10664 (define_insn "x86_64_shld"
10665   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10666         (ior:DI (ashift:DI (match_dup 0)
10667                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10668                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10669                   (minus:QI (const_int 64) (match_dup 2)))))
10670    (clobber (reg:CC FLAGS_REG))]
10671   "TARGET_64BIT"
10672   "@
10673    shld{q}\t{%2, %1, %0|%0, %1, %2}
10674    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10675   [(set_attr "type" "ishift")
10676    (set_attr "prefix_0f" "1")
10677    (set_attr "mode" "DI")
10678    (set_attr "athlon_decode" "vector")
10679    (set_attr "amdfam10_decode" "vector")])   
10680
10681 (define_expand "x86_64_shift_adj"
10682   [(set (reg:CCZ FLAGS_REG)
10683         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10684                              (const_int 64))
10685                      (const_int 0)))
10686    (set (match_operand:DI 0 "register_operand" "")
10687         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10688                          (match_operand:DI 1 "register_operand" "")
10689                          (match_dup 0)))
10690    (set (match_dup 1)
10691         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10692                          (match_operand:DI 3 "register_operand" "r")
10693                          (match_dup 1)))]
10694   "TARGET_64BIT"
10695   "")
10696
10697 (define_expand "ashldi3"
10698   [(set (match_operand:DI 0 "shiftdi_operand" "")
10699         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10700                    (match_operand:QI 2 "nonmemory_operand" "")))]
10701   ""
10702   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10703
10704 (define_insn "*ashldi3_1_rex64"
10705   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10706         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10707                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10708    (clobber (reg:CC FLAGS_REG))]
10709   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10710 {
10711   switch (get_attr_type (insn))
10712     {
10713     case TYPE_ALU:
10714       gcc_assert (operands[2] == const1_rtx);
10715       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10716       return "add{q}\t%0, %0";
10717
10718     case TYPE_LEA:
10719       gcc_assert (CONST_INT_P (operands[2]));
10720       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10721       operands[1] = gen_rtx_MULT (DImode, operands[1],
10722                                   GEN_INT (1 << INTVAL (operands[2])));
10723       return "lea{q}\t{%a1, %0|%0, %a1}";
10724
10725     default:
10726       if (REG_P (operands[2]))
10727         return "sal{q}\t{%b2, %0|%0, %b2}";
10728       else if (operands[2] == const1_rtx
10729                && (TARGET_SHIFT1 || optimize_size))
10730         return "sal{q}\t%0";
10731       else
10732         return "sal{q}\t{%2, %0|%0, %2}";
10733     }
10734 }
10735   [(set (attr "type")
10736      (cond [(eq_attr "alternative" "1")
10737               (const_string "lea")
10738             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10739                           (const_int 0))
10740                       (match_operand 0 "register_operand" ""))
10741                  (match_operand 2 "const1_operand" ""))
10742               (const_string "alu")
10743            ]
10744            (const_string "ishift")))
10745    (set_attr "mode" "DI")])
10746
10747 ;; Convert lea to the lea pattern to avoid flags dependency.
10748 (define_split
10749   [(set (match_operand:DI 0 "register_operand" "")
10750         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10751                    (match_operand:QI 2 "immediate_operand" "")))
10752    (clobber (reg:CC FLAGS_REG))]
10753   "TARGET_64BIT && reload_completed
10754    && true_regnum (operands[0]) != true_regnum (operands[1])"
10755   [(set (match_dup 0)
10756         (mult:DI (match_dup 1)
10757                  (match_dup 2)))]
10758   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10759
10760 ;; This pattern can't accept a variable shift count, since shifts by
10761 ;; zero don't affect the flags.  We assume that shifts by constant
10762 ;; zero are optimized away.
10763 (define_insn "*ashldi3_cmp_rex64"
10764   [(set (reg FLAGS_REG)
10765         (compare
10766           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10767                      (match_operand:QI 2 "immediate_operand" "e"))
10768           (const_int 0)))
10769    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10770         (ashift:DI (match_dup 1) (match_dup 2)))]
10771   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10772    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10773    && (optimize_size
10774        || !TARGET_PARTIAL_FLAG_REG_STALL
10775        || (operands[2] == const1_rtx
10776            && (TARGET_SHIFT1
10777                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10778 {
10779   switch (get_attr_type (insn))
10780     {
10781     case TYPE_ALU:
10782       gcc_assert (operands[2] == const1_rtx);
10783       return "add{q}\t%0, %0";
10784
10785     default:
10786       if (REG_P (operands[2]))
10787         return "sal{q}\t{%b2, %0|%0, %b2}";
10788       else if (operands[2] == const1_rtx
10789                && (TARGET_SHIFT1 || optimize_size))
10790         return "sal{q}\t%0";
10791       else
10792         return "sal{q}\t{%2, %0|%0, %2}";
10793     }
10794 }
10795   [(set (attr "type")
10796      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10797                           (const_int 0))
10798                       (match_operand 0 "register_operand" ""))
10799                  (match_operand 2 "const1_operand" ""))
10800               (const_string "alu")
10801            ]
10802            (const_string "ishift")))
10803    (set_attr "mode" "DI")])
10804
10805 (define_insn "*ashldi3_cconly_rex64"
10806   [(set (reg FLAGS_REG)
10807         (compare
10808           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10809                      (match_operand:QI 2 "immediate_operand" "e"))
10810           (const_int 0)))
10811    (clobber (match_scratch:DI 0 "=r"))]
10812   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10813    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10814    && (optimize_size
10815        || !TARGET_PARTIAL_FLAG_REG_STALL
10816        || (operands[2] == const1_rtx
10817            && (TARGET_SHIFT1
10818                || TARGET_DOUBLE_WITH_ADD)))"
10819 {
10820   switch (get_attr_type (insn))
10821     {
10822     case TYPE_ALU:
10823       gcc_assert (operands[2] == const1_rtx);
10824       return "add{q}\t%0, %0";
10825
10826     default:
10827       if (REG_P (operands[2]))
10828         return "sal{q}\t{%b2, %0|%0, %b2}";
10829       else if (operands[2] == const1_rtx
10830                && (TARGET_SHIFT1 || optimize_size))
10831         return "sal{q}\t%0";
10832       else
10833         return "sal{q}\t{%2, %0|%0, %2}";
10834     }
10835 }
10836   [(set (attr "type")
10837      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10838                           (const_int 0))
10839                       (match_operand 0 "register_operand" ""))
10840                  (match_operand 2 "const1_operand" ""))
10841               (const_string "alu")
10842            ]
10843            (const_string "ishift")))
10844    (set_attr "mode" "DI")])
10845
10846 (define_insn "*ashldi3_1"
10847   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10848         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10849                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10850    (clobber (reg:CC FLAGS_REG))]
10851   "!TARGET_64BIT"
10852   "#"
10853   [(set_attr "type" "multi")])
10854
10855 ;; By default we don't ask for a scratch register, because when DImode
10856 ;; values are manipulated, registers are already at a premium.  But if
10857 ;; we have one handy, we won't turn it away.
10858 (define_peephole2
10859   [(match_scratch:SI 3 "r")
10860    (parallel [(set (match_operand:DI 0 "register_operand" "")
10861                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10862                               (match_operand:QI 2 "nonmemory_operand" "")))
10863               (clobber (reg:CC FLAGS_REG))])
10864    (match_dup 3)]
10865   "!TARGET_64BIT && TARGET_CMOVE"
10866   [(const_int 0)]
10867   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10868
10869 (define_split
10870   [(set (match_operand:DI 0 "register_operand" "")
10871         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10872                    (match_operand:QI 2 "nonmemory_operand" "")))
10873    (clobber (reg:CC FLAGS_REG))]
10874   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10875                      ? flow2_completed : reload_completed)"
10876   [(const_int 0)]
10877   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10878
10879 (define_insn "x86_shld_1"
10880   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10881         (ior:SI (ashift:SI (match_dup 0)
10882                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10883                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10884                   (minus:QI (const_int 32) (match_dup 2)))))
10885    (clobber (reg:CC FLAGS_REG))]
10886   ""
10887   "@
10888    shld{l}\t{%2, %1, %0|%0, %1, %2}
10889    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10890   [(set_attr "type" "ishift")
10891    (set_attr "prefix_0f" "1")
10892    (set_attr "mode" "SI")
10893    (set_attr "pent_pair" "np")
10894    (set_attr "athlon_decode" "vector")
10895    (set_attr "amdfam10_decode" "vector")])   
10896
10897 (define_expand "x86_shift_adj_1"
10898   [(set (reg:CCZ FLAGS_REG)
10899         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10900                              (const_int 32))
10901                      (const_int 0)))
10902    (set (match_operand:SI 0 "register_operand" "")
10903         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10904                          (match_operand:SI 1 "register_operand" "")
10905                          (match_dup 0)))
10906    (set (match_dup 1)
10907         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10908                          (match_operand:SI 3 "register_operand" "r")
10909                          (match_dup 1)))]
10910   "TARGET_CMOVE"
10911   "")
10912
10913 (define_expand "x86_shift_adj_2"
10914   [(use (match_operand:SI 0 "register_operand" ""))
10915    (use (match_operand:SI 1 "register_operand" ""))
10916    (use (match_operand:QI 2 "register_operand" ""))]
10917   ""
10918 {
10919   rtx label = gen_label_rtx ();
10920   rtx tmp;
10921
10922   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10923
10924   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10925   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10926   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10927                               gen_rtx_LABEL_REF (VOIDmode, label),
10928                               pc_rtx);
10929   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10930   JUMP_LABEL (tmp) = label;
10931
10932   emit_move_insn (operands[0], operands[1]);
10933   ix86_expand_clear (operands[1]);
10934
10935   emit_label (label);
10936   LABEL_NUSES (label) = 1;
10937
10938   DONE;
10939 })
10940
10941 (define_expand "ashlsi3"
10942   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10943         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10944                    (match_operand:QI 2 "nonmemory_operand" "")))
10945    (clobber (reg:CC FLAGS_REG))]
10946   ""
10947   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10948
10949 (define_insn "*ashlsi3_1"
10950   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10951         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10952                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10953    (clobber (reg:CC FLAGS_REG))]
10954   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10955 {
10956   switch (get_attr_type (insn))
10957     {
10958     case TYPE_ALU:
10959       gcc_assert (operands[2] == const1_rtx);
10960       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10961       return "add{l}\t%0, %0";
10962
10963     case TYPE_LEA:
10964       return "#";
10965
10966     default:
10967       if (REG_P (operands[2]))
10968         return "sal{l}\t{%b2, %0|%0, %b2}";
10969       else if (operands[2] == const1_rtx
10970                && (TARGET_SHIFT1 || optimize_size))
10971         return "sal{l}\t%0";
10972       else
10973         return "sal{l}\t{%2, %0|%0, %2}";
10974     }
10975 }
10976   [(set (attr "type")
10977      (cond [(eq_attr "alternative" "1")
10978               (const_string "lea")
10979             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10980                           (const_int 0))
10981                       (match_operand 0 "register_operand" ""))
10982                  (match_operand 2 "const1_operand" ""))
10983               (const_string "alu")
10984            ]
10985            (const_string "ishift")))
10986    (set_attr "mode" "SI")])
10987
10988 ;; Convert lea to the lea pattern to avoid flags dependency.
10989 (define_split
10990   [(set (match_operand 0 "register_operand" "")
10991         (ashift (match_operand 1 "index_register_operand" "")
10992                 (match_operand:QI 2 "const_int_operand" "")))
10993    (clobber (reg:CC FLAGS_REG))]
10994   "reload_completed
10995    && true_regnum (operands[0]) != true_regnum (operands[1])
10996    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10997   [(const_int 0)]
10998 {
10999   rtx pat;
11000   enum machine_mode mode = GET_MODE (operands[0]);
11001
11002   if (GET_MODE_SIZE (mode) < 4)
11003     operands[0] = gen_lowpart (SImode, operands[0]);
11004   if (mode != Pmode)
11005     operands[1] = gen_lowpart (Pmode, operands[1]);
11006   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11007
11008   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11009   if (Pmode != SImode)
11010     pat = gen_rtx_SUBREG (SImode, pat, 0);
11011   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11012   DONE;
11013 })
11014
11015 ;; Rare case of shifting RSP is handled by generating move and shift
11016 (define_split
11017   [(set (match_operand 0 "register_operand" "")
11018         (ashift (match_operand 1 "register_operand" "")
11019                 (match_operand:QI 2 "const_int_operand" "")))
11020    (clobber (reg:CC FLAGS_REG))]
11021   "reload_completed
11022    && true_regnum (operands[0]) != true_regnum (operands[1])"
11023   [(const_int 0)]
11024 {
11025   rtx pat, clob;
11026   emit_move_insn (operands[0], operands[1]);
11027   pat = gen_rtx_SET (VOIDmode, operands[0],
11028                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11029                                      operands[0], operands[2]));
11030   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11031   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11032   DONE;
11033 })
11034
11035 (define_insn "*ashlsi3_1_zext"
11036   [(set (match_operand:DI 0 "register_operand" "=r,r")
11037         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11038                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11039    (clobber (reg:CC FLAGS_REG))]
11040   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11041 {
11042   switch (get_attr_type (insn))
11043     {
11044     case TYPE_ALU:
11045       gcc_assert (operands[2] == const1_rtx);
11046       return "add{l}\t%k0, %k0";
11047
11048     case TYPE_LEA:
11049       return "#";
11050
11051     default:
11052       if (REG_P (operands[2]))
11053         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11054       else if (operands[2] == const1_rtx
11055                && (TARGET_SHIFT1 || optimize_size))
11056         return "sal{l}\t%k0";
11057       else
11058         return "sal{l}\t{%2, %k0|%k0, %2}";
11059     }
11060 }
11061   [(set (attr "type")
11062      (cond [(eq_attr "alternative" "1")
11063               (const_string "lea")
11064             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11065                      (const_int 0))
11066                  (match_operand 2 "const1_operand" ""))
11067               (const_string "alu")
11068            ]
11069            (const_string "ishift")))
11070    (set_attr "mode" "SI")])
11071
11072 ;; Convert lea to the lea pattern to avoid flags dependency.
11073 (define_split
11074   [(set (match_operand:DI 0 "register_operand" "")
11075         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11076                                 (match_operand:QI 2 "const_int_operand" ""))))
11077    (clobber (reg:CC FLAGS_REG))]
11078   "TARGET_64BIT && reload_completed
11079    && true_regnum (operands[0]) != true_regnum (operands[1])"
11080   [(set (match_dup 0) (zero_extend:DI
11081                         (subreg:SI (mult:SI (match_dup 1)
11082                                             (match_dup 2)) 0)))]
11083 {
11084   operands[1] = gen_lowpart (Pmode, operands[1]);
11085   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11086 })
11087
11088 ;; This pattern can't accept a variable shift count, since shifts by
11089 ;; zero don't affect the flags.  We assume that shifts by constant
11090 ;; zero are optimized away.
11091 (define_insn "*ashlsi3_cmp"
11092   [(set (reg FLAGS_REG)
11093         (compare
11094           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11095                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11096           (const_int 0)))
11097    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11098         (ashift:SI (match_dup 1) (match_dup 2)))]
11099   "ix86_match_ccmode (insn, CCGOCmode)
11100    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11101    && (optimize_size
11102        || !TARGET_PARTIAL_FLAG_REG_STALL
11103        || (operands[2] == const1_rtx
11104            && (TARGET_SHIFT1
11105                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11106 {
11107   switch (get_attr_type (insn))
11108     {
11109     case TYPE_ALU:
11110       gcc_assert (operands[2] == const1_rtx);
11111       return "add{l}\t%0, %0";
11112
11113     default:
11114       if (REG_P (operands[2]))
11115         return "sal{l}\t{%b2, %0|%0, %b2}";
11116       else if (operands[2] == const1_rtx
11117                && (TARGET_SHIFT1 || optimize_size))
11118         return "sal{l}\t%0";
11119       else
11120         return "sal{l}\t{%2, %0|%0, %2}";
11121     }
11122 }
11123   [(set (attr "type")
11124      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11125                           (const_int 0))
11126                       (match_operand 0 "register_operand" ""))
11127                  (match_operand 2 "const1_operand" ""))
11128               (const_string "alu")
11129            ]
11130            (const_string "ishift")))
11131    (set_attr "mode" "SI")])
11132
11133 (define_insn "*ashlsi3_cconly"
11134   [(set (reg FLAGS_REG)
11135         (compare
11136           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11137                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11138           (const_int 0)))
11139    (clobber (match_scratch:SI 0 "=r"))]
11140   "ix86_match_ccmode (insn, CCGOCmode)
11141    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11142    && (optimize_size
11143        || !TARGET_PARTIAL_FLAG_REG_STALL
11144        || (operands[2] == const1_rtx
11145            && (TARGET_SHIFT1
11146                || TARGET_DOUBLE_WITH_ADD)))"
11147 {
11148   switch (get_attr_type (insn))
11149     {
11150     case TYPE_ALU:
11151       gcc_assert (operands[2] == const1_rtx);
11152       return "add{l}\t%0, %0";
11153
11154     default:
11155       if (REG_P (operands[2]))
11156         return "sal{l}\t{%b2, %0|%0, %b2}";
11157       else if (operands[2] == const1_rtx
11158                && (TARGET_SHIFT1 || optimize_size))
11159         return "sal{l}\t%0";
11160       else
11161         return "sal{l}\t{%2, %0|%0, %2}";
11162     }
11163 }
11164   [(set (attr "type")
11165      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11166                           (const_int 0))
11167                       (match_operand 0 "register_operand" ""))
11168                  (match_operand 2 "const1_operand" ""))
11169               (const_string "alu")
11170            ]
11171            (const_string "ishift")))
11172    (set_attr "mode" "SI")])
11173
11174 (define_insn "*ashlsi3_cmp_zext"
11175   [(set (reg FLAGS_REG)
11176         (compare
11177           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11178                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11179           (const_int 0)))
11180    (set (match_operand:DI 0 "register_operand" "=r")
11181         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11182   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11183    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11184    && (optimize_size
11185        || !TARGET_PARTIAL_FLAG_REG_STALL
11186        || (operands[2] == const1_rtx
11187            && (TARGET_SHIFT1
11188                || TARGET_DOUBLE_WITH_ADD)))"
11189 {
11190   switch (get_attr_type (insn))
11191     {
11192     case TYPE_ALU:
11193       gcc_assert (operands[2] == const1_rtx);
11194       return "add{l}\t%k0, %k0";
11195
11196     default:
11197       if (REG_P (operands[2]))
11198         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11199       else if (operands[2] == const1_rtx
11200                && (TARGET_SHIFT1 || optimize_size))
11201         return "sal{l}\t%k0";
11202       else
11203         return "sal{l}\t{%2, %k0|%k0, %2}";
11204     }
11205 }
11206   [(set (attr "type")
11207      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11208                      (const_int 0))
11209                  (match_operand 2 "const1_operand" ""))
11210               (const_string "alu")
11211            ]
11212            (const_string "ishift")))
11213    (set_attr "mode" "SI")])
11214
11215 (define_expand "ashlhi3"
11216   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11217         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11218                    (match_operand:QI 2 "nonmemory_operand" "")))
11219    (clobber (reg:CC FLAGS_REG))]
11220   "TARGET_HIMODE_MATH"
11221   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11222
11223 (define_insn "*ashlhi3_1_lea"
11224   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11225         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11226                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11227    (clobber (reg:CC FLAGS_REG))]
11228   "!TARGET_PARTIAL_REG_STALL
11229    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11230 {
11231   switch (get_attr_type (insn))
11232     {
11233     case TYPE_LEA:
11234       return "#";
11235     case TYPE_ALU:
11236       gcc_assert (operands[2] == const1_rtx);
11237       return "add{w}\t%0, %0";
11238
11239     default:
11240       if (REG_P (operands[2]))
11241         return "sal{w}\t{%b2, %0|%0, %b2}";
11242       else if (operands[2] == const1_rtx
11243                && (TARGET_SHIFT1 || optimize_size))
11244         return "sal{w}\t%0";
11245       else
11246         return "sal{w}\t{%2, %0|%0, %2}";
11247     }
11248 }
11249   [(set (attr "type")
11250      (cond [(eq_attr "alternative" "1")
11251               (const_string "lea")
11252             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11253                           (const_int 0))
11254                       (match_operand 0 "register_operand" ""))
11255                  (match_operand 2 "const1_operand" ""))
11256               (const_string "alu")
11257            ]
11258            (const_string "ishift")))
11259    (set_attr "mode" "HI,SI")])
11260
11261 (define_insn "*ashlhi3_1"
11262   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11263         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11264                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11265    (clobber (reg:CC FLAGS_REG))]
11266   "TARGET_PARTIAL_REG_STALL
11267    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11268 {
11269   switch (get_attr_type (insn))
11270     {
11271     case TYPE_ALU:
11272       gcc_assert (operands[2] == const1_rtx);
11273       return "add{w}\t%0, %0";
11274
11275     default:
11276       if (REG_P (operands[2]))
11277         return "sal{w}\t{%b2, %0|%0, %b2}";
11278       else if (operands[2] == const1_rtx
11279                && (TARGET_SHIFT1 || optimize_size))
11280         return "sal{w}\t%0";
11281       else
11282         return "sal{w}\t{%2, %0|%0, %2}";
11283     }
11284 }
11285   [(set (attr "type")
11286      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11287                           (const_int 0))
11288                       (match_operand 0 "register_operand" ""))
11289                  (match_operand 2 "const1_operand" ""))
11290               (const_string "alu")
11291            ]
11292            (const_string "ishift")))
11293    (set_attr "mode" "HI")])
11294
11295 ;; This pattern can't accept a variable shift count, since shifts by
11296 ;; zero don't affect the flags.  We assume that shifts by constant
11297 ;; zero are optimized away.
11298 (define_insn "*ashlhi3_cmp"
11299   [(set (reg FLAGS_REG)
11300         (compare
11301           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11302                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11303           (const_int 0)))
11304    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11305         (ashift:HI (match_dup 1) (match_dup 2)))]
11306   "ix86_match_ccmode (insn, CCGOCmode)
11307    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11308    && (optimize_size
11309        || !TARGET_PARTIAL_FLAG_REG_STALL
11310        || (operands[2] == const1_rtx
11311            && (TARGET_SHIFT1
11312                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11313 {
11314   switch (get_attr_type (insn))
11315     {
11316     case TYPE_ALU:
11317       gcc_assert (operands[2] == const1_rtx);
11318       return "add{w}\t%0, %0";
11319
11320     default:
11321       if (REG_P (operands[2]))
11322         return "sal{w}\t{%b2, %0|%0, %b2}";
11323       else if (operands[2] == const1_rtx
11324                && (TARGET_SHIFT1 || optimize_size))
11325         return "sal{w}\t%0";
11326       else
11327         return "sal{w}\t{%2, %0|%0, %2}";
11328     }
11329 }
11330   [(set (attr "type")
11331      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11332                           (const_int 0))
11333                       (match_operand 0 "register_operand" ""))
11334                  (match_operand 2 "const1_operand" ""))
11335               (const_string "alu")
11336            ]
11337            (const_string "ishift")))
11338    (set_attr "mode" "HI")])
11339
11340 (define_insn "*ashlhi3_cconly"
11341   [(set (reg FLAGS_REG)
11342         (compare
11343           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11344                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11345           (const_int 0)))
11346    (clobber (match_scratch:HI 0 "=r"))]
11347   "ix86_match_ccmode (insn, CCGOCmode)
11348    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11349    && (optimize_size
11350        || !TARGET_PARTIAL_FLAG_REG_STALL
11351        || (operands[2] == const1_rtx
11352            && (TARGET_SHIFT1
11353                || TARGET_DOUBLE_WITH_ADD)))"
11354 {
11355   switch (get_attr_type (insn))
11356     {
11357     case TYPE_ALU:
11358       gcc_assert (operands[2] == const1_rtx);
11359       return "add{w}\t%0, %0";
11360
11361     default:
11362       if (REG_P (operands[2]))
11363         return "sal{w}\t{%b2, %0|%0, %b2}";
11364       else if (operands[2] == const1_rtx
11365                && (TARGET_SHIFT1 || optimize_size))
11366         return "sal{w}\t%0";
11367       else
11368         return "sal{w}\t{%2, %0|%0, %2}";
11369     }
11370 }
11371   [(set (attr "type")
11372      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11373                           (const_int 0))
11374                       (match_operand 0 "register_operand" ""))
11375                  (match_operand 2 "const1_operand" ""))
11376               (const_string "alu")
11377            ]
11378            (const_string "ishift")))
11379    (set_attr "mode" "HI")])
11380
11381 (define_expand "ashlqi3"
11382   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11383         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11384                    (match_operand:QI 2 "nonmemory_operand" "")))
11385    (clobber (reg:CC FLAGS_REG))]
11386   "TARGET_QIMODE_MATH"
11387   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11388
11389 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11390
11391 (define_insn "*ashlqi3_1_lea"
11392   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11393         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11394                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11395    (clobber (reg:CC FLAGS_REG))]
11396   "!TARGET_PARTIAL_REG_STALL
11397    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11398 {
11399   switch (get_attr_type (insn))
11400     {
11401     case TYPE_LEA:
11402       return "#";
11403     case TYPE_ALU:
11404       gcc_assert (operands[2] == const1_rtx);
11405       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11406         return "add{l}\t%k0, %k0";
11407       else
11408         return "add{b}\t%0, %0";
11409
11410     default:
11411       if (REG_P (operands[2]))
11412         {
11413           if (get_attr_mode (insn) == MODE_SI)
11414             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11415           else
11416             return "sal{b}\t{%b2, %0|%0, %b2}";
11417         }
11418       else if (operands[2] == const1_rtx
11419                && (TARGET_SHIFT1 || optimize_size))
11420         {
11421           if (get_attr_mode (insn) == MODE_SI)
11422             return "sal{l}\t%0";
11423           else
11424             return "sal{b}\t%0";
11425         }
11426       else
11427         {
11428           if (get_attr_mode (insn) == MODE_SI)
11429             return "sal{l}\t{%2, %k0|%k0, %2}";
11430           else
11431             return "sal{b}\t{%2, %0|%0, %2}";
11432         }
11433     }
11434 }
11435   [(set (attr "type")
11436      (cond [(eq_attr "alternative" "2")
11437               (const_string "lea")
11438             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11439                           (const_int 0))
11440                       (match_operand 0 "register_operand" ""))
11441                  (match_operand 2 "const1_operand" ""))
11442               (const_string "alu")
11443            ]
11444            (const_string "ishift")))
11445    (set_attr "mode" "QI,SI,SI")])
11446
11447 (define_insn "*ashlqi3_1"
11448   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11449         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11450                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11451    (clobber (reg:CC FLAGS_REG))]
11452   "TARGET_PARTIAL_REG_STALL
11453    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11454 {
11455   switch (get_attr_type (insn))
11456     {
11457     case TYPE_ALU:
11458       gcc_assert (operands[2] == const1_rtx);
11459       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11460         return "add{l}\t%k0, %k0";
11461       else
11462         return "add{b}\t%0, %0";
11463
11464     default:
11465       if (REG_P (operands[2]))
11466         {
11467           if (get_attr_mode (insn) == MODE_SI)
11468             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11469           else
11470             return "sal{b}\t{%b2, %0|%0, %b2}";
11471         }
11472       else if (operands[2] == const1_rtx
11473                && (TARGET_SHIFT1 || optimize_size))
11474         {
11475           if (get_attr_mode (insn) == MODE_SI)
11476             return "sal{l}\t%0";
11477           else
11478             return "sal{b}\t%0";
11479         }
11480       else
11481         {
11482           if (get_attr_mode (insn) == MODE_SI)
11483             return "sal{l}\t{%2, %k0|%k0, %2}";
11484           else
11485             return "sal{b}\t{%2, %0|%0, %2}";
11486         }
11487     }
11488 }
11489   [(set (attr "type")
11490      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11491                           (const_int 0))
11492                       (match_operand 0 "register_operand" ""))
11493                  (match_operand 2 "const1_operand" ""))
11494               (const_string "alu")
11495            ]
11496            (const_string "ishift")))
11497    (set_attr "mode" "QI,SI")])
11498
11499 ;; This pattern can't accept a variable shift count, since shifts by
11500 ;; zero don't affect the flags.  We assume that shifts by constant
11501 ;; zero are optimized away.
11502 (define_insn "*ashlqi3_cmp"
11503   [(set (reg FLAGS_REG)
11504         (compare
11505           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11506                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11507           (const_int 0)))
11508    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11509         (ashift:QI (match_dup 1) (match_dup 2)))]
11510   "ix86_match_ccmode (insn, CCGOCmode)
11511    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11512    && (optimize_size
11513        || !TARGET_PARTIAL_FLAG_REG_STALL
11514        || (operands[2] == const1_rtx
11515            && (TARGET_SHIFT1
11516                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11517 {
11518   switch (get_attr_type (insn))
11519     {
11520     case TYPE_ALU:
11521       gcc_assert (operands[2] == const1_rtx);
11522       return "add{b}\t%0, %0";
11523
11524     default:
11525       if (REG_P (operands[2]))
11526         return "sal{b}\t{%b2, %0|%0, %b2}";
11527       else if (operands[2] == const1_rtx
11528                && (TARGET_SHIFT1 || optimize_size))
11529         return "sal{b}\t%0";
11530       else
11531         return "sal{b}\t{%2, %0|%0, %2}";
11532     }
11533 }
11534   [(set (attr "type")
11535      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11536                           (const_int 0))
11537                       (match_operand 0 "register_operand" ""))
11538                  (match_operand 2 "const1_operand" ""))
11539               (const_string "alu")
11540            ]
11541            (const_string "ishift")))
11542    (set_attr "mode" "QI")])
11543
11544 (define_insn "*ashlqi3_cconly"
11545   [(set (reg FLAGS_REG)
11546         (compare
11547           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11548                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11549           (const_int 0)))
11550    (clobber (match_scratch:QI 0 "=q"))]
11551   "ix86_match_ccmode (insn, CCGOCmode)
11552    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11553    && (optimize_size
11554        || !TARGET_PARTIAL_FLAG_REG_STALL
11555        || (operands[2] == const1_rtx
11556            && (TARGET_SHIFT1
11557                || TARGET_DOUBLE_WITH_ADD)))"
11558 {
11559   switch (get_attr_type (insn))
11560     {
11561     case TYPE_ALU:
11562       gcc_assert (operands[2] == const1_rtx);
11563       return "add{b}\t%0, %0";
11564
11565     default:
11566       if (REG_P (operands[2]))
11567         return "sal{b}\t{%b2, %0|%0, %b2}";
11568       else if (operands[2] == const1_rtx
11569                && (TARGET_SHIFT1 || optimize_size))
11570         return "sal{b}\t%0";
11571       else
11572         return "sal{b}\t{%2, %0|%0, %2}";
11573     }
11574 }
11575   [(set (attr "type")
11576      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11577                           (const_int 0))
11578                       (match_operand 0 "register_operand" ""))
11579                  (match_operand 2 "const1_operand" ""))
11580               (const_string "alu")
11581            ]
11582            (const_string "ishift")))
11583    (set_attr "mode" "QI")])
11584
11585 ;; See comment above `ashldi3' about how this works.
11586
11587 (define_expand "ashrti3"
11588   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11589                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11590                                 (match_operand:QI 2 "nonmemory_operand" "")))
11591               (clobber (reg:CC FLAGS_REG))])]
11592   "TARGET_64BIT"
11593 {
11594   if (! immediate_operand (operands[2], QImode))
11595     {
11596       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11597       DONE;
11598     }
11599   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11600   DONE;
11601 })
11602
11603 (define_insn "ashrti3_1"
11604   [(set (match_operand:TI 0 "register_operand" "=r")
11605         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11606                      (match_operand:QI 2 "register_operand" "c")))
11607    (clobber (match_scratch:DI 3 "=&r"))
11608    (clobber (reg:CC FLAGS_REG))]
11609   "TARGET_64BIT"
11610   "#"
11611   [(set_attr "type" "multi")])
11612
11613 (define_insn "*ashrti3_2"
11614   [(set (match_operand:TI 0 "register_operand" "=r")
11615         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11616                      (match_operand:QI 2 "immediate_operand" "O")))
11617    (clobber (reg:CC FLAGS_REG))]
11618   "TARGET_64BIT"
11619   "#"
11620   [(set_attr "type" "multi")])
11621
11622 (define_split
11623   [(set (match_operand:TI 0 "register_operand" "")
11624         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11625                      (match_operand:QI 2 "register_operand" "")))
11626    (clobber (match_scratch:DI 3 ""))
11627    (clobber (reg:CC FLAGS_REG))]
11628   "TARGET_64BIT && reload_completed"
11629   [(const_int 0)]
11630   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11631
11632 (define_split
11633   [(set (match_operand:TI 0 "register_operand" "")
11634         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11635                      (match_operand:QI 2 "immediate_operand" "")))
11636    (clobber (reg:CC FLAGS_REG))]
11637   "TARGET_64BIT && reload_completed"
11638   [(const_int 0)]
11639   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11640
11641 (define_insn "x86_64_shrd"
11642   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11643         (ior:DI (ashiftrt:DI (match_dup 0)
11644                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11645                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11646                   (minus:QI (const_int 64) (match_dup 2)))))
11647    (clobber (reg:CC FLAGS_REG))]
11648   "TARGET_64BIT"
11649   "@
11650    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11651    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11652   [(set_attr "type" "ishift")
11653    (set_attr "prefix_0f" "1")
11654    (set_attr "mode" "DI")
11655    (set_attr "athlon_decode" "vector")
11656    (set_attr "amdfam10_decode" "vector")])   
11657
11658 (define_expand "ashrdi3"
11659   [(set (match_operand:DI 0 "shiftdi_operand" "")
11660         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11661                      (match_operand:QI 2 "nonmemory_operand" "")))]
11662   ""
11663   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11664
11665 (define_insn "*ashrdi3_63_rex64"
11666   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11667         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11668                      (match_operand:DI 2 "const_int_operand" "i,i")))
11669    (clobber (reg:CC FLAGS_REG))]
11670   "TARGET_64BIT && INTVAL (operands[2]) == 63
11671    && (TARGET_USE_CLTD || optimize_size)
11672    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11673   "@
11674    {cqto|cqo}
11675    sar{q}\t{%2, %0|%0, %2}"
11676   [(set_attr "type" "imovx,ishift")
11677    (set_attr "prefix_0f" "0,*")
11678    (set_attr "length_immediate" "0,*")
11679    (set_attr "modrm" "0,1")
11680    (set_attr "mode" "DI")])
11681
11682 (define_insn "*ashrdi3_1_one_bit_rex64"
11683   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11684         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11685                      (match_operand:QI 2 "const1_operand" "")))
11686    (clobber (reg:CC FLAGS_REG))]
11687   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11688    && (TARGET_SHIFT1 || optimize_size)"
11689   "sar{q}\t%0"
11690   [(set_attr "type" "ishift")
11691    (set (attr "length")
11692      (if_then_else (match_operand:DI 0 "register_operand" "")
11693         (const_string "2")
11694         (const_string "*")))])
11695
11696 (define_insn "*ashrdi3_1_rex64"
11697   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11698         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11699                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11700    (clobber (reg:CC FLAGS_REG))]
11701   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11702   "@
11703    sar{q}\t{%2, %0|%0, %2}
11704    sar{q}\t{%b2, %0|%0, %b2}"
11705   [(set_attr "type" "ishift")
11706    (set_attr "mode" "DI")])
11707
11708 ;; This pattern can't accept a variable shift count, since shifts by
11709 ;; zero don't affect the flags.  We assume that shifts by constant
11710 ;; zero are optimized away.
11711 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11712   [(set (reg FLAGS_REG)
11713         (compare
11714           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11715                        (match_operand:QI 2 "const1_operand" ""))
11716           (const_int 0)))
11717    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11718         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11719   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11720    && (TARGET_SHIFT1 || optimize_size)
11721    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11722   "sar{q}\t%0"
11723   [(set_attr "type" "ishift")
11724    (set (attr "length")
11725      (if_then_else (match_operand:DI 0 "register_operand" "")
11726         (const_string "2")
11727         (const_string "*")))])
11728
11729 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11730   [(set (reg FLAGS_REG)
11731         (compare
11732           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11733                        (match_operand:QI 2 "const1_operand" ""))
11734           (const_int 0)))
11735    (clobber (match_scratch:DI 0 "=r"))]
11736   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11737    && (TARGET_SHIFT1 || optimize_size)
11738    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11739   "sar{q}\t%0"
11740   [(set_attr "type" "ishift")
11741    (set_attr "length" "2")])
11742
11743 ;; This pattern can't accept a variable shift count, since shifts by
11744 ;; zero don't affect the flags.  We assume that shifts by constant
11745 ;; zero are optimized away.
11746 (define_insn "*ashrdi3_cmp_rex64"
11747   [(set (reg FLAGS_REG)
11748         (compare
11749           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11750                        (match_operand:QI 2 "const_int_operand" "n"))
11751           (const_int 0)))
11752    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11753         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11754   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11755    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11756    && (optimize_size
11757        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11758   "sar{q}\t{%2, %0|%0, %2}"
11759   [(set_attr "type" "ishift")
11760    (set_attr "mode" "DI")])
11761
11762 (define_insn "*ashrdi3_cconly_rex64"
11763   [(set (reg FLAGS_REG)
11764         (compare
11765           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11766                        (match_operand:QI 2 "const_int_operand" "n"))
11767           (const_int 0)))
11768    (clobber (match_scratch:DI 0 "=r"))]
11769   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11770    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11771    && (optimize_size
11772        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11773   "sar{q}\t{%2, %0|%0, %2}"
11774   [(set_attr "type" "ishift")
11775    (set_attr "mode" "DI")])
11776
11777 (define_insn "*ashrdi3_1"
11778   [(set (match_operand:DI 0 "register_operand" "=r")
11779         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11780                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11781    (clobber (reg:CC FLAGS_REG))]
11782   "!TARGET_64BIT"
11783   "#"
11784   [(set_attr "type" "multi")])
11785
11786 ;; By default we don't ask for a scratch register, because when DImode
11787 ;; values are manipulated, registers are already at a premium.  But if
11788 ;; we have one handy, we won't turn it away.
11789 (define_peephole2
11790   [(match_scratch:SI 3 "r")
11791    (parallel [(set (match_operand:DI 0 "register_operand" "")
11792                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11793                                 (match_operand:QI 2 "nonmemory_operand" "")))
11794               (clobber (reg:CC FLAGS_REG))])
11795    (match_dup 3)]
11796   "!TARGET_64BIT && TARGET_CMOVE"
11797   [(const_int 0)]
11798   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11799
11800 (define_split
11801   [(set (match_operand:DI 0 "register_operand" "")
11802         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11803                      (match_operand:QI 2 "nonmemory_operand" "")))
11804    (clobber (reg:CC FLAGS_REG))]
11805   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11806                      ? flow2_completed : reload_completed)"
11807   [(const_int 0)]
11808   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11809
11810 (define_insn "x86_shrd_1"
11811   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11812         (ior:SI (ashiftrt:SI (match_dup 0)
11813                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11814                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11815                   (minus:QI (const_int 32) (match_dup 2)))))
11816    (clobber (reg:CC FLAGS_REG))]
11817   ""
11818   "@
11819    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11820    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11821   [(set_attr "type" "ishift")
11822    (set_attr "prefix_0f" "1")
11823    (set_attr "pent_pair" "np")
11824    (set_attr "mode" "SI")])
11825
11826 (define_expand "x86_shift_adj_3"
11827   [(use (match_operand:SI 0 "register_operand" ""))
11828    (use (match_operand:SI 1 "register_operand" ""))
11829    (use (match_operand:QI 2 "register_operand" ""))]
11830   ""
11831 {
11832   rtx label = gen_label_rtx ();
11833   rtx tmp;
11834
11835   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11836
11837   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11838   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11839   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11840                               gen_rtx_LABEL_REF (VOIDmode, label),
11841                               pc_rtx);
11842   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11843   JUMP_LABEL (tmp) = label;
11844
11845   emit_move_insn (operands[0], operands[1]);
11846   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11847
11848   emit_label (label);
11849   LABEL_NUSES (label) = 1;
11850
11851   DONE;
11852 })
11853
11854 (define_insn "ashrsi3_31"
11855   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11856         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11857                      (match_operand:SI 2 "const_int_operand" "i,i")))
11858    (clobber (reg:CC FLAGS_REG))]
11859   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11860    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11861   "@
11862    {cltd|cdq}
11863    sar{l}\t{%2, %0|%0, %2}"
11864   [(set_attr "type" "imovx,ishift")
11865    (set_attr "prefix_0f" "0,*")
11866    (set_attr "length_immediate" "0,*")
11867    (set_attr "modrm" "0,1")
11868    (set_attr "mode" "SI")])
11869
11870 (define_insn "*ashrsi3_31_zext"
11871   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11872         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11873                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11874    (clobber (reg:CC FLAGS_REG))]
11875   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11876    && INTVAL (operands[2]) == 31
11877    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11878   "@
11879    {cltd|cdq}
11880    sar{l}\t{%2, %k0|%k0, %2}"
11881   [(set_attr "type" "imovx,ishift")
11882    (set_attr "prefix_0f" "0,*")
11883    (set_attr "length_immediate" "0,*")
11884    (set_attr "modrm" "0,1")
11885    (set_attr "mode" "SI")])
11886
11887 (define_expand "ashrsi3"
11888   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11889         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11890                      (match_operand:QI 2 "nonmemory_operand" "")))
11891    (clobber (reg:CC FLAGS_REG))]
11892   ""
11893   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11894
11895 (define_insn "*ashrsi3_1_one_bit"
11896   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11897         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11898                      (match_operand:QI 2 "const1_operand" "")))
11899    (clobber (reg:CC FLAGS_REG))]
11900   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11901    && (TARGET_SHIFT1 || optimize_size)"
11902   "sar{l}\t%0"
11903   [(set_attr "type" "ishift")
11904    (set (attr "length")
11905      (if_then_else (match_operand:SI 0 "register_operand" "")
11906         (const_string "2")
11907         (const_string "*")))])
11908
11909 (define_insn "*ashrsi3_1_one_bit_zext"
11910   [(set (match_operand:DI 0 "register_operand" "=r")
11911         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11912                                      (match_operand:QI 2 "const1_operand" ""))))
11913    (clobber (reg:CC FLAGS_REG))]
11914   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11915    && (TARGET_SHIFT1 || optimize_size)"
11916   "sar{l}\t%k0"
11917   [(set_attr "type" "ishift")
11918    (set_attr "length" "2")])
11919
11920 (define_insn "*ashrsi3_1"
11921   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11922         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11923                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11924    (clobber (reg:CC FLAGS_REG))]
11925   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11926   "@
11927    sar{l}\t{%2, %0|%0, %2}
11928    sar{l}\t{%b2, %0|%0, %b2}"
11929   [(set_attr "type" "ishift")
11930    (set_attr "mode" "SI")])
11931
11932 (define_insn "*ashrsi3_1_zext"
11933   [(set (match_operand:DI 0 "register_operand" "=r,r")
11934         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11935                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11936    (clobber (reg:CC FLAGS_REG))]
11937   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11938   "@
11939    sar{l}\t{%2, %k0|%k0, %2}
11940    sar{l}\t{%b2, %k0|%k0, %b2}"
11941   [(set_attr "type" "ishift")
11942    (set_attr "mode" "SI")])
11943
11944 ;; This pattern can't accept a variable shift count, since shifts by
11945 ;; zero don't affect the flags.  We assume that shifts by constant
11946 ;; zero are optimized away.
11947 (define_insn "*ashrsi3_one_bit_cmp"
11948   [(set (reg FLAGS_REG)
11949         (compare
11950           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11951                        (match_operand:QI 2 "const1_operand" ""))
11952           (const_int 0)))
11953    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11954         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11955   "ix86_match_ccmode (insn, CCGOCmode)
11956    && (TARGET_SHIFT1 || optimize_size)
11957    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11958   "sar{l}\t%0"
11959   [(set_attr "type" "ishift")
11960    (set (attr "length")
11961      (if_then_else (match_operand:SI 0 "register_operand" "")
11962         (const_string "2")
11963         (const_string "*")))])
11964
11965 (define_insn "*ashrsi3_one_bit_cconly"
11966   [(set (reg FLAGS_REG)
11967         (compare
11968           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11969                        (match_operand:QI 2 "const1_operand" ""))
11970           (const_int 0)))
11971    (clobber (match_scratch:SI 0 "=r"))]
11972   "ix86_match_ccmode (insn, CCGOCmode)
11973    && (TARGET_SHIFT1 || optimize_size)
11974    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11975   "sar{l}\t%0"
11976   [(set_attr "type" "ishift")
11977    (set_attr "length" "2")])
11978
11979 (define_insn "*ashrsi3_one_bit_cmp_zext"
11980   [(set (reg FLAGS_REG)
11981         (compare
11982           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11983                        (match_operand:QI 2 "const1_operand" ""))
11984           (const_int 0)))
11985    (set (match_operand:DI 0 "register_operand" "=r")
11986         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11987   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11988    && (TARGET_SHIFT1 || optimize_size)
11989    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11990   "sar{l}\t%k0"
11991   [(set_attr "type" "ishift")
11992    (set_attr "length" "2")])
11993
11994 ;; This pattern can't accept a variable shift count, since shifts by
11995 ;; zero don't affect the flags.  We assume that shifts by constant
11996 ;; zero are optimized away.
11997 (define_insn "*ashrsi3_cmp"
11998   [(set (reg FLAGS_REG)
11999         (compare
12000           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12001                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12002           (const_int 0)))
12003    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12004         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12005   "ix86_match_ccmode (insn, CCGOCmode)
12006    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
12007    && (optimize_size
12008        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12009   "sar{l}\t{%2, %0|%0, %2}"
12010   [(set_attr "type" "ishift")
12011    (set_attr "mode" "SI")])
12012
12013 (define_insn "*ashrsi3_cconly"
12014   [(set (reg FLAGS_REG)
12015         (compare
12016           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12017                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12018           (const_int 0)))
12019    (clobber (match_scratch:SI 0 "=r"))]
12020   "ix86_match_ccmode (insn, CCGOCmode)
12021    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
12022    && (optimize_size
12023        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12024   "sar{l}\t{%2, %0|%0, %2}"
12025   [(set_attr "type" "ishift")
12026    (set_attr "mode" "SI")])
12027
12028 (define_insn "*ashrsi3_cmp_zext"
12029   [(set (reg FLAGS_REG)
12030         (compare
12031           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12032                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12033           (const_int 0)))
12034    (set (match_operand:DI 0 "register_operand" "=r")
12035         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12036   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12037    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
12038    && (optimize_size
12039        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12040   "sar{l}\t{%2, %k0|%k0, %2}"
12041   [(set_attr "type" "ishift")
12042    (set_attr "mode" "SI")])
12043
12044 (define_expand "ashrhi3"
12045   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12046         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12047                      (match_operand:QI 2 "nonmemory_operand" "")))
12048    (clobber (reg:CC FLAGS_REG))]
12049   "TARGET_HIMODE_MATH"
12050   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12051
12052 (define_insn "*ashrhi3_1_one_bit"
12053   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12054         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12055                      (match_operand:QI 2 "const1_operand" "")))
12056    (clobber (reg:CC FLAGS_REG))]
12057   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12058    && (TARGET_SHIFT1 || optimize_size)"
12059   "sar{w}\t%0"
12060   [(set_attr "type" "ishift")
12061    (set (attr "length")
12062      (if_then_else (match_operand 0 "register_operand" "")
12063         (const_string "2")
12064         (const_string "*")))])
12065
12066 (define_insn "*ashrhi3_1"
12067   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12068         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12069                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12070    (clobber (reg:CC FLAGS_REG))]
12071   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12072   "@
12073    sar{w}\t{%2, %0|%0, %2}
12074    sar{w}\t{%b2, %0|%0, %b2}"
12075   [(set_attr "type" "ishift")
12076    (set_attr "mode" "HI")])
12077
12078 ;; This pattern can't accept a variable shift count, since shifts by
12079 ;; zero don't affect the flags.  We assume that shifts by constant
12080 ;; zero are optimized away.
12081 (define_insn "*ashrhi3_one_bit_cmp"
12082   [(set (reg FLAGS_REG)
12083         (compare
12084           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12085                        (match_operand:QI 2 "const1_operand" ""))
12086           (const_int 0)))
12087    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12088         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12089   "ix86_match_ccmode (insn, CCGOCmode)
12090    && (TARGET_SHIFT1 || optimize_size)
12091    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12092   "sar{w}\t%0"
12093   [(set_attr "type" "ishift")
12094    (set (attr "length")
12095      (if_then_else (match_operand 0 "register_operand" "")
12096         (const_string "2")
12097         (const_string "*")))])
12098
12099 (define_insn "*ashrhi3_one_bit_cconly"
12100   [(set (reg FLAGS_REG)
12101         (compare
12102           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12103                        (match_operand:QI 2 "const1_operand" ""))
12104           (const_int 0)))
12105    (clobber (match_scratch:HI 0 "=r"))]
12106   "ix86_match_ccmode (insn, CCGOCmode)
12107    && (TARGET_SHIFT1 || optimize_size)
12108    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12109   "sar{w}\t%0"
12110   [(set_attr "type" "ishift")
12111    (set_attr "length" "2")])
12112
12113 ;; This pattern can't accept a variable shift count, since shifts by
12114 ;; zero don't affect the flags.  We assume that shifts by constant
12115 ;; zero are optimized away.
12116 (define_insn "*ashrhi3_cmp"
12117   [(set (reg FLAGS_REG)
12118         (compare
12119           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12120                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12121           (const_int 0)))
12122    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12123         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12124   "ix86_match_ccmode (insn, CCGOCmode)
12125    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12126    && (optimize_size
12127        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12128   "sar{w}\t{%2, %0|%0, %2}"
12129   [(set_attr "type" "ishift")
12130    (set_attr "mode" "HI")])
12131
12132 (define_insn "*ashrhi3_cconly"
12133   [(set (reg FLAGS_REG)
12134         (compare
12135           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12136                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12137           (const_int 0)))
12138    (clobber (match_scratch:HI 0 "=r"))]
12139   "ix86_match_ccmode (insn, CCGOCmode)
12140    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12141    && (optimize_size
12142        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12143   "sar{w}\t{%2, %0|%0, %2}"
12144   [(set_attr "type" "ishift")
12145    (set_attr "mode" "HI")])
12146
12147 (define_expand "ashrqi3"
12148   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12149         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12150                      (match_operand:QI 2 "nonmemory_operand" "")))
12151    (clobber (reg:CC FLAGS_REG))]
12152   "TARGET_QIMODE_MATH"
12153   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12154
12155 (define_insn "*ashrqi3_1_one_bit"
12156   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12157         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12158                      (match_operand:QI 2 "const1_operand" "")))
12159    (clobber (reg:CC FLAGS_REG))]
12160   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12161    && (TARGET_SHIFT1 || optimize_size)"
12162   "sar{b}\t%0"
12163   [(set_attr "type" "ishift")
12164    (set (attr "length")
12165      (if_then_else (match_operand 0 "register_operand" "")
12166         (const_string "2")
12167         (const_string "*")))])
12168
12169 (define_insn "*ashrqi3_1_one_bit_slp"
12170   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12171         (ashiftrt:QI (match_dup 0)
12172                      (match_operand:QI 1 "const1_operand" "")))
12173    (clobber (reg:CC FLAGS_REG))]
12174   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12175    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
12176    && (TARGET_SHIFT1 || optimize_size)"
12177   "sar{b}\t%0"
12178   [(set_attr "type" "ishift1")
12179    (set (attr "length")
12180      (if_then_else (match_operand 0 "register_operand" "")
12181         (const_string "2")
12182         (const_string "*")))])
12183
12184 (define_insn "*ashrqi3_1"
12185   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12186         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12187                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12188    (clobber (reg:CC FLAGS_REG))]
12189   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12190   "@
12191    sar{b}\t{%2, %0|%0, %2}
12192    sar{b}\t{%b2, %0|%0, %b2}"
12193   [(set_attr "type" "ishift")
12194    (set_attr "mode" "QI")])
12195
12196 (define_insn "*ashrqi3_1_slp"
12197   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12198         (ashiftrt:QI (match_dup 0)
12199                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12200    (clobber (reg:CC FLAGS_REG))]
12201   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12202    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12203   "@
12204    sar{b}\t{%1, %0|%0, %1}
12205    sar{b}\t{%b1, %0|%0, %b1}"
12206   [(set_attr "type" "ishift1")
12207    (set_attr "mode" "QI")])
12208
12209 ;; This pattern can't accept a variable shift count, since shifts by
12210 ;; zero don't affect the flags.  We assume that shifts by constant
12211 ;; zero are optimized away.
12212 (define_insn "*ashrqi3_one_bit_cmp"
12213   [(set (reg FLAGS_REG)
12214         (compare
12215           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12216                        (match_operand:QI 2 "const1_operand" "I"))
12217           (const_int 0)))
12218    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12219         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12220   "ix86_match_ccmode (insn, CCGOCmode)
12221    && (TARGET_SHIFT1 || optimize_size)
12222    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12223   "sar{b}\t%0"
12224   [(set_attr "type" "ishift")
12225    (set (attr "length")
12226      (if_then_else (match_operand 0 "register_operand" "")
12227         (const_string "2")
12228         (const_string "*")))])
12229
12230 (define_insn "*ashrqi3_one_bit_cconly"
12231   [(set (reg FLAGS_REG)
12232         (compare
12233           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12234                        (match_operand:QI 2 "const1_operand" "I"))
12235           (const_int 0)))
12236    (clobber (match_scratch:QI 0 "=q"))]
12237   "ix86_match_ccmode (insn, CCGOCmode)
12238    && (TARGET_SHIFT1 || optimize_size)
12239    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12240   "sar{b}\t%0"
12241   [(set_attr "type" "ishift")
12242    (set_attr "length" "2")])
12243
12244 ;; This pattern can't accept a variable shift count, since shifts by
12245 ;; zero don't affect the flags.  We assume that shifts by constant
12246 ;; zero are optimized away.
12247 (define_insn "*ashrqi3_cmp"
12248   [(set (reg FLAGS_REG)
12249         (compare
12250           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12251                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12252           (const_int 0)))
12253    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12254         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12255   "ix86_match_ccmode (insn, CCGOCmode)
12256    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12257    && (optimize_size
12258        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12259   "sar{b}\t{%2, %0|%0, %2}"
12260   [(set_attr "type" "ishift")
12261    (set_attr "mode" "QI")])
12262
12263 (define_insn "*ashrqi3_cconly"
12264   [(set (reg FLAGS_REG)
12265         (compare
12266           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12267                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12268           (const_int 0)))
12269    (clobber (match_scratch:QI 0 "=q"))]
12270   "ix86_match_ccmode (insn, CCGOCmode)
12271    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12272    && (optimize_size
12273        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12274   "sar{b}\t{%2, %0|%0, %2}"
12275   [(set_attr "type" "ishift")
12276    (set_attr "mode" "QI")])
12277
12278 \f
12279 ;; Logical shift instructions
12280
12281 ;; See comment above `ashldi3' about how this works.
12282
12283 (define_expand "lshrti3"
12284   [(parallel [(set (match_operand:TI 0 "register_operand" "")
12285                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12286                                 (match_operand:QI 2 "nonmemory_operand" "")))
12287               (clobber (reg:CC FLAGS_REG))])]
12288   "TARGET_64BIT"
12289 {
12290   if (! immediate_operand (operands[2], QImode))
12291     {
12292       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12293       DONE;
12294     }
12295   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12296   DONE;
12297 })
12298
12299 (define_insn "lshrti3_1"
12300   [(set (match_operand:TI 0 "register_operand" "=r")
12301         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12302                      (match_operand:QI 2 "register_operand" "c")))
12303    (clobber (match_scratch:DI 3 "=&r"))
12304    (clobber (reg:CC FLAGS_REG))]
12305   "TARGET_64BIT"
12306   "#"
12307   [(set_attr "type" "multi")])
12308
12309 (define_insn "*lshrti3_2"
12310   [(set (match_operand:TI 0 "register_operand" "=r")
12311         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12312                      (match_operand:QI 2 "immediate_operand" "O")))
12313    (clobber (reg:CC FLAGS_REG))]
12314   "TARGET_64BIT"
12315   "#"
12316   [(set_attr "type" "multi")])
12317
12318 (define_split
12319   [(set (match_operand:TI 0 "register_operand" "")
12320         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12321                      (match_operand:QI 2 "register_operand" "")))
12322    (clobber (match_scratch:DI 3 ""))
12323    (clobber (reg:CC FLAGS_REG))]
12324   "TARGET_64BIT && reload_completed"
12325   [(const_int 0)]
12326   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12327
12328 (define_split
12329   [(set (match_operand:TI 0 "register_operand" "")
12330         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12331                      (match_operand:QI 2 "immediate_operand" "")))
12332    (clobber (reg:CC FLAGS_REG))]
12333   "TARGET_64BIT && reload_completed"
12334   [(const_int 0)]
12335   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12336
12337 (define_expand "lshrdi3"
12338   [(set (match_operand:DI 0 "shiftdi_operand" "")
12339         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12340                      (match_operand:QI 2 "nonmemory_operand" "")))]
12341   ""
12342   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12343
12344 (define_insn "*lshrdi3_1_one_bit_rex64"
12345   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12346         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12347                      (match_operand:QI 2 "const1_operand" "")))
12348    (clobber (reg:CC FLAGS_REG))]
12349   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12350    && (TARGET_SHIFT1 || optimize_size)"
12351   "shr{q}\t%0"
12352   [(set_attr "type" "ishift")
12353    (set (attr "length")
12354      (if_then_else (match_operand:DI 0 "register_operand" "")
12355         (const_string "2")
12356         (const_string "*")))])
12357
12358 (define_insn "*lshrdi3_1_rex64"
12359   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12360         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12361                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12362    (clobber (reg:CC FLAGS_REG))]
12363   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12364   "@
12365    shr{q}\t{%2, %0|%0, %2}
12366    shr{q}\t{%b2, %0|%0, %b2}"
12367   [(set_attr "type" "ishift")
12368    (set_attr "mode" "DI")])
12369
12370 ;; This pattern can't accept a variable shift count, since shifts by
12371 ;; zero don't affect the flags.  We assume that shifts by constant
12372 ;; zero are optimized away.
12373 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12374   [(set (reg FLAGS_REG)
12375         (compare
12376           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12377                        (match_operand:QI 2 "const1_operand" ""))
12378           (const_int 0)))
12379    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12380         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12381   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12382    && (TARGET_SHIFT1 || optimize_size)
12383    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12384   "shr{q}\t%0"
12385   [(set_attr "type" "ishift")
12386    (set (attr "length")
12387      (if_then_else (match_operand:DI 0 "register_operand" "")
12388         (const_string "2")
12389         (const_string "*")))])
12390
12391 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12392   [(set (reg FLAGS_REG)
12393         (compare
12394           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12395                        (match_operand:QI 2 "const1_operand" ""))
12396           (const_int 0)))
12397    (clobber (match_scratch:DI 0 "=r"))]
12398   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12399    && (TARGET_SHIFT1 || optimize_size)
12400    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12401   "shr{q}\t%0"
12402   [(set_attr "type" "ishift")
12403    (set_attr "length" "2")])
12404
12405 ;; This pattern can't accept a variable shift count, since shifts by
12406 ;; zero don't affect the flags.  We assume that shifts by constant
12407 ;; zero are optimized away.
12408 (define_insn "*lshrdi3_cmp_rex64"
12409   [(set (reg FLAGS_REG)
12410         (compare
12411           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12412                        (match_operand:QI 2 "const_int_operand" "e"))
12413           (const_int 0)))
12414    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12415         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12416   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12417    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12418    && (optimize_size
12419        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12420   "shr{q}\t{%2, %0|%0, %2}"
12421   [(set_attr "type" "ishift")
12422    (set_attr "mode" "DI")])
12423
12424 (define_insn "*lshrdi3_cconly_rex64"
12425   [(set (reg FLAGS_REG)
12426         (compare
12427           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12428                        (match_operand:QI 2 "const_int_operand" "e"))
12429           (const_int 0)))
12430    (clobber (match_scratch:DI 0 "=r"))]
12431   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12432    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12433    && (optimize_size
12434        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12435   "shr{q}\t{%2, %0|%0, %2}"
12436   [(set_attr "type" "ishift")
12437    (set_attr "mode" "DI")])
12438
12439 (define_insn "*lshrdi3_1"
12440   [(set (match_operand:DI 0 "register_operand" "=r")
12441         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12442                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12443    (clobber (reg:CC FLAGS_REG))]
12444   "!TARGET_64BIT"
12445   "#"
12446   [(set_attr "type" "multi")])
12447
12448 ;; By default we don't ask for a scratch register, because when DImode
12449 ;; values are manipulated, registers are already at a premium.  But if
12450 ;; we have one handy, we won't turn it away.
12451 (define_peephole2
12452   [(match_scratch:SI 3 "r")
12453    (parallel [(set (match_operand:DI 0 "register_operand" "")
12454                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12455                                 (match_operand:QI 2 "nonmemory_operand" "")))
12456               (clobber (reg:CC FLAGS_REG))])
12457    (match_dup 3)]
12458   "!TARGET_64BIT && TARGET_CMOVE"
12459   [(const_int 0)]
12460   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12461
12462 (define_split
12463   [(set (match_operand:DI 0 "register_operand" "")
12464         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12465                      (match_operand:QI 2 "nonmemory_operand" "")))
12466    (clobber (reg:CC FLAGS_REG))]
12467   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12468                      ? flow2_completed : reload_completed)"
12469   [(const_int 0)]
12470   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12471
12472 (define_expand "lshrsi3"
12473   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12474         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12475                      (match_operand:QI 2 "nonmemory_operand" "")))
12476    (clobber (reg:CC FLAGS_REG))]
12477   ""
12478   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12479
12480 (define_insn "*lshrsi3_1_one_bit"
12481   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12482         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12483                      (match_operand:QI 2 "const1_operand" "")))
12484    (clobber (reg:CC FLAGS_REG))]
12485   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12486    && (TARGET_SHIFT1 || optimize_size)"
12487   "shr{l}\t%0"
12488   [(set_attr "type" "ishift")
12489    (set (attr "length")
12490      (if_then_else (match_operand:SI 0 "register_operand" "")
12491         (const_string "2")
12492         (const_string "*")))])
12493
12494 (define_insn "*lshrsi3_1_one_bit_zext"
12495   [(set (match_operand:DI 0 "register_operand" "=r")
12496         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12497                      (match_operand:QI 2 "const1_operand" "")))
12498    (clobber (reg:CC FLAGS_REG))]
12499   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12500    && (TARGET_SHIFT1 || optimize_size)"
12501   "shr{l}\t%k0"
12502   [(set_attr "type" "ishift")
12503    (set_attr "length" "2")])
12504
12505 (define_insn "*lshrsi3_1"
12506   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12507         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12508                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12509    (clobber (reg:CC FLAGS_REG))]
12510   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12511   "@
12512    shr{l}\t{%2, %0|%0, %2}
12513    shr{l}\t{%b2, %0|%0, %b2}"
12514   [(set_attr "type" "ishift")
12515    (set_attr "mode" "SI")])
12516
12517 (define_insn "*lshrsi3_1_zext"
12518   [(set (match_operand:DI 0 "register_operand" "=r,r")
12519         (zero_extend:DI
12520           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12521                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12522    (clobber (reg:CC FLAGS_REG))]
12523   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12524   "@
12525    shr{l}\t{%2, %k0|%k0, %2}
12526    shr{l}\t{%b2, %k0|%k0, %b2}"
12527   [(set_attr "type" "ishift")
12528    (set_attr "mode" "SI")])
12529
12530 ;; This pattern can't accept a variable shift count, since shifts by
12531 ;; zero don't affect the flags.  We assume that shifts by constant
12532 ;; zero are optimized away.
12533 (define_insn "*lshrsi3_one_bit_cmp"
12534   [(set (reg FLAGS_REG)
12535         (compare
12536           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12537                        (match_operand:QI 2 "const1_operand" ""))
12538           (const_int 0)))
12539    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12540         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12541   "ix86_match_ccmode (insn, CCGOCmode)
12542    && (TARGET_SHIFT1 || optimize_size)
12543    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12544   "shr{l}\t%0"
12545   [(set_attr "type" "ishift")
12546    (set (attr "length")
12547      (if_then_else (match_operand:SI 0 "register_operand" "")
12548         (const_string "2")
12549         (const_string "*")))])
12550
12551 (define_insn "*lshrsi3_one_bit_cconly"
12552   [(set (reg FLAGS_REG)
12553         (compare
12554           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12555                        (match_operand:QI 2 "const1_operand" ""))
12556           (const_int 0)))
12557    (clobber (match_scratch:SI 0 "=r"))]
12558   "ix86_match_ccmode (insn, CCGOCmode)
12559    && (TARGET_SHIFT1 || optimize_size)
12560    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12561   "shr{l}\t%0"
12562   [(set_attr "type" "ishift")
12563    (set_attr "length" "2")])
12564
12565 (define_insn "*lshrsi3_cmp_one_bit_zext"
12566   [(set (reg FLAGS_REG)
12567         (compare
12568           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12569                        (match_operand:QI 2 "const1_operand" ""))
12570           (const_int 0)))
12571    (set (match_operand:DI 0 "register_operand" "=r")
12572         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12573   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12574    && (TARGET_SHIFT1 || optimize_size)
12575    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12576   "shr{l}\t%k0"
12577   [(set_attr "type" "ishift")
12578    (set_attr "length" "2")])
12579
12580 ;; This pattern can't accept a variable shift count, since shifts by
12581 ;; zero don't affect the flags.  We assume that shifts by constant
12582 ;; zero are optimized away.
12583 (define_insn "*lshrsi3_cmp"
12584   [(set (reg FLAGS_REG)
12585         (compare
12586           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12587                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12588           (const_int 0)))
12589    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12590         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12591   "ix86_match_ccmode (insn, CCGOCmode)
12592    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12593    && (optimize_size
12594        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12595   "shr{l}\t{%2, %0|%0, %2}"
12596   [(set_attr "type" "ishift")
12597    (set_attr "mode" "SI")])
12598
12599 (define_insn "*lshrsi3_cconly"
12600   [(set (reg FLAGS_REG)
12601       (compare
12602         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12603                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12604         (const_int 0)))
12605    (clobber (match_scratch:SI 0 "=r"))]
12606   "ix86_match_ccmode (insn, CCGOCmode)
12607    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12608    && (optimize_size
12609        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12610   "shr{l}\t{%2, %0|%0, %2}"
12611   [(set_attr "type" "ishift")
12612    (set_attr "mode" "SI")])
12613
12614 (define_insn "*lshrsi3_cmp_zext"
12615   [(set (reg FLAGS_REG)
12616         (compare
12617           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12618                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12619           (const_int 0)))
12620    (set (match_operand:DI 0 "register_operand" "=r")
12621         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12622   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12623    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12624    && (optimize_size
12625        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12626   "shr{l}\t{%2, %k0|%k0, %2}"
12627   [(set_attr "type" "ishift")
12628    (set_attr "mode" "SI")])
12629
12630 (define_expand "lshrhi3"
12631   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12632         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12633                      (match_operand:QI 2 "nonmemory_operand" "")))
12634    (clobber (reg:CC FLAGS_REG))]
12635   "TARGET_HIMODE_MATH"
12636   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12637
12638 (define_insn "*lshrhi3_1_one_bit"
12639   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12640         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12641                      (match_operand:QI 2 "const1_operand" "")))
12642    (clobber (reg:CC FLAGS_REG))]
12643   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12644    && (TARGET_SHIFT1 || optimize_size)"
12645   "shr{w}\t%0"
12646   [(set_attr "type" "ishift")
12647    (set (attr "length")
12648      (if_then_else (match_operand 0 "register_operand" "")
12649         (const_string "2")
12650         (const_string "*")))])
12651
12652 (define_insn "*lshrhi3_1"
12653   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12654         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12655                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12656    (clobber (reg:CC FLAGS_REG))]
12657   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12658   "@
12659    shr{w}\t{%2, %0|%0, %2}
12660    shr{w}\t{%b2, %0|%0, %b2}"
12661   [(set_attr "type" "ishift")
12662    (set_attr "mode" "HI")])
12663
12664 ;; This pattern can't accept a variable shift count, since shifts by
12665 ;; zero don't affect the flags.  We assume that shifts by constant
12666 ;; zero are optimized away.
12667 (define_insn "*lshrhi3_one_bit_cmp"
12668   [(set (reg FLAGS_REG)
12669         (compare
12670           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12671                        (match_operand:QI 2 "const1_operand" ""))
12672           (const_int 0)))
12673    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12674         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12675   "ix86_match_ccmode (insn, CCGOCmode)
12676    && (TARGET_SHIFT1 || optimize_size)
12677    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12678   "shr{w}\t%0"
12679   [(set_attr "type" "ishift")
12680    (set (attr "length")
12681      (if_then_else (match_operand:SI 0 "register_operand" "")
12682         (const_string "2")
12683         (const_string "*")))])
12684
12685 (define_insn "*lshrhi3_one_bit_cconly"
12686   [(set (reg FLAGS_REG)
12687         (compare
12688           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12689                        (match_operand:QI 2 "const1_operand" ""))
12690           (const_int 0)))
12691    (clobber (match_scratch:HI 0 "=r"))]
12692   "ix86_match_ccmode (insn, CCGOCmode)
12693    && (TARGET_SHIFT1 || optimize_size)
12694    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12695   "shr{w}\t%0"
12696   [(set_attr "type" "ishift")
12697    (set_attr "length" "2")])
12698
12699 ;; This pattern can't accept a variable shift count, since shifts by
12700 ;; zero don't affect the flags.  We assume that shifts by constant
12701 ;; zero are optimized away.
12702 (define_insn "*lshrhi3_cmp"
12703   [(set (reg FLAGS_REG)
12704         (compare
12705           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12706                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12707           (const_int 0)))
12708    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12709         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12710   "ix86_match_ccmode (insn, CCGOCmode)
12711    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12712    && (optimize_size
12713        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12714   "shr{w}\t{%2, %0|%0, %2}"
12715   [(set_attr "type" "ishift")
12716    (set_attr "mode" "HI")])
12717
12718 (define_insn "*lshrhi3_cconly"
12719   [(set (reg FLAGS_REG)
12720         (compare
12721           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12722                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12723           (const_int 0)))
12724    (clobber (match_scratch:HI 0 "=r"))]
12725   "ix86_match_ccmode (insn, CCGOCmode)
12726    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12727    && (optimize_size
12728        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12729   "shr{w}\t{%2, %0|%0, %2}"
12730   [(set_attr "type" "ishift")
12731    (set_attr "mode" "HI")])
12732
12733 (define_expand "lshrqi3"
12734   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12735         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12736                      (match_operand:QI 2 "nonmemory_operand" "")))
12737    (clobber (reg:CC FLAGS_REG))]
12738   "TARGET_QIMODE_MATH"
12739   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12740
12741 (define_insn "*lshrqi3_1_one_bit"
12742   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12743         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12744                      (match_operand:QI 2 "const1_operand" "")))
12745    (clobber (reg:CC FLAGS_REG))]
12746   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12747    && (TARGET_SHIFT1 || optimize_size)"
12748   "shr{b}\t%0"
12749   [(set_attr "type" "ishift")
12750    (set (attr "length")
12751      (if_then_else (match_operand 0 "register_operand" "")
12752         (const_string "2")
12753         (const_string "*")))])
12754
12755 (define_insn "*lshrqi3_1_one_bit_slp"
12756   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12757         (lshiftrt:QI (match_dup 0)
12758                      (match_operand:QI 1 "const1_operand" "")))
12759    (clobber (reg:CC FLAGS_REG))]
12760   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12761    && (TARGET_SHIFT1 || optimize_size)"
12762   "shr{b}\t%0"
12763   [(set_attr "type" "ishift1")
12764    (set (attr "length")
12765      (if_then_else (match_operand 0 "register_operand" "")
12766         (const_string "2")
12767         (const_string "*")))])
12768
12769 (define_insn "*lshrqi3_1"
12770   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12771         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12772                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12773    (clobber (reg:CC FLAGS_REG))]
12774   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12775   "@
12776    shr{b}\t{%2, %0|%0, %2}
12777    shr{b}\t{%b2, %0|%0, %b2}"
12778   [(set_attr "type" "ishift")
12779    (set_attr "mode" "QI")])
12780
12781 (define_insn "*lshrqi3_1_slp"
12782   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12783         (lshiftrt:QI (match_dup 0)
12784                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12785    (clobber (reg:CC FLAGS_REG))]
12786   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12787    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12788   "@
12789    shr{b}\t{%1, %0|%0, %1}
12790    shr{b}\t{%b1, %0|%0, %b1}"
12791   [(set_attr "type" "ishift1")
12792    (set_attr "mode" "QI")])
12793
12794 ;; This pattern can't accept a variable shift count, since shifts by
12795 ;; zero don't affect the flags.  We assume that shifts by constant
12796 ;; zero are optimized away.
12797 (define_insn "*lshrqi2_one_bit_cmp"
12798   [(set (reg FLAGS_REG)
12799         (compare
12800           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12801                        (match_operand:QI 2 "const1_operand" ""))
12802           (const_int 0)))
12803    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12804         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12805   "ix86_match_ccmode (insn, CCGOCmode)
12806    && (TARGET_SHIFT1 || optimize_size)
12807    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12808   "shr{b}\t%0"
12809   [(set_attr "type" "ishift")
12810    (set (attr "length")
12811      (if_then_else (match_operand:SI 0 "register_operand" "")
12812         (const_string "2")
12813         (const_string "*")))])
12814
12815 (define_insn "*lshrqi2_one_bit_cconly"
12816   [(set (reg FLAGS_REG)
12817         (compare
12818           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12819                        (match_operand:QI 2 "const1_operand" ""))
12820           (const_int 0)))
12821    (clobber (match_scratch:QI 0 "=q"))]
12822   "ix86_match_ccmode (insn, CCGOCmode)
12823    && (TARGET_SHIFT1 || optimize_size)
12824    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12825   "shr{b}\t%0"
12826   [(set_attr "type" "ishift")
12827    (set_attr "length" "2")])
12828
12829 ;; This pattern can't accept a variable shift count, since shifts by
12830 ;; zero don't affect the flags.  We assume that shifts by constant
12831 ;; zero are optimized away.
12832 (define_insn "*lshrqi2_cmp"
12833   [(set (reg FLAGS_REG)
12834         (compare
12835           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12836                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12837           (const_int 0)))
12838    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12839         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12840   "ix86_match_ccmode (insn, CCGOCmode)
12841    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12842    && (optimize_size
12843        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12844   "shr{b}\t{%2, %0|%0, %2}"
12845   [(set_attr "type" "ishift")
12846    (set_attr "mode" "QI")])
12847
12848 (define_insn "*lshrqi2_cconly"
12849   [(set (reg FLAGS_REG)
12850         (compare
12851           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12852                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12853           (const_int 0)))
12854    (clobber (match_scratch:QI 0 "=q"))]
12855   "ix86_match_ccmode (insn, CCGOCmode)
12856    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12857    && (optimize_size
12858        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12859   "shr{b}\t{%2, %0|%0, %2}"
12860   [(set_attr "type" "ishift")
12861    (set_attr "mode" "QI")])
12862 \f
12863 ;; Rotate instructions
12864
12865 (define_expand "rotldi3"
12866   [(set (match_operand:DI 0 "shiftdi_operand" "")
12867         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12868                    (match_operand:QI 2 "nonmemory_operand" "")))
12869    (clobber (reg:CC FLAGS_REG))]
12870  ""
12871 {
12872   if (TARGET_64BIT)
12873     {
12874       ix86_expand_binary_operator (ROTATE, DImode, operands);
12875       DONE;
12876     }
12877   if (!const_1_to_31_operand (operands[2], VOIDmode))
12878     FAIL;
12879   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12880   DONE;
12881 })
12882
12883 ;; Implement rotation using two double-precision shift instructions
12884 ;; and a scratch register.
12885 (define_insn_and_split "ix86_rotldi3"
12886  [(set (match_operand:DI 0 "register_operand" "=r")
12887        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12888                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12889   (clobber (reg:CC FLAGS_REG))
12890   (clobber (match_scratch:SI 3 "=&r"))]
12891  "!TARGET_64BIT"
12892  ""
12893  "&& reload_completed"
12894  [(set (match_dup 3) (match_dup 4))
12895   (parallel
12896    [(set (match_dup 4)
12897          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12898                  (lshiftrt:SI (match_dup 5)
12899                               (minus:QI (const_int 32) (match_dup 2)))))
12900     (clobber (reg:CC FLAGS_REG))])
12901   (parallel
12902    [(set (match_dup 5)
12903          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12904                  (lshiftrt:SI (match_dup 3)
12905                               (minus:QI (const_int 32) (match_dup 2)))))
12906     (clobber (reg:CC FLAGS_REG))])]
12907  "split_di (operands, 1, operands + 4, operands + 5);")
12908
12909 (define_insn "*rotlsi3_1_one_bit_rex64"
12910   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12911         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12912                    (match_operand:QI 2 "const1_operand" "")))
12913    (clobber (reg:CC FLAGS_REG))]
12914   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12915    && (TARGET_SHIFT1 || optimize_size)"
12916   "rol{q}\t%0"
12917   [(set_attr "type" "rotate")
12918    (set (attr "length")
12919      (if_then_else (match_operand:DI 0 "register_operand" "")
12920         (const_string "2")
12921         (const_string "*")))])
12922
12923 (define_insn "*rotldi3_1_rex64"
12924   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12925         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12926                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12927    (clobber (reg:CC FLAGS_REG))]
12928   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12929   "@
12930    rol{q}\t{%2, %0|%0, %2}
12931    rol{q}\t{%b2, %0|%0, %b2}"
12932   [(set_attr "type" "rotate")
12933    (set_attr "mode" "DI")])
12934
12935 (define_expand "rotlsi3"
12936   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12937         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12938                    (match_operand:QI 2 "nonmemory_operand" "")))
12939    (clobber (reg:CC FLAGS_REG))]
12940   ""
12941   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12942
12943 (define_insn "*rotlsi3_1_one_bit"
12944   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12945         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12946                    (match_operand:QI 2 "const1_operand" "")))
12947    (clobber (reg:CC FLAGS_REG))]
12948   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12949    && (TARGET_SHIFT1 || optimize_size)"
12950   "rol{l}\t%0"
12951   [(set_attr "type" "rotate")
12952    (set (attr "length")
12953      (if_then_else (match_operand:SI 0 "register_operand" "")
12954         (const_string "2")
12955         (const_string "*")))])
12956
12957 (define_insn "*rotlsi3_1_one_bit_zext"
12958   [(set (match_operand:DI 0 "register_operand" "=r")
12959         (zero_extend:DI
12960           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12961                      (match_operand:QI 2 "const1_operand" ""))))
12962    (clobber (reg:CC FLAGS_REG))]
12963   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12964    && (TARGET_SHIFT1 || optimize_size)"
12965   "rol{l}\t%k0"
12966   [(set_attr "type" "rotate")
12967    (set_attr "length" "2")])
12968
12969 (define_insn "*rotlsi3_1"
12970   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12971         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12972                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12973    (clobber (reg:CC FLAGS_REG))]
12974   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12975   "@
12976    rol{l}\t{%2, %0|%0, %2}
12977    rol{l}\t{%b2, %0|%0, %b2}"
12978   [(set_attr "type" "rotate")
12979    (set_attr "mode" "SI")])
12980
12981 (define_insn "*rotlsi3_1_zext"
12982   [(set (match_operand:DI 0 "register_operand" "=r,r")
12983         (zero_extend:DI
12984           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12985                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12986    (clobber (reg:CC FLAGS_REG))]
12987   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12988   "@
12989    rol{l}\t{%2, %k0|%k0, %2}
12990    rol{l}\t{%b2, %k0|%k0, %b2}"
12991   [(set_attr "type" "rotate")
12992    (set_attr "mode" "SI")])
12993
12994 (define_expand "rotlhi3"
12995   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12996         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12997                    (match_operand:QI 2 "nonmemory_operand" "")))
12998    (clobber (reg:CC FLAGS_REG))]
12999   "TARGET_HIMODE_MATH"
13000   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13001
13002 (define_insn "*rotlhi3_1_one_bit"
13003   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13004         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13005                    (match_operand:QI 2 "const1_operand" "")))
13006    (clobber (reg:CC FLAGS_REG))]
13007   "ix86_binary_operator_ok (ROTATE, HImode, operands)
13008    && (TARGET_SHIFT1 || optimize_size)"
13009   "rol{w}\t%0"
13010   [(set_attr "type" "rotate")
13011    (set (attr "length")
13012      (if_then_else (match_operand 0 "register_operand" "")
13013         (const_string "2")
13014         (const_string "*")))])
13015
13016 (define_insn "*rotlhi3_1"
13017   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13018         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13019                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13020    (clobber (reg:CC FLAGS_REG))]
13021   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13022   "@
13023    rol{w}\t{%2, %0|%0, %2}
13024    rol{w}\t{%b2, %0|%0, %b2}"
13025   [(set_attr "type" "rotate")
13026    (set_attr "mode" "HI")])
13027
13028 (define_expand "rotlqi3"
13029   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13030         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13031                    (match_operand:QI 2 "nonmemory_operand" "")))
13032    (clobber (reg:CC FLAGS_REG))]
13033   "TARGET_QIMODE_MATH"
13034   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13035
13036 (define_insn "*rotlqi3_1_one_bit_slp"
13037   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13038         (rotate:QI (match_dup 0)
13039                    (match_operand:QI 1 "const1_operand" "")))
13040    (clobber (reg:CC FLAGS_REG))]
13041   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13042    && (TARGET_SHIFT1 || optimize_size)"
13043   "rol{b}\t%0"
13044   [(set_attr "type" "rotate1")
13045    (set (attr "length")
13046      (if_then_else (match_operand 0 "register_operand" "")
13047         (const_string "2")
13048         (const_string "*")))])
13049
13050 (define_insn "*rotlqi3_1_one_bit"
13051   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13052         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13053                    (match_operand:QI 2 "const1_operand" "")))
13054    (clobber (reg:CC FLAGS_REG))]
13055   "ix86_binary_operator_ok (ROTATE, QImode, operands)
13056    && (TARGET_SHIFT1 || optimize_size)"
13057   "rol{b}\t%0"
13058   [(set_attr "type" "rotate")
13059    (set (attr "length")
13060      (if_then_else (match_operand 0 "register_operand" "")
13061         (const_string "2")
13062         (const_string "*")))])
13063
13064 (define_insn "*rotlqi3_1_slp"
13065   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13066         (rotate:QI (match_dup 0)
13067                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13068    (clobber (reg:CC FLAGS_REG))]
13069   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13070    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13071   "@
13072    rol{b}\t{%1, %0|%0, %1}
13073    rol{b}\t{%b1, %0|%0, %b1}"
13074   [(set_attr "type" "rotate1")
13075    (set_attr "mode" "QI")])
13076
13077 (define_insn "*rotlqi3_1"
13078   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13079         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13080                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13081    (clobber (reg:CC FLAGS_REG))]
13082   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13083   "@
13084    rol{b}\t{%2, %0|%0, %2}
13085    rol{b}\t{%b2, %0|%0, %b2}"
13086   [(set_attr "type" "rotate")
13087    (set_attr "mode" "QI")])
13088
13089 (define_expand "rotrdi3"
13090   [(set (match_operand:DI 0 "shiftdi_operand" "")
13091         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13092                    (match_operand:QI 2 "nonmemory_operand" "")))
13093    (clobber (reg:CC FLAGS_REG))]
13094  ""
13095 {
13096   if (TARGET_64BIT)
13097     {
13098       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13099       DONE;
13100     }
13101   if (!const_1_to_31_operand (operands[2], VOIDmode))
13102     FAIL;
13103   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13104   DONE;
13105 })
13106
13107 ;; Implement rotation using two double-precision shift instructions
13108 ;; and a scratch register.
13109 (define_insn_and_split "ix86_rotrdi3"
13110  [(set (match_operand:DI 0 "register_operand" "=r")
13111        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13112                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13113   (clobber (reg:CC FLAGS_REG))
13114   (clobber (match_scratch:SI 3 "=&r"))]
13115  "!TARGET_64BIT"
13116  ""
13117  "&& reload_completed"
13118  [(set (match_dup 3) (match_dup 4))
13119   (parallel
13120    [(set (match_dup 4)
13121          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13122                  (ashift:SI (match_dup 5)
13123                             (minus:QI (const_int 32) (match_dup 2)))))
13124     (clobber (reg:CC FLAGS_REG))])
13125   (parallel
13126    [(set (match_dup 5)
13127          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13128                  (ashift:SI (match_dup 3)
13129                             (minus:QI (const_int 32) (match_dup 2)))))
13130     (clobber (reg:CC FLAGS_REG))])]
13131  "split_di (operands, 1, operands + 4, operands + 5);")
13132
13133 (define_insn "*rotrdi3_1_one_bit_rex64"
13134   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13135         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13136                      (match_operand:QI 2 "const1_operand" "")))
13137    (clobber (reg:CC FLAGS_REG))]
13138   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
13139    && (TARGET_SHIFT1 || optimize_size)"
13140   "ror{q}\t%0"
13141   [(set_attr "type" "rotate")
13142    (set (attr "length")
13143      (if_then_else (match_operand:DI 0 "register_operand" "")
13144         (const_string "2")
13145         (const_string "*")))])
13146
13147 (define_insn "*rotrdi3_1_rex64"
13148   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13149         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13150                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13151    (clobber (reg:CC FLAGS_REG))]
13152   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13153   "@
13154    ror{q}\t{%2, %0|%0, %2}
13155    ror{q}\t{%b2, %0|%0, %b2}"
13156   [(set_attr "type" "rotate")
13157    (set_attr "mode" "DI")])
13158
13159 (define_expand "rotrsi3"
13160   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13161         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13162                      (match_operand:QI 2 "nonmemory_operand" "")))
13163    (clobber (reg:CC FLAGS_REG))]
13164   ""
13165   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13166
13167 (define_insn "*rotrsi3_1_one_bit"
13168   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13169         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13170                      (match_operand:QI 2 "const1_operand" "")))
13171    (clobber (reg:CC FLAGS_REG))]
13172   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
13173    && (TARGET_SHIFT1 || optimize_size)"
13174   "ror{l}\t%0"
13175   [(set_attr "type" "rotate")
13176    (set (attr "length")
13177      (if_then_else (match_operand:SI 0 "register_operand" "")
13178         (const_string "2")
13179         (const_string "*")))])
13180
13181 (define_insn "*rotrsi3_1_one_bit_zext"
13182   [(set (match_operand:DI 0 "register_operand" "=r")
13183         (zero_extend:DI
13184           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13185                        (match_operand:QI 2 "const1_operand" ""))))
13186    (clobber (reg:CC FLAGS_REG))]
13187   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
13188    && (TARGET_SHIFT1 || optimize_size)"
13189   "ror{l}\t%k0"
13190   [(set_attr "type" "rotate")
13191    (set (attr "length")
13192      (if_then_else (match_operand:SI 0 "register_operand" "")
13193         (const_string "2")
13194         (const_string "*")))])
13195
13196 (define_insn "*rotrsi3_1"
13197   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13198         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13199                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13200    (clobber (reg:CC FLAGS_REG))]
13201   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13202   "@
13203    ror{l}\t{%2, %0|%0, %2}
13204    ror{l}\t{%b2, %0|%0, %b2}"
13205   [(set_attr "type" "rotate")
13206    (set_attr "mode" "SI")])
13207
13208 (define_insn "*rotrsi3_1_zext"
13209   [(set (match_operand:DI 0 "register_operand" "=r,r")
13210         (zero_extend:DI
13211           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13212                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13213    (clobber (reg:CC FLAGS_REG))]
13214   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13215   "@
13216    ror{l}\t{%2, %k0|%k0, %2}
13217    ror{l}\t{%b2, %k0|%k0, %b2}"
13218   [(set_attr "type" "rotate")
13219    (set_attr "mode" "SI")])
13220
13221 (define_expand "rotrhi3"
13222   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13223         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13224                      (match_operand:QI 2 "nonmemory_operand" "")))
13225    (clobber (reg:CC FLAGS_REG))]
13226   "TARGET_HIMODE_MATH"
13227   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13228
13229 (define_insn "*rotrhi3_one_bit"
13230   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13231         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13232                      (match_operand:QI 2 "const1_operand" "")))
13233    (clobber (reg:CC FLAGS_REG))]
13234   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
13235    && (TARGET_SHIFT1 || optimize_size)"
13236   "ror{w}\t%0"
13237   [(set_attr "type" "rotate")
13238    (set (attr "length")
13239      (if_then_else (match_operand 0 "register_operand" "")
13240         (const_string "2")
13241         (const_string "*")))])
13242
13243 (define_insn "*rotrhi3"
13244   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13245         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13246                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13247    (clobber (reg:CC FLAGS_REG))]
13248   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13249   "@
13250    ror{w}\t{%2, %0|%0, %2}
13251    ror{w}\t{%b2, %0|%0, %b2}"
13252   [(set_attr "type" "rotate")
13253    (set_attr "mode" "HI")])
13254
13255 (define_expand "rotrqi3"
13256   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13257         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13258                      (match_operand:QI 2 "nonmemory_operand" "")))
13259    (clobber (reg:CC FLAGS_REG))]
13260   "TARGET_QIMODE_MATH"
13261   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13262
13263 (define_insn "*rotrqi3_1_one_bit"
13264   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13265         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13266                      (match_operand:QI 2 "const1_operand" "")))
13267    (clobber (reg:CC FLAGS_REG))]
13268   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
13269    && (TARGET_SHIFT1 || optimize_size)"
13270   "ror{b}\t%0"
13271   [(set_attr "type" "rotate")
13272    (set (attr "length")
13273      (if_then_else (match_operand 0 "register_operand" "")
13274         (const_string "2")
13275         (const_string "*")))])
13276
13277 (define_insn "*rotrqi3_1_one_bit_slp"
13278   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13279         (rotatert:QI (match_dup 0)
13280                      (match_operand:QI 1 "const1_operand" "")))
13281    (clobber (reg:CC FLAGS_REG))]
13282   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13283    && (TARGET_SHIFT1 || optimize_size)"
13284   "ror{b}\t%0"
13285   [(set_attr "type" "rotate1")
13286    (set (attr "length")
13287      (if_then_else (match_operand 0 "register_operand" "")
13288         (const_string "2")
13289         (const_string "*")))])
13290
13291 (define_insn "*rotrqi3_1"
13292   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13293         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13294                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13295    (clobber (reg:CC FLAGS_REG))]
13296   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13297   "@
13298    ror{b}\t{%2, %0|%0, %2}
13299    ror{b}\t{%b2, %0|%0, %b2}"
13300   [(set_attr "type" "rotate")
13301    (set_attr "mode" "QI")])
13302
13303 (define_insn "*rotrqi3_1_slp"
13304   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13305         (rotatert:QI (match_dup 0)
13306                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13307    (clobber (reg:CC FLAGS_REG))]
13308   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13309    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13310   "@
13311    ror{b}\t{%1, %0|%0, %1}
13312    ror{b}\t{%b1, %0|%0, %b1}"
13313   [(set_attr "type" "rotate1")
13314    (set_attr "mode" "QI")])
13315 \f
13316 ;; Bit set / bit test instructions
13317
13318 (define_expand "extv"
13319   [(set (match_operand:SI 0 "register_operand" "")
13320         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13321                          (match_operand:SI 2 "const8_operand" "")
13322                          (match_operand:SI 3 "const8_operand" "")))]
13323   ""
13324 {
13325   /* Handle extractions from %ah et al.  */
13326   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13327     FAIL;
13328
13329   /* From mips.md: extract_bit_field doesn't verify that our source
13330      matches the predicate, so check it again here.  */
13331   if (! ext_register_operand (operands[1], VOIDmode))
13332     FAIL;
13333 })
13334
13335 (define_expand "extzv"
13336   [(set (match_operand:SI 0 "register_operand" "")
13337         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13338                          (match_operand:SI 2 "const8_operand" "")
13339                          (match_operand:SI 3 "const8_operand" "")))]
13340   ""
13341 {
13342   /* Handle extractions from %ah et al.  */
13343   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13344     FAIL;
13345
13346   /* From mips.md: extract_bit_field doesn't verify that our source
13347      matches the predicate, so check it again here.  */
13348   if (! ext_register_operand (operands[1], VOIDmode))
13349     FAIL;
13350 })
13351
13352 (define_expand "insv"
13353   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13354                       (match_operand 1 "const8_operand" "")
13355                       (match_operand 2 "const8_operand" ""))
13356         (match_operand 3 "register_operand" ""))]
13357   ""
13358 {
13359   /* Handle insertions to %ah et al.  */
13360   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13361     FAIL;
13362
13363   /* From mips.md: insert_bit_field doesn't verify that our source
13364      matches the predicate, so check it again here.  */
13365   if (! ext_register_operand (operands[0], VOIDmode))
13366     FAIL;
13367
13368   if (TARGET_64BIT)
13369     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13370   else
13371     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13372
13373   DONE;
13374 })
13375
13376 ;; %%% bts, btr, btc, bt.
13377 ;; In general these instructions are *slow* when applied to memory,
13378 ;; since they enforce atomic operation.  When applied to registers,
13379 ;; it depends on the cpu implementation.  They're never faster than
13380 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13381 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13382 ;; within the instruction itself, so operating on bits in the high
13383 ;; 32-bits of a register becomes easier.
13384 ;;
13385 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13386 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13387 ;; negdf respectively, so they can never be disabled entirely.
13388
13389 (define_insn "*btsq"
13390   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13391                          (const_int 1)
13392                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13393         (const_int 1))
13394    (clobber (reg:CC FLAGS_REG))]
13395   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13396   "bts{q} %1,%0"
13397   [(set_attr "type" "alu1")])
13398
13399 (define_insn "*btrq"
13400   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13401                          (const_int 1)
13402                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13403         (const_int 0))
13404    (clobber (reg:CC FLAGS_REG))]
13405   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13406   "btr{q} %1,%0"
13407   [(set_attr "type" "alu1")])
13408
13409 (define_insn "*btcq"
13410   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13411                          (const_int 1)
13412                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13413         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13414    (clobber (reg:CC FLAGS_REG))]
13415   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13416   "btc{q} %1,%0"
13417   [(set_attr "type" "alu1")])
13418
13419 ;; Allow Nocona to avoid these instructions if a register is available.
13420
13421 (define_peephole2
13422   [(match_scratch:DI 2 "r")
13423    (parallel [(set (zero_extract:DI
13424                      (match_operand:DI 0 "register_operand" "")
13425                      (const_int 1)
13426                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13427                    (const_int 1))
13428               (clobber (reg:CC FLAGS_REG))])]
13429   "TARGET_64BIT && !TARGET_USE_BT"
13430   [(const_int 0)]
13431 {
13432   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13433   rtx op1;
13434
13435   if (HOST_BITS_PER_WIDE_INT >= 64)
13436     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13437   else if (i < HOST_BITS_PER_WIDE_INT)
13438     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13439   else
13440     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13441
13442   op1 = immed_double_const (lo, hi, DImode);
13443   if (i >= 31)
13444     {
13445       emit_move_insn (operands[2], op1);
13446       op1 = operands[2];
13447     }
13448
13449   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13450   DONE;
13451 })
13452
13453 (define_peephole2
13454   [(match_scratch:DI 2 "r")
13455    (parallel [(set (zero_extract:DI
13456                      (match_operand:DI 0 "register_operand" "")
13457                      (const_int 1)
13458                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13459                    (const_int 0))
13460               (clobber (reg:CC FLAGS_REG))])]
13461   "TARGET_64BIT && !TARGET_USE_BT"
13462   [(const_int 0)]
13463 {
13464   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13465   rtx op1;
13466
13467   if (HOST_BITS_PER_WIDE_INT >= 64)
13468     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13469   else if (i < HOST_BITS_PER_WIDE_INT)
13470     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13471   else
13472     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13473
13474   op1 = immed_double_const (~lo, ~hi, DImode);
13475   if (i >= 32)
13476     {
13477       emit_move_insn (operands[2], op1);
13478       op1 = operands[2];
13479     }
13480
13481   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13482   DONE;
13483 })
13484
13485 (define_peephole2
13486   [(match_scratch:DI 2 "r")
13487    (parallel [(set (zero_extract:DI
13488                      (match_operand:DI 0 "register_operand" "")
13489                      (const_int 1)
13490                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13491               (not:DI (zero_extract:DI
13492                         (match_dup 0) (const_int 1) (match_dup 1))))
13493               (clobber (reg:CC FLAGS_REG))])]
13494   "TARGET_64BIT && !TARGET_USE_BT"
13495   [(const_int 0)]
13496 {
13497   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13498   rtx op1;
13499
13500   if (HOST_BITS_PER_WIDE_INT >= 64)
13501     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13502   else if (i < HOST_BITS_PER_WIDE_INT)
13503     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13504   else
13505     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13506
13507   op1 = immed_double_const (lo, hi, DImode);
13508   if (i >= 31)
13509     {
13510       emit_move_insn (operands[2], op1);
13511       op1 = operands[2];
13512     }
13513
13514   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13515   DONE;
13516 })
13517 \f
13518 ;; Store-flag instructions.
13519
13520 ;; For all sCOND expanders, also expand the compare or test insn that
13521 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13522
13523 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13524 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13525 ;; way, which can later delete the movzx if only QImode is needed.
13526
13527 (define_expand "seq"
13528   [(set (match_operand:QI 0 "register_operand" "")
13529         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13530   ""
13531   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13532
13533 (define_expand "sne"
13534   [(set (match_operand:QI 0 "register_operand" "")
13535         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13536   ""
13537   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13538
13539 (define_expand "sgt"
13540   [(set (match_operand:QI 0 "register_operand" "")
13541         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13542   ""
13543   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13544
13545 (define_expand "sgtu"
13546   [(set (match_operand:QI 0 "register_operand" "")
13547         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13548   ""
13549   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13550
13551 (define_expand "slt"
13552   [(set (match_operand:QI 0 "register_operand" "")
13553         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13554   ""
13555   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13556
13557 (define_expand "sltu"
13558   [(set (match_operand:QI 0 "register_operand" "")
13559         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13560   ""
13561   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13562
13563 (define_expand "sge"
13564   [(set (match_operand:QI 0 "register_operand" "")
13565         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13566   ""
13567   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13568
13569 (define_expand "sgeu"
13570   [(set (match_operand:QI 0 "register_operand" "")
13571         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13572   ""
13573   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13574
13575 (define_expand "sle"
13576   [(set (match_operand:QI 0 "register_operand" "")
13577         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13578   ""
13579   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13580
13581 (define_expand "sleu"
13582   [(set (match_operand:QI 0 "register_operand" "")
13583         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13584   ""
13585   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13586
13587 (define_expand "sunordered"
13588   [(set (match_operand:QI 0 "register_operand" "")
13589         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13590   "TARGET_80387 || TARGET_SSE"
13591   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13592
13593 (define_expand "sordered"
13594   [(set (match_operand:QI 0 "register_operand" "")
13595         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13596   "TARGET_80387"
13597   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13598
13599 (define_expand "suneq"
13600   [(set (match_operand:QI 0 "register_operand" "")
13601         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13602   "TARGET_80387 || TARGET_SSE"
13603   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13604
13605 (define_expand "sunge"
13606   [(set (match_operand:QI 0 "register_operand" "")
13607         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13608   "TARGET_80387 || TARGET_SSE"
13609   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13610
13611 (define_expand "sungt"
13612   [(set (match_operand:QI 0 "register_operand" "")
13613         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13614   "TARGET_80387 || TARGET_SSE"
13615   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13616
13617 (define_expand "sunle"
13618   [(set (match_operand:QI 0 "register_operand" "")
13619         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13620   "TARGET_80387 || TARGET_SSE"
13621   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13622
13623 (define_expand "sunlt"
13624   [(set (match_operand:QI 0 "register_operand" "")
13625         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13626   "TARGET_80387 || TARGET_SSE"
13627   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13628
13629 (define_expand "sltgt"
13630   [(set (match_operand:QI 0 "register_operand" "")
13631         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13632   "TARGET_80387 || TARGET_SSE"
13633   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13634
13635 (define_insn "*setcc_1"
13636   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13637         (match_operator:QI 1 "ix86_comparison_operator"
13638           [(reg FLAGS_REG) (const_int 0)]))]
13639   ""
13640   "set%C1\t%0"
13641   [(set_attr "type" "setcc")
13642    (set_attr "mode" "QI")])
13643
13644 (define_insn "*setcc_2"
13645   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13646         (match_operator:QI 1 "ix86_comparison_operator"
13647           [(reg FLAGS_REG) (const_int 0)]))]
13648   ""
13649   "set%C1\t%0"
13650   [(set_attr "type" "setcc")
13651    (set_attr "mode" "QI")])
13652
13653 ;; In general it is not safe to assume too much about CCmode registers,
13654 ;; so simplify-rtx stops when it sees a second one.  Under certain
13655 ;; conditions this is safe on x86, so help combine not create
13656 ;;
13657 ;;      seta    %al
13658 ;;      testb   %al, %al
13659 ;;      sete    %al
13660
13661 (define_split
13662   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13663         (ne:QI (match_operator 1 "ix86_comparison_operator"
13664                  [(reg FLAGS_REG) (const_int 0)])
13665             (const_int 0)))]
13666   ""
13667   [(set (match_dup 0) (match_dup 1))]
13668 {
13669   PUT_MODE (operands[1], QImode);
13670 })
13671
13672 (define_split
13673   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13674         (ne:QI (match_operator 1 "ix86_comparison_operator"
13675                  [(reg FLAGS_REG) (const_int 0)])
13676             (const_int 0)))]
13677   ""
13678   [(set (match_dup 0) (match_dup 1))]
13679 {
13680   PUT_MODE (operands[1], QImode);
13681 })
13682
13683 (define_split
13684   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13685         (eq:QI (match_operator 1 "ix86_comparison_operator"
13686                  [(reg FLAGS_REG) (const_int 0)])
13687             (const_int 0)))]
13688   ""
13689   [(set (match_dup 0) (match_dup 1))]
13690 {
13691   rtx new_op1 = copy_rtx (operands[1]);
13692   operands[1] = new_op1;
13693   PUT_MODE (new_op1, QImode);
13694   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13695                                              GET_MODE (XEXP (new_op1, 0))));
13696
13697   /* Make sure that (a) the CCmode we have for the flags is strong
13698      enough for the reversed compare or (b) we have a valid FP compare.  */
13699   if (! ix86_comparison_operator (new_op1, VOIDmode))
13700     FAIL;
13701 })
13702
13703 (define_split
13704   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13705         (eq:QI (match_operator 1 "ix86_comparison_operator"
13706                  [(reg FLAGS_REG) (const_int 0)])
13707             (const_int 0)))]
13708   ""
13709   [(set (match_dup 0) (match_dup 1))]
13710 {
13711   rtx new_op1 = copy_rtx (operands[1]);
13712   operands[1] = new_op1;
13713   PUT_MODE (new_op1, QImode);
13714   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13715                                              GET_MODE (XEXP (new_op1, 0))));
13716
13717   /* Make sure that (a) the CCmode we have for the flags is strong
13718      enough for the reversed compare or (b) we have a valid FP compare.  */
13719   if (! ix86_comparison_operator (new_op1, VOIDmode))
13720     FAIL;
13721 })
13722
13723 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13724 ;; subsequent logical operations are used to imitate conditional moves.
13725 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13726 ;; it directly.
13727
13728 (define_insn "*sse_setccsf"
13729   [(set (match_operand:SF 0 "register_operand" "=x")
13730         (match_operator:SF 1 "sse_comparison_operator"
13731           [(match_operand:SF 2 "register_operand" "0")
13732            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13733   "TARGET_SSE"
13734   "cmp%D1ss\t{%3, %0|%0, %3}"
13735   [(set_attr "type" "ssecmp")
13736    (set_attr "mode" "SF")])
13737
13738 (define_insn "*sse_setccdf"
13739   [(set (match_operand:DF 0 "register_operand" "=x")
13740         (match_operator:DF 1 "sse_comparison_operator"
13741           [(match_operand:DF 2 "register_operand" "0")
13742            (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
13743   "TARGET_SSE2"
13744   "cmp%D1sd\t{%3, %0|%0, %3}"
13745   [(set_attr "type" "ssecmp")
13746    (set_attr "mode" "DF")])
13747 \f
13748 ;; Basic conditional jump instructions.
13749 ;; We ignore the overflow flag for signed branch instructions.
13750
13751 ;; For all bCOND expanders, also expand the compare or test insn that
13752 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13753
13754 (define_expand "beq"
13755   [(set (pc)
13756         (if_then_else (match_dup 1)
13757                       (label_ref (match_operand 0 "" ""))
13758                       (pc)))]
13759   ""
13760   "ix86_expand_branch (EQ, operands[0]); DONE;")
13761
13762 (define_expand "bne"
13763   [(set (pc)
13764         (if_then_else (match_dup 1)
13765                       (label_ref (match_operand 0 "" ""))
13766                       (pc)))]
13767   ""
13768   "ix86_expand_branch (NE, operands[0]); DONE;")
13769
13770 (define_expand "bgt"
13771   [(set (pc)
13772         (if_then_else (match_dup 1)
13773                       (label_ref (match_operand 0 "" ""))
13774                       (pc)))]
13775   ""
13776   "ix86_expand_branch (GT, operands[0]); DONE;")
13777
13778 (define_expand "bgtu"
13779   [(set (pc)
13780         (if_then_else (match_dup 1)
13781                       (label_ref (match_operand 0 "" ""))
13782                       (pc)))]
13783   ""
13784   "ix86_expand_branch (GTU, operands[0]); DONE;")
13785
13786 (define_expand "blt"
13787   [(set (pc)
13788         (if_then_else (match_dup 1)
13789                       (label_ref (match_operand 0 "" ""))
13790                       (pc)))]
13791   ""
13792   "ix86_expand_branch (LT, operands[0]); DONE;")
13793
13794 (define_expand "bltu"
13795   [(set (pc)
13796         (if_then_else (match_dup 1)
13797                       (label_ref (match_operand 0 "" ""))
13798                       (pc)))]
13799   ""
13800   "ix86_expand_branch (LTU, operands[0]); DONE;")
13801
13802 (define_expand "bge"
13803   [(set (pc)
13804         (if_then_else (match_dup 1)
13805                       (label_ref (match_operand 0 "" ""))
13806                       (pc)))]
13807   ""
13808   "ix86_expand_branch (GE, operands[0]); DONE;")
13809
13810 (define_expand "bgeu"
13811   [(set (pc)
13812         (if_then_else (match_dup 1)
13813                       (label_ref (match_operand 0 "" ""))
13814                       (pc)))]
13815   ""
13816   "ix86_expand_branch (GEU, operands[0]); DONE;")
13817
13818 (define_expand "ble"
13819   [(set (pc)
13820         (if_then_else (match_dup 1)
13821                       (label_ref (match_operand 0 "" ""))
13822                       (pc)))]
13823   ""
13824   "ix86_expand_branch (LE, operands[0]); DONE;")
13825
13826 (define_expand "bleu"
13827   [(set (pc)
13828         (if_then_else (match_dup 1)
13829                       (label_ref (match_operand 0 "" ""))
13830                       (pc)))]
13831   ""
13832   "ix86_expand_branch (LEU, operands[0]); DONE;")
13833
13834 (define_expand "bunordered"
13835   [(set (pc)
13836         (if_then_else (match_dup 1)
13837                       (label_ref (match_operand 0 "" ""))
13838                       (pc)))]
13839   "TARGET_80387 || TARGET_SSE_MATH"
13840   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13841
13842 (define_expand "bordered"
13843   [(set (pc)
13844         (if_then_else (match_dup 1)
13845                       (label_ref (match_operand 0 "" ""))
13846                       (pc)))]
13847   "TARGET_80387 || TARGET_SSE_MATH"
13848   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13849
13850 (define_expand "buneq"
13851   [(set (pc)
13852         (if_then_else (match_dup 1)
13853                       (label_ref (match_operand 0 "" ""))
13854                       (pc)))]
13855   "TARGET_80387 || TARGET_SSE_MATH"
13856   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13857
13858 (define_expand "bunge"
13859   [(set (pc)
13860         (if_then_else (match_dup 1)
13861                       (label_ref (match_operand 0 "" ""))
13862                       (pc)))]
13863   "TARGET_80387 || TARGET_SSE_MATH"
13864   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13865
13866 (define_expand "bungt"
13867   [(set (pc)
13868         (if_then_else (match_dup 1)
13869                       (label_ref (match_operand 0 "" ""))
13870                       (pc)))]
13871   "TARGET_80387 || TARGET_SSE_MATH"
13872   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13873
13874 (define_expand "bunle"
13875   [(set (pc)
13876         (if_then_else (match_dup 1)
13877                       (label_ref (match_operand 0 "" ""))
13878                       (pc)))]
13879   "TARGET_80387 || TARGET_SSE_MATH"
13880   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13881
13882 (define_expand "bunlt"
13883   [(set (pc)
13884         (if_then_else (match_dup 1)
13885                       (label_ref (match_operand 0 "" ""))
13886                       (pc)))]
13887   "TARGET_80387 || TARGET_SSE_MATH"
13888   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13889
13890 (define_expand "bltgt"
13891   [(set (pc)
13892         (if_then_else (match_dup 1)
13893                       (label_ref (match_operand 0 "" ""))
13894                       (pc)))]
13895   "TARGET_80387 || TARGET_SSE_MATH"
13896   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13897
13898 (define_insn "*jcc_1"
13899   [(set (pc)
13900         (if_then_else (match_operator 1 "ix86_comparison_operator"
13901                                       [(reg FLAGS_REG) (const_int 0)])
13902                       (label_ref (match_operand 0 "" ""))
13903                       (pc)))]
13904   ""
13905   "%+j%C1\t%l0"
13906   [(set_attr "type" "ibr")
13907    (set_attr "modrm" "0")
13908    (set (attr "length")
13909            (if_then_else (and (ge (minus (match_dup 0) (pc))
13910                                   (const_int -126))
13911                               (lt (minus (match_dup 0) (pc))
13912                                   (const_int 128)))
13913              (const_int 2)
13914              (const_int 6)))])
13915
13916 (define_insn "*jcc_2"
13917   [(set (pc)
13918         (if_then_else (match_operator 1 "ix86_comparison_operator"
13919                                       [(reg FLAGS_REG) (const_int 0)])
13920                       (pc)
13921                       (label_ref (match_operand 0 "" ""))))]
13922   ""
13923   "%+j%c1\t%l0"
13924   [(set_attr "type" "ibr")
13925    (set_attr "modrm" "0")
13926    (set (attr "length")
13927            (if_then_else (and (ge (minus (match_dup 0) (pc))
13928                                   (const_int -126))
13929                               (lt (minus (match_dup 0) (pc))
13930                                   (const_int 128)))
13931              (const_int 2)
13932              (const_int 6)))])
13933
13934 ;; In general it is not safe to assume too much about CCmode registers,
13935 ;; so simplify-rtx stops when it sees a second one.  Under certain
13936 ;; conditions this is safe on x86, so help combine not create
13937 ;;
13938 ;;      seta    %al
13939 ;;      testb   %al, %al
13940 ;;      je      Lfoo
13941
13942 (define_split
13943   [(set (pc)
13944         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13945                                       [(reg FLAGS_REG) (const_int 0)])
13946                           (const_int 0))
13947                       (label_ref (match_operand 1 "" ""))
13948                       (pc)))]
13949   ""
13950   [(set (pc)
13951         (if_then_else (match_dup 0)
13952                       (label_ref (match_dup 1))
13953                       (pc)))]
13954 {
13955   PUT_MODE (operands[0], VOIDmode);
13956 })
13957
13958 (define_split
13959   [(set (pc)
13960         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13961                                       [(reg FLAGS_REG) (const_int 0)])
13962                           (const_int 0))
13963                       (label_ref (match_operand 1 "" ""))
13964                       (pc)))]
13965   ""
13966   [(set (pc)
13967         (if_then_else (match_dup 0)
13968                       (label_ref (match_dup 1))
13969                       (pc)))]
13970 {
13971   rtx new_op0 = copy_rtx (operands[0]);
13972   operands[0] = new_op0;
13973   PUT_MODE (new_op0, VOIDmode);
13974   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13975                                              GET_MODE (XEXP (new_op0, 0))));
13976
13977   /* Make sure that (a) the CCmode we have for the flags is strong
13978      enough for the reversed compare or (b) we have a valid FP compare.  */
13979   if (! ix86_comparison_operator (new_op0, VOIDmode))
13980     FAIL;
13981 })
13982
13983 ;; Define combination compare-and-branch fp compare instructions to use
13984 ;; during early optimization.  Splitting the operation apart early makes
13985 ;; for bad code when we want to reverse the operation.
13986
13987 (define_insn "*fp_jcc_1_mixed"
13988   [(set (pc)
13989         (if_then_else (match_operator 0 "comparison_operator"
13990                         [(match_operand 1 "register_operand" "f,x")
13991                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13992           (label_ref (match_operand 3 "" ""))
13993           (pc)))
13994    (clobber (reg:CCFP FPSR_REG))
13995    (clobber (reg:CCFP FLAGS_REG))]
13996   "TARGET_MIX_SSE_I387
13997    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13998    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13999    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14000   "#")
14001
14002 (define_insn "*fp_jcc_1_sse"
14003   [(set (pc)
14004         (if_then_else (match_operator 0 "comparison_operator"
14005                         [(match_operand 1 "register_operand" "x")
14006                          (match_operand 2 "nonimmediate_operand" "xm")])
14007           (label_ref (match_operand 3 "" ""))
14008           (pc)))
14009    (clobber (reg:CCFP FPSR_REG))
14010    (clobber (reg:CCFP FLAGS_REG))]
14011   "TARGET_SSE_MATH
14012    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14013    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14014    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14015   "#")
14016
14017 (define_insn "*fp_jcc_1_387"
14018   [(set (pc)
14019         (if_then_else (match_operator 0 "comparison_operator"
14020                         [(match_operand 1 "register_operand" "f")
14021                          (match_operand 2 "register_operand" "f")])
14022           (label_ref (match_operand 3 "" ""))
14023           (pc)))
14024    (clobber (reg:CCFP FPSR_REG))
14025    (clobber (reg:CCFP FLAGS_REG))]
14026   "TARGET_CMOVE && TARGET_80387
14027    && FLOAT_MODE_P (GET_MODE (operands[1]))
14028    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14029    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14030   "#")
14031
14032 (define_insn "*fp_jcc_2_mixed"
14033   [(set (pc)
14034         (if_then_else (match_operator 0 "comparison_operator"
14035                         [(match_operand 1 "register_operand" "f,x")
14036                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14037           (pc)
14038           (label_ref (match_operand 3 "" ""))))
14039    (clobber (reg:CCFP FPSR_REG))
14040    (clobber (reg:CCFP FLAGS_REG))]
14041   "TARGET_MIX_SSE_I387
14042    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14043    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14044    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14045   "#")
14046
14047 (define_insn "*fp_jcc_2_sse"
14048   [(set (pc)
14049         (if_then_else (match_operator 0 "comparison_operator"
14050                         [(match_operand 1 "register_operand" "x")
14051                          (match_operand 2 "nonimmediate_operand" "xm")])
14052           (pc)
14053           (label_ref (match_operand 3 "" ""))))
14054    (clobber (reg:CCFP FPSR_REG))
14055    (clobber (reg:CCFP FLAGS_REG))]
14056   "TARGET_SSE_MATH
14057    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14058    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14059    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14060   "#")
14061
14062 (define_insn "*fp_jcc_2_387"
14063   [(set (pc)
14064         (if_then_else (match_operator 0 "comparison_operator"
14065                         [(match_operand 1 "register_operand" "f")
14066                          (match_operand 2 "register_operand" "f")])
14067           (pc)
14068           (label_ref (match_operand 3 "" ""))))
14069    (clobber (reg:CCFP FPSR_REG))
14070    (clobber (reg:CCFP FLAGS_REG))]
14071   "TARGET_CMOVE && TARGET_80387
14072    && FLOAT_MODE_P (GET_MODE (operands[1]))
14073    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14074    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14075   "#")
14076
14077 (define_insn "*fp_jcc_3_387"
14078   [(set (pc)
14079         (if_then_else (match_operator 0 "comparison_operator"
14080                         [(match_operand 1 "register_operand" "f")
14081                          (match_operand 2 "nonimmediate_operand" "fm")])
14082           (label_ref (match_operand 3 "" ""))
14083           (pc)))
14084    (clobber (reg:CCFP FPSR_REG))
14085    (clobber (reg:CCFP FLAGS_REG))
14086    (clobber (match_scratch:HI 4 "=a"))]
14087   "TARGET_80387
14088    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14089    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14090    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14091    && SELECT_CC_MODE (GET_CODE (operands[0]),
14092                       operands[1], operands[2]) == CCFPmode
14093    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14094   "#")
14095
14096 (define_insn "*fp_jcc_4_387"
14097   [(set (pc)
14098         (if_then_else (match_operator 0 "comparison_operator"
14099                         [(match_operand 1 "register_operand" "f")
14100                          (match_operand 2 "nonimmediate_operand" "fm")])
14101           (pc)
14102           (label_ref (match_operand 3 "" ""))))
14103    (clobber (reg:CCFP FPSR_REG))
14104    (clobber (reg:CCFP FLAGS_REG))
14105    (clobber (match_scratch:HI 4 "=a"))]
14106   "TARGET_80387
14107    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14108    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14109    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14110    && SELECT_CC_MODE (GET_CODE (operands[0]),
14111                       operands[1], operands[2]) == CCFPmode
14112    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14113   "#")
14114
14115 (define_insn "*fp_jcc_5_387"
14116   [(set (pc)
14117         (if_then_else (match_operator 0 "comparison_operator"
14118                         [(match_operand 1 "register_operand" "f")
14119                          (match_operand 2 "register_operand" "f")])
14120           (label_ref (match_operand 3 "" ""))
14121           (pc)))
14122    (clobber (reg:CCFP FPSR_REG))
14123    (clobber (reg:CCFP FLAGS_REG))
14124    (clobber (match_scratch:HI 4 "=a"))]
14125   "TARGET_80387
14126    && FLOAT_MODE_P (GET_MODE (operands[1]))
14127    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14128    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14129   "#")
14130
14131 (define_insn "*fp_jcc_6_387"
14132   [(set (pc)
14133         (if_then_else (match_operator 0 "comparison_operator"
14134                         [(match_operand 1 "register_operand" "f")
14135                          (match_operand 2 "register_operand" "f")])
14136           (pc)
14137           (label_ref (match_operand 3 "" ""))))
14138    (clobber (reg:CCFP FPSR_REG))
14139    (clobber (reg:CCFP FLAGS_REG))
14140    (clobber (match_scratch:HI 4 "=a"))]
14141   "TARGET_80387
14142    && FLOAT_MODE_P (GET_MODE (operands[1]))
14143    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14144    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14145   "#")
14146
14147 (define_insn "*fp_jcc_7_387"
14148   [(set (pc)
14149         (if_then_else (match_operator 0 "comparison_operator"
14150                         [(match_operand 1 "register_operand" "f")
14151                          (match_operand 2 "const0_operand" "X")])
14152           (label_ref (match_operand 3 "" ""))
14153           (pc)))
14154    (clobber (reg:CCFP FPSR_REG))
14155    (clobber (reg:CCFP FLAGS_REG))
14156    (clobber (match_scratch:HI 4 "=a"))]
14157   "TARGET_80387
14158    && FLOAT_MODE_P (GET_MODE (operands[1]))
14159    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14160    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14161    && SELECT_CC_MODE (GET_CODE (operands[0]),
14162                       operands[1], operands[2]) == CCFPmode
14163    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14164   "#")
14165
14166 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14167 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14168 ;; with a precedence over other operators and is always put in the first
14169 ;; place. Swap condition and operands to match ficom instruction.
14170
14171 (define_insn "*fp_jcc_8<mode>_387"
14172   [(set (pc)
14173         (if_then_else (match_operator 0 "comparison_operator"
14174                         [(match_operator 1 "float_operator"
14175                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14176                            (match_operand 3 "register_operand" "f,f")])
14177           (label_ref (match_operand 4 "" ""))
14178           (pc)))
14179    (clobber (reg:CCFP FPSR_REG))
14180    (clobber (reg:CCFP FLAGS_REG))
14181    (clobber (match_scratch:HI 5 "=a,a"))]
14182   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14183    && FLOAT_MODE_P (GET_MODE (operands[3]))
14184    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14185    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14186    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14187    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14188   "#")
14189
14190 (define_split
14191   [(set (pc)
14192         (if_then_else (match_operator 0 "comparison_operator"
14193                         [(match_operand 1 "register_operand" "")
14194                          (match_operand 2 "nonimmediate_operand" "")])
14195           (match_operand 3 "" "")
14196           (match_operand 4 "" "")))
14197    (clobber (reg:CCFP FPSR_REG))
14198    (clobber (reg:CCFP FLAGS_REG))]
14199   "reload_completed"
14200   [(const_int 0)]
14201 {
14202   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14203                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14204   DONE;
14205 })
14206
14207 (define_split
14208   [(set (pc)
14209         (if_then_else (match_operator 0 "comparison_operator"
14210                         [(match_operand 1 "register_operand" "")
14211                          (match_operand 2 "general_operand" "")])
14212           (match_operand 3 "" "")
14213           (match_operand 4 "" "")))
14214    (clobber (reg:CCFP FPSR_REG))
14215    (clobber (reg:CCFP FLAGS_REG))
14216    (clobber (match_scratch:HI 5 "=a"))]
14217   "reload_completed"
14218   [(const_int 0)]
14219 {
14220   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14221                         operands[3], operands[4], operands[5], NULL_RTX);
14222   DONE;
14223 })
14224
14225 (define_split
14226   [(set (pc)
14227         (if_then_else (match_operator 0 "comparison_operator"
14228                         [(match_operator 1 "float_operator"
14229                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14230                            (match_operand 3 "register_operand" "")])
14231           (match_operand 4 "" "")
14232           (match_operand 5 "" "")))
14233    (clobber (reg:CCFP FPSR_REG))
14234    (clobber (reg:CCFP FLAGS_REG))
14235    (clobber (match_scratch:HI 6 "=a"))]
14236   "reload_completed"
14237   [(const_int 0)]
14238 {
14239   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14240   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14241                         operands[3], operands[7],
14242                         operands[4], operands[5], operands[6], NULL_RTX);
14243   DONE;
14244 })
14245
14246 ;; %%% Kill this when reload knows how to do it.
14247 (define_split
14248   [(set (pc)
14249         (if_then_else (match_operator 0 "comparison_operator"
14250                         [(match_operator 1 "float_operator"
14251                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14252                            (match_operand 3 "register_operand" "")])
14253           (match_operand 4 "" "")
14254           (match_operand 5 "" "")))
14255    (clobber (reg:CCFP FPSR_REG))
14256    (clobber (reg:CCFP FLAGS_REG))
14257    (clobber (match_scratch:HI 6 "=a"))]
14258   "reload_completed"
14259   [(const_int 0)]
14260 {
14261   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14262   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14263   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14264                         operands[3], operands[7],
14265                         operands[4], operands[5], operands[6], operands[2]);
14266   DONE;
14267 })
14268 \f
14269 ;; Unconditional and other jump instructions
14270
14271 (define_insn "jump"
14272   [(set (pc)
14273         (label_ref (match_operand 0 "" "")))]
14274   ""
14275   "jmp\t%l0"
14276   [(set_attr "type" "ibr")
14277    (set (attr "length")
14278            (if_then_else (and (ge (minus (match_dup 0) (pc))
14279                                   (const_int -126))
14280                               (lt (minus (match_dup 0) (pc))
14281                                   (const_int 128)))
14282              (const_int 2)
14283              (const_int 5)))
14284    (set_attr "modrm" "0")])
14285
14286 (define_expand "indirect_jump"
14287   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
14288   ""
14289   "")
14290
14291 (define_insn "*indirect_jump"
14292   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14293   "!TARGET_64BIT"
14294   "jmp\t%A0"
14295   [(set_attr "type" "ibr")
14296    (set_attr "length_immediate" "0")])
14297
14298 (define_insn "*indirect_jump_rtx64"
14299   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14300   "TARGET_64BIT"
14301   "jmp\t%A0"
14302   [(set_attr "type" "ibr")
14303    (set_attr "length_immediate" "0")])
14304
14305 (define_expand "tablejump"
14306   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14307               (use (label_ref (match_operand 1 "" "")))])]
14308   ""
14309 {
14310   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14311      relative.  Convert the relative address to an absolute address.  */
14312   if (flag_pic)
14313     {
14314       rtx op0, op1;
14315       enum rtx_code code;
14316
14317       if (TARGET_64BIT)
14318         {
14319           code = PLUS;
14320           op0 = operands[0];
14321           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14322         }
14323       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14324         {
14325           code = PLUS;
14326           op0 = operands[0];
14327           op1 = pic_offset_table_rtx;
14328         }
14329       else
14330         {
14331           code = MINUS;
14332           op0 = pic_offset_table_rtx;
14333           op1 = operands[0];
14334         }
14335
14336       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14337                                          OPTAB_DIRECT);
14338     }
14339 })
14340
14341 (define_insn "*tablejump_1"
14342   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14343    (use (label_ref (match_operand 1 "" "")))]
14344   "!TARGET_64BIT"
14345   "jmp\t%A0"
14346   [(set_attr "type" "ibr")
14347    (set_attr "length_immediate" "0")])
14348
14349 (define_insn "*tablejump_1_rtx64"
14350   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14351    (use (label_ref (match_operand 1 "" "")))]
14352   "TARGET_64BIT"
14353   "jmp\t%A0"
14354   [(set_attr "type" "ibr")
14355    (set_attr "length_immediate" "0")])
14356 \f
14357 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14358
14359 (define_peephole2
14360   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14361    (set (match_operand:QI 1 "register_operand" "")
14362         (match_operator:QI 2 "ix86_comparison_operator"
14363           [(reg FLAGS_REG) (const_int 0)]))
14364    (set (match_operand 3 "q_regs_operand" "")
14365         (zero_extend (match_dup 1)))]
14366   "(peep2_reg_dead_p (3, operands[1])
14367     || operands_match_p (operands[1], operands[3]))
14368    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14369   [(set (match_dup 4) (match_dup 0))
14370    (set (strict_low_part (match_dup 5))
14371         (match_dup 2))]
14372 {
14373   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14374   operands[5] = gen_lowpart (QImode, operands[3]);
14375   ix86_expand_clear (operands[3]);
14376 })
14377
14378 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14379
14380 (define_peephole2
14381   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14382    (set (match_operand:QI 1 "register_operand" "")
14383         (match_operator:QI 2 "ix86_comparison_operator"
14384           [(reg FLAGS_REG) (const_int 0)]))
14385    (parallel [(set (match_operand 3 "q_regs_operand" "")
14386                    (zero_extend (match_dup 1)))
14387               (clobber (reg:CC FLAGS_REG))])]
14388   "(peep2_reg_dead_p (3, operands[1])
14389     || operands_match_p (operands[1], operands[3]))
14390    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14391   [(set (match_dup 4) (match_dup 0))
14392    (set (strict_low_part (match_dup 5))
14393         (match_dup 2))]
14394 {
14395   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14396   operands[5] = gen_lowpart (QImode, operands[3]);
14397   ix86_expand_clear (operands[3]);
14398 })
14399 \f
14400 ;; Call instructions.
14401
14402 ;; The predicates normally associated with named expanders are not properly
14403 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14404 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14405
14406 ;; Call subroutine returning no value.
14407
14408 (define_expand "call_pop"
14409   [(parallel [(call (match_operand:QI 0 "" "")
14410                     (match_operand:SI 1 "" ""))
14411               (set (reg:SI SP_REG)
14412                    (plus:SI (reg:SI SP_REG)
14413                             (match_operand:SI 3 "" "")))])]
14414   "!TARGET_64BIT"
14415 {
14416   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14417   DONE;
14418 })
14419
14420 (define_insn "*call_pop_0"
14421   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14422          (match_operand:SI 1 "" ""))
14423    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14424                             (match_operand:SI 2 "immediate_operand" "")))]
14425   "!TARGET_64BIT"
14426 {
14427   if (SIBLING_CALL_P (insn))
14428     return "jmp\t%P0";
14429   else
14430     return "call\t%P0";
14431 }
14432   [(set_attr "type" "call")])
14433
14434 (define_insn "*call_pop_1"
14435   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14436          (match_operand:SI 1 "" ""))
14437    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14438                             (match_operand:SI 2 "immediate_operand" "i")))]
14439   "!TARGET_64BIT"
14440 {
14441   if (constant_call_address_operand (operands[0], Pmode))
14442     {
14443       if (SIBLING_CALL_P (insn))
14444         return "jmp\t%P0";
14445       else
14446         return "call\t%P0";
14447     }
14448   if (SIBLING_CALL_P (insn))
14449     return "jmp\t%A0";
14450   else
14451     return "call\t%A0";
14452 }
14453   [(set_attr "type" "call")])
14454
14455 (define_expand "call"
14456   [(call (match_operand:QI 0 "" "")
14457          (match_operand 1 "" ""))
14458    (use (match_operand 2 "" ""))]
14459   ""
14460 {
14461   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14462   DONE;
14463 })
14464
14465 (define_expand "sibcall"
14466   [(call (match_operand:QI 0 "" "")
14467          (match_operand 1 "" ""))
14468    (use (match_operand 2 "" ""))]
14469   ""
14470 {
14471   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14472   DONE;
14473 })
14474
14475 (define_insn "*call_0"
14476   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14477          (match_operand 1 "" ""))]
14478   ""
14479 {
14480   if (SIBLING_CALL_P (insn))
14481     return "jmp\t%P0";
14482   else
14483     return "call\t%P0";
14484 }
14485   [(set_attr "type" "call")])
14486
14487 (define_insn "*call_1"
14488   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14489          (match_operand 1 "" ""))]
14490   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14491 {
14492   if (constant_call_address_operand (operands[0], Pmode))
14493     return "call\t%P0";
14494   return "call\t%A0";
14495 }
14496   [(set_attr "type" "call")])
14497
14498 (define_insn "*sibcall_1"
14499   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14500          (match_operand 1 "" ""))]
14501   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14502 {
14503   if (constant_call_address_operand (operands[0], Pmode))
14504     return "jmp\t%P0";
14505   return "jmp\t%A0";
14506 }
14507   [(set_attr "type" "call")])
14508
14509 (define_insn "*call_1_rex64"
14510   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14511          (match_operand 1 "" ""))]
14512   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14513 {
14514   if (constant_call_address_operand (operands[0], Pmode))
14515     return "call\t%P0";
14516   return "call\t%A0";
14517 }
14518   [(set_attr "type" "call")])
14519
14520 (define_insn "*sibcall_1_rex64"
14521   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14522          (match_operand 1 "" ""))]
14523   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14524   "jmp\t%P0"
14525   [(set_attr "type" "call")])
14526
14527 (define_insn "*sibcall_1_rex64_v"
14528   [(call (mem:QI (reg:DI R11_REG))
14529          (match_operand 0 "" ""))]
14530   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14531   "jmp\t*%%r11"
14532   [(set_attr "type" "call")])
14533
14534
14535 ;; Call subroutine, returning value in operand 0
14536
14537 (define_expand "call_value_pop"
14538   [(parallel [(set (match_operand 0 "" "")
14539                    (call (match_operand:QI 1 "" "")
14540                          (match_operand:SI 2 "" "")))
14541               (set (reg:SI SP_REG)
14542                    (plus:SI (reg:SI SP_REG)
14543                             (match_operand:SI 4 "" "")))])]
14544   "!TARGET_64BIT"
14545 {
14546   ix86_expand_call (operands[0], operands[1], operands[2],
14547                     operands[3], operands[4], 0);
14548   DONE;
14549 })
14550
14551 (define_expand "call_value"
14552   [(set (match_operand 0 "" "")
14553         (call (match_operand:QI 1 "" "")
14554               (match_operand:SI 2 "" "")))
14555    (use (match_operand:SI 3 "" ""))]
14556   ;; Operand 2 not used on the i386.
14557   ""
14558 {
14559   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14560   DONE;
14561 })
14562
14563 (define_expand "sibcall_value"
14564   [(set (match_operand 0 "" "")
14565         (call (match_operand:QI 1 "" "")
14566               (match_operand:SI 2 "" "")))
14567    (use (match_operand:SI 3 "" ""))]
14568   ;; Operand 2 not used on the i386.
14569   ""
14570 {
14571   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14572   DONE;
14573 })
14574
14575 ;; Call subroutine returning any type.
14576
14577 (define_expand "untyped_call"
14578   [(parallel [(call (match_operand 0 "" "")
14579                     (const_int 0))
14580               (match_operand 1 "" "")
14581               (match_operand 2 "" "")])]
14582   ""
14583 {
14584   int i;
14585
14586   /* In order to give reg-stack an easier job in validating two
14587      coprocessor registers as containing a possible return value,
14588      simply pretend the untyped call returns a complex long double
14589      value.  */
14590
14591   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14592                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14593                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14594                     NULL, 0);
14595
14596   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14597     {
14598       rtx set = XVECEXP (operands[2], 0, i);
14599       emit_move_insn (SET_DEST (set), SET_SRC (set));
14600     }
14601
14602   /* The optimizer does not know that the call sets the function value
14603      registers we stored in the result block.  We avoid problems by
14604      claiming that all hard registers are used and clobbered at this
14605      point.  */
14606   emit_insn (gen_blockage (const0_rtx));
14607
14608   DONE;
14609 })
14610 \f
14611 ;; Prologue and epilogue instructions
14612
14613 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14614 ;; all of memory.  This blocks insns from being moved across this point.
14615
14616 (define_insn "blockage"
14617   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14618   ""
14619   ""
14620   [(set_attr "length" "0")])
14621
14622 ;; Insn emitted into the body of a function to return from a function.
14623 ;; This is only done if the function's epilogue is known to be simple.
14624 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14625
14626 (define_expand "return"
14627   [(return)]
14628   "ix86_can_use_return_insn_p ()"
14629 {
14630   if (current_function_pops_args)
14631     {
14632       rtx popc = GEN_INT (current_function_pops_args);
14633       emit_jump_insn (gen_return_pop_internal (popc));
14634       DONE;
14635     }
14636 })
14637
14638 (define_insn "return_internal"
14639   [(return)]
14640   "reload_completed"
14641   "ret"
14642   [(set_attr "length" "1")
14643    (set_attr "length_immediate" "0")
14644    (set_attr "modrm" "0")])
14645
14646 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14647 ;; instruction Athlon and K8 have.
14648
14649 (define_insn "return_internal_long"
14650   [(return)
14651    (unspec [(const_int 0)] UNSPEC_REP)]
14652   "reload_completed"
14653   "rep {;} ret"
14654   [(set_attr "length" "1")
14655    (set_attr "length_immediate" "0")
14656    (set_attr "prefix_rep" "1")
14657    (set_attr "modrm" "0")])
14658
14659 (define_insn "return_pop_internal"
14660   [(return)
14661    (use (match_operand:SI 0 "const_int_operand" ""))]
14662   "reload_completed"
14663   "ret\t%0"
14664   [(set_attr "length" "3")
14665    (set_attr "length_immediate" "2")
14666    (set_attr "modrm" "0")])
14667
14668 (define_insn "return_indirect_internal"
14669   [(return)
14670    (use (match_operand:SI 0 "register_operand" "r"))]
14671   "reload_completed"
14672   "jmp\t%A0"
14673   [(set_attr "type" "ibr")
14674    (set_attr "length_immediate" "0")])
14675
14676 (define_insn "nop"
14677   [(const_int 0)]
14678   ""
14679   "nop"
14680   [(set_attr "length" "1")
14681    (set_attr "length_immediate" "0")
14682    (set_attr "modrm" "0")])
14683
14684 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14685 ;; branch prediction penalty for the third jump in a 16-byte
14686 ;; block on K8.
14687
14688 (define_insn "align"
14689   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14690   ""
14691 {
14692 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14693   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14694 #else
14695   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14696      The align insn is used to avoid 3 jump instructions in the row to improve
14697      branch prediction and the benefits hardly outweigh the cost of extra 8
14698      nops on the average inserted by full alignment pseudo operation.  */
14699 #endif
14700   return "";
14701 }
14702   [(set_attr "length" "16")])
14703
14704 (define_expand "prologue"
14705   [(const_int 1)]
14706   ""
14707   "ix86_expand_prologue (); DONE;")
14708
14709 (define_insn "set_got"
14710   [(set (match_operand:SI 0 "register_operand" "=r")
14711         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14712    (clobber (reg:CC FLAGS_REG))]
14713   "!TARGET_64BIT"
14714   { return output_set_got (operands[0], NULL_RTX); }
14715   [(set_attr "type" "multi")
14716    (set_attr "length" "12")])
14717
14718 (define_insn "set_got_labelled"
14719   [(set (match_operand:SI 0 "register_operand" "=r")
14720         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14721          UNSPEC_SET_GOT))
14722    (clobber (reg:CC FLAGS_REG))]
14723   "!TARGET_64BIT"
14724   { return output_set_got (operands[0], operands[1]); }
14725   [(set_attr "type" "multi")
14726    (set_attr "length" "12")])
14727
14728 (define_insn "set_got_rex64"
14729   [(set (match_operand:DI 0 "register_operand" "=r")
14730         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14731   "TARGET_64BIT"
14732   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14733   [(set_attr "type" "lea")
14734    (set_attr "length" "6")])
14735
14736 (define_expand "epilogue"
14737   [(const_int 1)]
14738   ""
14739   "ix86_expand_epilogue (1); DONE;")
14740
14741 (define_expand "sibcall_epilogue"
14742   [(const_int 1)]
14743   ""
14744   "ix86_expand_epilogue (0); DONE;")
14745
14746 (define_expand "eh_return"
14747   [(use (match_operand 0 "register_operand" ""))]
14748   ""
14749 {
14750   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14751
14752   /* Tricky bit: we write the address of the handler to which we will
14753      be returning into someone else's stack frame, one word below the
14754      stack address we wish to restore.  */
14755   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14756   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14757   tmp = gen_rtx_MEM (Pmode, tmp);
14758   emit_move_insn (tmp, ra);
14759
14760   if (Pmode == SImode)
14761     emit_jump_insn (gen_eh_return_si (sa));
14762   else
14763     emit_jump_insn (gen_eh_return_di (sa));
14764   emit_barrier ();
14765   DONE;
14766 })
14767
14768 (define_insn_and_split "eh_return_si"
14769   [(set (pc)
14770         (unspec [(match_operand:SI 0 "register_operand" "c")]
14771                  UNSPEC_EH_RETURN))]
14772   "!TARGET_64BIT"
14773   "#"
14774   "reload_completed"
14775   [(const_int 1)]
14776   "ix86_expand_epilogue (2); DONE;")
14777
14778 (define_insn_and_split "eh_return_di"
14779   [(set (pc)
14780         (unspec [(match_operand:DI 0 "register_operand" "c")]
14781                  UNSPEC_EH_RETURN))]
14782   "TARGET_64BIT"
14783   "#"
14784   "reload_completed"
14785   [(const_int 1)]
14786   "ix86_expand_epilogue (2); DONE;")
14787
14788 (define_insn "leave"
14789   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14790    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14791    (clobber (mem:BLK (scratch)))]
14792   "!TARGET_64BIT"
14793   "leave"
14794   [(set_attr "type" "leave")])
14795
14796 (define_insn "leave_rex64"
14797   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14798    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14799    (clobber (mem:BLK (scratch)))]
14800   "TARGET_64BIT"
14801   "leave"
14802   [(set_attr "type" "leave")])
14803 \f
14804 (define_expand "ffssi2"
14805   [(parallel
14806      [(set (match_operand:SI 0 "register_operand" "")
14807            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14808       (clobber (match_scratch:SI 2 ""))
14809       (clobber (reg:CC FLAGS_REG))])]
14810   ""
14811   "")
14812
14813 (define_insn_and_split "*ffs_cmove"
14814   [(set (match_operand:SI 0 "register_operand" "=r")
14815         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14816    (clobber (match_scratch:SI 2 "=&r"))
14817    (clobber (reg:CC FLAGS_REG))]
14818   "TARGET_CMOVE"
14819   "#"
14820   "&& reload_completed"
14821   [(set (match_dup 2) (const_int -1))
14822    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14823               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14824    (set (match_dup 0) (if_then_else:SI
14825                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14826                         (match_dup 2)
14827                         (match_dup 0)))
14828    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14829               (clobber (reg:CC FLAGS_REG))])]
14830   "")
14831
14832 (define_insn_and_split "*ffs_no_cmove"
14833   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14834         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14835    (clobber (match_scratch:SI 2 "=&q"))
14836    (clobber (reg:CC FLAGS_REG))]
14837   ""
14838   "#"
14839   "reload_completed"
14840   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14841               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14842    (set (strict_low_part (match_dup 3))
14843         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14844    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14845               (clobber (reg:CC FLAGS_REG))])
14846    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14847               (clobber (reg:CC FLAGS_REG))])
14848    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14849               (clobber (reg:CC FLAGS_REG))])]
14850 {
14851   operands[3] = gen_lowpart (QImode, operands[2]);
14852   ix86_expand_clear (operands[2]);
14853 })
14854
14855 (define_insn "*ffssi_1"
14856   [(set (reg:CCZ FLAGS_REG)
14857         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14858                      (const_int 0)))
14859    (set (match_operand:SI 0 "register_operand" "=r")
14860         (ctz:SI (match_dup 1)))]
14861   ""
14862   "bsf{l}\t{%1, %0|%0, %1}"
14863   [(set_attr "prefix_0f" "1")])
14864
14865 (define_expand "ffsdi2"
14866   [(parallel
14867      [(set (match_operand:DI 0 "register_operand" "")
14868            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14869       (clobber (match_scratch:DI 2 ""))
14870       (clobber (reg:CC FLAGS_REG))])]
14871   "TARGET_64BIT && TARGET_CMOVE"
14872   "")
14873
14874 (define_insn_and_split "*ffs_rex64"
14875   [(set (match_operand:DI 0 "register_operand" "=r")
14876         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14877    (clobber (match_scratch:DI 2 "=&r"))
14878    (clobber (reg:CC FLAGS_REG))]
14879   "TARGET_64BIT && TARGET_CMOVE"
14880   "#"
14881   "&& reload_completed"
14882   [(set (match_dup 2) (const_int -1))
14883    (parallel [(set (reg:CCZ FLAGS_REG)
14884                    (compare:CCZ (match_dup 1) (const_int 0)))
14885               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14886    (set (match_dup 0) (if_then_else:DI
14887                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14888                         (match_dup 2)
14889                         (match_dup 0)))
14890    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14891               (clobber (reg:CC FLAGS_REG))])]
14892   "")
14893
14894 (define_insn "*ffsdi_1"
14895   [(set (reg:CCZ FLAGS_REG)
14896         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14897                      (const_int 0)))
14898    (set (match_operand:DI 0 "register_operand" "=r")
14899         (ctz:DI (match_dup 1)))]
14900   "TARGET_64BIT"
14901   "bsf{q}\t{%1, %0|%0, %1}"
14902   [(set_attr "prefix_0f" "1")])
14903
14904 (define_insn "ctzsi2"
14905   [(set (match_operand:SI 0 "register_operand" "=r")
14906         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14907    (clobber (reg:CC FLAGS_REG))]
14908   ""
14909   "bsf{l}\t{%1, %0|%0, %1}"
14910   [(set_attr "prefix_0f" "1")])
14911
14912 (define_insn "ctzdi2"
14913   [(set (match_operand:DI 0 "register_operand" "=r")
14914         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14915    (clobber (reg:CC FLAGS_REG))]
14916   "TARGET_64BIT"
14917   "bsf{q}\t{%1, %0|%0, %1}"
14918   [(set_attr "prefix_0f" "1")])
14919
14920 (define_expand "clzsi2"
14921   [(parallel
14922      [(set (match_operand:SI 0 "register_operand" "")
14923            (minus:SI (const_int 31)
14924                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14925       (clobber (reg:CC FLAGS_REG))])
14926    (parallel
14927      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14928       (clobber (reg:CC FLAGS_REG))])]
14929   ""
14930 {
14931   if (TARGET_ABM)
14932     {
14933       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14934       DONE;
14935     }
14936 })
14937
14938 (define_insn "clzsi2_abm"
14939   [(set (match_operand:SI 0 "register_operand" "=r")
14940         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14941    (clobber (reg:CC FLAGS_REG))]
14942   "TARGET_ABM"
14943   "lzcnt{l}\t{%1, %0|%0, %1}"
14944   [(set_attr "prefix_rep" "1")
14945    (set_attr "type" "bitmanip")
14946    (set_attr "mode" "SI")])
14947
14948 (define_insn "*bsr"
14949   [(set (match_operand:SI 0 "register_operand" "=r")
14950         (minus:SI (const_int 31)
14951                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14952    (clobber (reg:CC FLAGS_REG))]
14953   ""
14954   "bsr{l}\t{%1, %0|%0, %1}"
14955   [(set_attr "prefix_0f" "1")
14956    (set_attr "mode" "SI")])
14957
14958 (define_insn "popcountsi2"
14959   [(set (match_operand:SI 0 "register_operand" "=r")
14960         (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14961    (clobber (reg:CC FLAGS_REG))]
14962   "TARGET_POPCNT"
14963   "popcnt{l}\t{%1, %0|%0, %1}"
14964   [(set_attr "prefix_rep" "1")
14965    (set_attr "type" "bitmanip")
14966    (set_attr "mode" "SI")])
14967
14968 (define_insn "*popcountsi2_cmp"
14969   [(set (reg FLAGS_REG)
14970         (compare
14971           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14972           (const_int 0)))
14973    (set (match_operand:SI 0 "register_operand" "=r")
14974         (popcount:SI (match_dup 1)))]
14975   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14976   "popcnt{l}\t{%1, %0|%0, %1}"
14977   [(set_attr "prefix_rep" "1")
14978    (set_attr "type" "bitmanip")
14979    (set_attr "mode" "SI")])
14980
14981 (define_insn "*popcountsi2_cmp_zext"
14982   [(set (reg FLAGS_REG)
14983         (compare
14984           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14985           (const_int 0)))
14986    (set (match_operand:DI 0 "register_operand" "=r")
14987         (zero_extend:DI(popcount:SI (match_dup 1))))]
14988   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14989   "popcnt{l}\t{%1, %0|%0, %1}"
14990   [(set_attr "prefix_rep" "1")
14991    (set_attr "type" "bitmanip")
14992    (set_attr "mode" "SI")])
14993
14994 (define_expand "bswapsi2"
14995   [(set (match_operand:SI 0 "register_operand" "")
14996         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
14997   ""
14998 {
14999   if (!TARGET_BSWAP)
15000     {
15001       rtx x = operands[0];
15002
15003       emit_move_insn (x, operands[1]);
15004       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15005       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15006       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15007       DONE;
15008     }
15009 })
15010
15011 (define_insn "*bswapsi_1"
15012   [(set (match_operand:SI 0 "register_operand" "=r")
15013         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15014   "TARGET_BSWAP"
15015   "bswap\t%0"
15016   [(set_attr "prefix_0f" "1")
15017    (set_attr "length" "2")])
15018
15019 (define_insn "bswaphi_lowpart"
15020   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q"))
15021         (bswap:HI (match_dup 0)))]
15022   ""
15023   "xchg{b}\t%h0, %b0"
15024   [(set_attr "type" "alu1")
15025    (set_attr "mode" "QI")
15026    (set_attr "pent_pair" "np")
15027    (set_attr "athlon_decode" "vector")
15028    (set_attr "amdfam10_decode" "double")])
15029
15030 (define_insn "bswapdi2"
15031   [(set (match_operand:DI 0 "register_operand" "=r")
15032         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15033   "TARGET_64BIT"
15034   "bswap\t%0"
15035   [(set_attr "prefix_0f" "1")
15036    (set_attr "length" "3")])
15037
15038 (define_expand "clzdi2"
15039   [(parallel
15040      [(set (match_operand:DI 0 "register_operand" "")
15041            (minus:DI (const_int 63)
15042                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15043       (clobber (reg:CC FLAGS_REG))])
15044    (parallel
15045      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15046       (clobber (reg:CC FLAGS_REG))])]
15047   "TARGET_64BIT"
15048 {
15049   if (TARGET_ABM)
15050     {
15051       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15052       DONE;
15053     }
15054 })
15055
15056 (define_insn "clzdi2_abm"
15057   [(set (match_operand:DI 0 "register_operand" "=r")
15058         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15059    (clobber (reg:CC FLAGS_REG))]
15060   "TARGET_64BIT && TARGET_ABM"
15061   "lzcnt{q}\t{%1, %0|%0, %1}"
15062   [(set_attr "prefix_rep" "1")
15063    (set_attr "type" "bitmanip")
15064    (set_attr "mode" "DI")])
15065
15066 (define_insn "*bsr_rex64"
15067   [(set (match_operand:DI 0 "register_operand" "=r")
15068         (minus:DI (const_int 63)
15069                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15070    (clobber (reg:CC FLAGS_REG))]
15071   "TARGET_64BIT"
15072   "bsr{q}\t{%1, %0|%0, %1}"
15073   [(set_attr "prefix_0f" "1")
15074    (set_attr "mode" "DI")])
15075
15076 (define_insn "popcountdi2"
15077   [(set (match_operand:DI 0 "register_operand" "=r")
15078         (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15079    (clobber (reg:CC FLAGS_REG))]
15080   "TARGET_64BIT && TARGET_POPCNT"
15081   "popcnt{q}\t{%1, %0|%0, %1}"
15082   [(set_attr "prefix_rep" "1")
15083    (set_attr "type" "bitmanip")
15084    (set_attr "mode" "DI")])
15085
15086 (define_insn "*popcountdi2_cmp"
15087   [(set (reg FLAGS_REG)
15088         (compare
15089           (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15090           (const_int 0)))
15091    (set (match_operand:DI 0 "register_operand" "=r")
15092         (popcount:DI (match_dup 1)))]
15093   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15094   "popcnt{q}\t{%1, %0|%0, %1}"
15095   [(set_attr "prefix_rep" "1")
15096    (set_attr "type" "bitmanip")
15097    (set_attr "mode" "DI")])
15098
15099 (define_expand "clzhi2"
15100   [(parallel
15101      [(set (match_operand:HI 0 "register_operand" "")
15102            (minus:HI (const_int 15)
15103                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15104       (clobber (reg:CC FLAGS_REG))])
15105    (parallel
15106      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15107       (clobber (reg:CC FLAGS_REG))])]
15108   ""
15109 {
15110   if (TARGET_ABM)
15111     {
15112       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15113       DONE;
15114     }
15115 })
15116
15117 (define_insn "clzhi2_abm"
15118   [(set (match_operand:HI 0 "register_operand" "=r")
15119         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15120    (clobber (reg:CC FLAGS_REG))]
15121   "TARGET_ABM"
15122   "lzcnt{w}\t{%1, %0|%0, %1}"
15123   [(set_attr "prefix_rep" "1")
15124    (set_attr "type" "bitmanip")
15125    (set_attr "mode" "HI")])
15126
15127 (define_insn "*bsrhi"
15128   [(set (match_operand:HI 0 "register_operand" "=r")
15129         (minus:HI (const_int 15)
15130                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15131    (clobber (reg:CC FLAGS_REG))]
15132   ""
15133   "bsr{w}\t{%1, %0|%0, %1}"
15134   [(set_attr "prefix_0f" "1")
15135    (set_attr "mode" "HI")])
15136
15137 (define_insn "popcounthi2"
15138   [(set (match_operand:HI 0 "register_operand" "=r")
15139         (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15140    (clobber (reg:CC FLAGS_REG))]
15141   "TARGET_POPCNT"
15142   "popcnt{w}\t{%1, %0|%0, %1}"
15143   [(set_attr "prefix_rep" "1")
15144    (set_attr "type" "bitmanip")
15145    (set_attr "mode" "HI")])
15146
15147 (define_insn "*popcounthi2_cmp"
15148   [(set (reg FLAGS_REG)
15149         (compare
15150           (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15151           (const_int 0)))
15152    (set (match_operand:HI 0 "register_operand" "=r")
15153         (popcount:HI (match_dup 1)))]
15154   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15155   "popcnt{w}\t{%1, %0|%0, %1}"
15156   [(set_attr "prefix_rep" "1")
15157    (set_attr "type" "bitmanip")
15158    (set_attr "mode" "HI")])
15159
15160 (define_expand "paritydi2"
15161   [(set (match_operand:DI 0 "register_operand" "")
15162         (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
15163   "! TARGET_POPCNT"
15164 {
15165   rtx scratch = gen_reg_rtx (QImode);
15166   rtx cond;
15167
15168   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15169                                 NULL_RTX, operands[1]));
15170
15171   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15172                          gen_rtx_REG (CCmode, FLAGS_REG),
15173                          const0_rtx);
15174   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15175
15176   if (TARGET_64BIT)
15177     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15178   else
15179     {
15180       rtx tmp = gen_reg_rtx (SImode);
15181
15182       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15183       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15184     }
15185   DONE;
15186 })
15187
15188 (define_insn_and_split "paritydi2_cmp"
15189   [(set (reg:CC FLAGS_REG)
15190         (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m")))
15191    (clobber (match_scratch:DI 0 "=r,X"))
15192    (clobber (match_scratch:SI 1 "=r,r"))
15193    (clobber (match_scratch:HI 2 "=Q,Q"))]
15194   "! TARGET_POPCNT"
15195   "#"
15196   "&& reload_completed"
15197   [(parallel
15198      [(set (match_dup 1)
15199            (xor:SI (match_dup 1) (match_dup 4)))
15200       (clobber (reg:CC FLAGS_REG))])
15201    (parallel
15202      [(set (reg:CC FLAGS_REG)
15203            (parity:CC (match_dup 1)))
15204       (clobber (match_dup 1))
15205       (clobber (match_dup 2))])]
15206 {
15207   operands[4] = gen_lowpart (SImode, operands[3]);
15208
15209   if (MEM_P (operands[3]))
15210     emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
15211   else if (! TARGET_64BIT)
15212     operands[1] = gen_highpart (SImode, operands[3]);
15213   else
15214     {
15215       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15216       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15217     }
15218 })
15219
15220 (define_expand "paritysi2"
15221   [(set (match_operand:SI 0 "register_operand" "")
15222         (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
15223   "! TARGET_POPCNT"
15224 {
15225   rtx scratch = gen_reg_rtx (QImode);
15226   rtx cond;
15227
15228   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15229
15230   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15231                          gen_rtx_REG (CCmode, FLAGS_REG),
15232                          const0_rtx);
15233   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15234
15235   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15236   DONE;
15237 })
15238
15239 (define_insn_and_split "paritysi2_cmp"
15240   [(set (reg:CC FLAGS_REG)
15241         (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
15242    (clobber (match_scratch:SI 0 "=r,X"))
15243    (clobber (match_scratch:HI 1 "=Q,Q"))]
15244   "! TARGET_POPCNT"
15245   "#"
15246   "&& reload_completed"
15247   [(parallel
15248      [(set (match_dup 1)
15249            (xor:HI (match_dup 1) (match_dup 3)))
15250       (clobber (reg:CC FLAGS_REG))])
15251    (parallel
15252      [(set (reg:CC FLAGS_REG)
15253            (parity:CC (match_dup 1)))
15254       (clobber (match_dup 1))])]
15255 {
15256   operands[3] = gen_lowpart (HImode, operands[2]);
15257
15258   if (MEM_P (operands[2]))
15259     emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
15260   else
15261     {
15262       emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15263       emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15264     }
15265 })
15266
15267 (define_insn "*parityhi2_cmp"
15268   [(set (reg:CC FLAGS_REG)
15269         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15270    (clobber (match_scratch:HI 0 "=Q"))]
15271   "! TARGET_POPCNT"
15272   "xor{b}\t{%h0, %b0|%b0, %h0}"
15273   [(set_attr "length" "2")
15274    (set_attr "mode" "HI")])
15275
15276 (define_insn "*parityqi2_cmp"
15277   [(set (reg:CC FLAGS_REG)
15278         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15279   "! TARGET_POPCNT"
15280   "test{b}\t%0, %0"
15281   [(set_attr "length" "2")
15282    (set_attr "mode" "QI")])
15283 \f
15284 ;; Thread-local storage patterns for ELF.
15285 ;;
15286 ;; Note that these code sequences must appear exactly as shown
15287 ;; in order to allow linker relaxation.
15288
15289 (define_insn "*tls_global_dynamic_32_gnu"
15290   [(set (match_operand:SI 0 "register_operand" "=a")
15291         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15292                     (match_operand:SI 2 "tls_symbolic_operand" "")
15293                     (match_operand:SI 3 "call_insn_operand" "")]
15294                     UNSPEC_TLS_GD))
15295    (clobber (match_scratch:SI 4 "=d"))
15296    (clobber (match_scratch:SI 5 "=c"))
15297    (clobber (reg:CC FLAGS_REG))]
15298   "!TARGET_64BIT && TARGET_GNU_TLS"
15299   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15300   [(set_attr "type" "multi")
15301    (set_attr "length" "12")])
15302
15303 (define_insn "*tls_global_dynamic_32_sun"
15304   [(set (match_operand:SI 0 "register_operand" "=a")
15305         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15306                     (match_operand:SI 2 "tls_symbolic_operand" "")
15307                     (match_operand:SI 3 "call_insn_operand" "")]
15308                     UNSPEC_TLS_GD))
15309    (clobber (match_scratch:SI 4 "=d"))
15310    (clobber (match_scratch:SI 5 "=c"))
15311    (clobber (reg:CC FLAGS_REG))]
15312   "!TARGET_64BIT && TARGET_SUN_TLS"
15313   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15314         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15315   [(set_attr "type" "multi")
15316    (set_attr "length" "14")])
15317
15318 (define_expand "tls_global_dynamic_32"
15319   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15320                    (unspec:SI
15321                     [(match_dup 2)
15322                      (match_operand:SI 1 "tls_symbolic_operand" "")
15323                      (match_dup 3)]
15324                     UNSPEC_TLS_GD))
15325               (clobber (match_scratch:SI 4 ""))
15326               (clobber (match_scratch:SI 5 ""))
15327               (clobber (reg:CC FLAGS_REG))])]
15328   ""
15329 {
15330   if (flag_pic)
15331     operands[2] = pic_offset_table_rtx;
15332   else
15333     {
15334       operands[2] = gen_reg_rtx (Pmode);
15335       emit_insn (gen_set_got (operands[2]));
15336     }
15337   if (TARGET_GNU2_TLS)
15338     {
15339        emit_insn (gen_tls_dynamic_gnu2_32
15340                   (operands[0], operands[1], operands[2]));
15341        DONE;
15342     }
15343   operands[3] = ix86_tls_get_addr ();
15344 })
15345
15346 (define_insn "*tls_global_dynamic_64"
15347   [(set (match_operand:DI 0 "register_operand" "=a")
15348         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15349                  (match_operand:DI 3 "" "")))
15350    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15351               UNSPEC_TLS_GD)]
15352   "TARGET_64BIT"
15353   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15354   [(set_attr "type" "multi")
15355    (set_attr "length" "16")])
15356
15357 (define_expand "tls_global_dynamic_64"
15358   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15359                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15360               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15361                          UNSPEC_TLS_GD)])]
15362   ""
15363 {
15364   if (TARGET_GNU2_TLS)
15365     {
15366        emit_insn (gen_tls_dynamic_gnu2_64
15367                   (operands[0], operands[1]));
15368        DONE;
15369     }
15370   operands[2] = ix86_tls_get_addr ();
15371 })
15372
15373 (define_insn "*tls_local_dynamic_base_32_gnu"
15374   [(set (match_operand:SI 0 "register_operand" "=a")
15375         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15376                     (match_operand:SI 2 "call_insn_operand" "")]
15377                    UNSPEC_TLS_LD_BASE))
15378    (clobber (match_scratch:SI 3 "=d"))
15379    (clobber (match_scratch:SI 4 "=c"))
15380    (clobber (reg:CC FLAGS_REG))]
15381   "!TARGET_64BIT && TARGET_GNU_TLS"
15382   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15383   [(set_attr "type" "multi")
15384    (set_attr "length" "11")])
15385
15386 (define_insn "*tls_local_dynamic_base_32_sun"
15387   [(set (match_operand:SI 0 "register_operand" "=a")
15388         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15389                     (match_operand:SI 2 "call_insn_operand" "")]
15390                    UNSPEC_TLS_LD_BASE))
15391    (clobber (match_scratch:SI 3 "=d"))
15392    (clobber (match_scratch:SI 4 "=c"))
15393    (clobber (reg:CC FLAGS_REG))]
15394   "!TARGET_64BIT && TARGET_SUN_TLS"
15395   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15396         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15397   [(set_attr "type" "multi")
15398    (set_attr "length" "13")])
15399
15400 (define_expand "tls_local_dynamic_base_32"
15401   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15402                    (unspec:SI [(match_dup 1) (match_dup 2)]
15403                               UNSPEC_TLS_LD_BASE))
15404               (clobber (match_scratch:SI 3 ""))
15405               (clobber (match_scratch:SI 4 ""))
15406               (clobber (reg:CC FLAGS_REG))])]
15407   ""
15408 {
15409   if (flag_pic)
15410     operands[1] = pic_offset_table_rtx;
15411   else
15412     {
15413       operands[1] = gen_reg_rtx (Pmode);
15414       emit_insn (gen_set_got (operands[1]));
15415     }
15416   if (TARGET_GNU2_TLS)
15417     {
15418        emit_insn (gen_tls_dynamic_gnu2_32
15419                   (operands[0], ix86_tls_module_base (), operands[1]));
15420        DONE;
15421     }
15422   operands[2] = ix86_tls_get_addr ();
15423 })
15424
15425 (define_insn "*tls_local_dynamic_base_64"
15426   [(set (match_operand:DI 0 "register_operand" "=a")
15427         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15428                  (match_operand:DI 2 "" "")))
15429    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15430   "TARGET_64BIT"
15431   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15432   [(set_attr "type" "multi")
15433    (set_attr "length" "12")])
15434
15435 (define_expand "tls_local_dynamic_base_64"
15436   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15437                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15438               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15439   ""
15440 {
15441   if (TARGET_GNU2_TLS)
15442     {
15443        emit_insn (gen_tls_dynamic_gnu2_64
15444                   (operands[0], ix86_tls_module_base ()));
15445        DONE;
15446     }
15447   operands[1] = ix86_tls_get_addr ();
15448 })
15449
15450 ;; Local dynamic of a single variable is a lose.  Show combine how
15451 ;; to convert that back to global dynamic.
15452
15453 (define_insn_and_split "*tls_local_dynamic_32_once"
15454   [(set (match_operand:SI 0 "register_operand" "=a")
15455         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15456                              (match_operand:SI 2 "call_insn_operand" "")]
15457                             UNSPEC_TLS_LD_BASE)
15458                  (const:SI (unspec:SI
15459                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15460                             UNSPEC_DTPOFF))))
15461    (clobber (match_scratch:SI 4 "=d"))
15462    (clobber (match_scratch:SI 5 "=c"))
15463    (clobber (reg:CC FLAGS_REG))]
15464   ""
15465   "#"
15466   ""
15467   [(parallel [(set (match_dup 0)
15468                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15469                               UNSPEC_TLS_GD))
15470               (clobber (match_dup 4))
15471               (clobber (match_dup 5))
15472               (clobber (reg:CC FLAGS_REG))])]
15473   "")
15474
15475 ;; Load and add the thread base pointer from %gs:0.
15476
15477 (define_insn "*load_tp_si"
15478   [(set (match_operand:SI 0 "register_operand" "=r")
15479         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15480   "!TARGET_64BIT"
15481   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15482   [(set_attr "type" "imov")
15483    (set_attr "modrm" "0")
15484    (set_attr "length" "7")
15485    (set_attr "memory" "load")
15486    (set_attr "imm_disp" "false")])
15487
15488 (define_insn "*add_tp_si"
15489   [(set (match_operand:SI 0 "register_operand" "=r")
15490         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15491                  (match_operand:SI 1 "register_operand" "0")))
15492    (clobber (reg:CC FLAGS_REG))]
15493   "!TARGET_64BIT"
15494   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15495   [(set_attr "type" "alu")
15496    (set_attr "modrm" "0")
15497    (set_attr "length" "7")
15498    (set_attr "memory" "load")
15499    (set_attr "imm_disp" "false")])
15500
15501 (define_insn "*load_tp_di"
15502   [(set (match_operand:DI 0 "register_operand" "=r")
15503         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15504   "TARGET_64BIT"
15505   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15506   [(set_attr "type" "imov")
15507    (set_attr "modrm" "0")
15508    (set_attr "length" "7")
15509    (set_attr "memory" "load")
15510    (set_attr "imm_disp" "false")])
15511
15512 (define_insn "*add_tp_di"
15513   [(set (match_operand:DI 0 "register_operand" "=r")
15514         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15515                  (match_operand:DI 1 "register_operand" "0")))
15516    (clobber (reg:CC FLAGS_REG))]
15517   "TARGET_64BIT"
15518   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15519   [(set_attr "type" "alu")
15520    (set_attr "modrm" "0")
15521    (set_attr "length" "7")
15522    (set_attr "memory" "load")
15523    (set_attr "imm_disp" "false")])
15524
15525 ;; GNU2 TLS patterns can be split.
15526
15527 (define_expand "tls_dynamic_gnu2_32"
15528   [(set (match_dup 3)
15529         (plus:SI (match_operand:SI 2 "register_operand" "")
15530                  (const:SI
15531                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15532                              UNSPEC_TLSDESC))))
15533    (parallel
15534     [(set (match_operand:SI 0 "register_operand" "")
15535           (unspec:SI [(match_dup 1) (match_dup 3)
15536                       (match_dup 2) (reg:SI SP_REG)]
15537                       UNSPEC_TLSDESC))
15538      (clobber (reg:CC FLAGS_REG))])]
15539   "!TARGET_64BIT && TARGET_GNU2_TLS"
15540 {
15541   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15542   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15543 })
15544
15545 (define_insn "*tls_dynamic_lea_32"
15546   [(set (match_operand:SI 0 "register_operand" "=r")
15547         (plus:SI (match_operand:SI 1 "register_operand" "b")
15548                  (const:SI
15549                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15550                               UNSPEC_TLSDESC))))]
15551   "!TARGET_64BIT && TARGET_GNU2_TLS"
15552   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15553   [(set_attr "type" "lea")
15554    (set_attr "mode" "SI")
15555    (set_attr "length" "6")
15556    (set_attr "length_address" "4")])
15557
15558 (define_insn "*tls_dynamic_call_32"
15559   [(set (match_operand:SI 0 "register_operand" "=a")
15560         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15561                     (match_operand:SI 2 "register_operand" "0")
15562                     ;; we have to make sure %ebx still points to the GOT
15563                     (match_operand:SI 3 "register_operand" "b")
15564                     (reg:SI SP_REG)]
15565                    UNSPEC_TLSDESC))
15566    (clobber (reg:CC FLAGS_REG))]
15567   "!TARGET_64BIT && TARGET_GNU2_TLS"
15568   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15569   [(set_attr "type" "call")
15570    (set_attr "length" "2")
15571    (set_attr "length_address" "0")])
15572
15573 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15574   [(set (match_operand:SI 0 "register_operand" "=&a")
15575         (plus:SI
15576          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15577                      (match_operand:SI 4 "" "")
15578                      (match_operand:SI 2 "register_operand" "b")
15579                      (reg:SI SP_REG)]
15580                     UNSPEC_TLSDESC)
15581          (const:SI (unspec:SI
15582                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15583                     UNSPEC_DTPOFF))))
15584    (clobber (reg:CC FLAGS_REG))]
15585   "!TARGET_64BIT && TARGET_GNU2_TLS"
15586   "#"
15587   ""
15588   [(set (match_dup 0) (match_dup 5))]
15589 {
15590   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15591   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15592 })
15593
15594 (define_expand "tls_dynamic_gnu2_64"
15595   [(set (match_dup 2)
15596         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15597                    UNSPEC_TLSDESC))
15598    (parallel
15599     [(set (match_operand:DI 0 "register_operand" "")
15600           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15601                      UNSPEC_TLSDESC))
15602      (clobber (reg:CC FLAGS_REG))])]
15603   "TARGET_64BIT && TARGET_GNU2_TLS"
15604 {
15605   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15606   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15607 })
15608
15609 (define_insn "*tls_dynamic_lea_64"
15610   [(set (match_operand:DI 0 "register_operand" "=r")
15611         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15612                    UNSPEC_TLSDESC))]
15613   "TARGET_64BIT && TARGET_GNU2_TLS"
15614   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15615   [(set_attr "type" "lea")
15616    (set_attr "mode" "DI")
15617    (set_attr "length" "7")
15618    (set_attr "length_address" "4")])
15619
15620 (define_insn "*tls_dynamic_call_64"
15621   [(set (match_operand:DI 0 "register_operand" "=a")
15622         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15623                     (match_operand:DI 2 "register_operand" "0")
15624                     (reg:DI SP_REG)]
15625                    UNSPEC_TLSDESC))
15626    (clobber (reg:CC FLAGS_REG))]
15627   "TARGET_64BIT && TARGET_GNU2_TLS"
15628   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15629   [(set_attr "type" "call")
15630    (set_attr "length" "2")
15631    (set_attr "length_address" "0")])
15632
15633 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15634   [(set (match_operand:DI 0 "register_operand" "=&a")
15635         (plus:DI
15636          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15637                      (match_operand:DI 3 "" "")
15638                      (reg:DI SP_REG)]
15639                     UNSPEC_TLSDESC)
15640          (const:DI (unspec:DI
15641                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15642                     UNSPEC_DTPOFF))))
15643    (clobber (reg:CC FLAGS_REG))]
15644   "TARGET_64BIT && TARGET_GNU2_TLS"
15645   "#"
15646   ""
15647   [(set (match_dup 0) (match_dup 4))]
15648 {
15649   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15650   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15651 })
15652
15653 ;;
15654 \f
15655 ;; These patterns match the binary 387 instructions for addM3, subM3,
15656 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15657 ;; SFmode.  The first is the normal insn, the second the same insn but
15658 ;; with one operand a conversion, and the third the same insn but with
15659 ;; the other operand a conversion.  The conversion may be SFmode or
15660 ;; SImode if the target mode DFmode, but only SImode if the target mode
15661 ;; is SFmode.
15662
15663 ;; Gcc is slightly more smart about handling normal two address instructions
15664 ;; so use special patterns for add and mull.
15665
15666 (define_insn "*fop_sf_comm_mixed"
15667   [(set (match_operand:SF 0 "register_operand" "=f,x")
15668         (match_operator:SF 3 "binary_fp_operator"
15669                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15670                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15671   "TARGET_MIX_SSE_I387
15672    && COMMUTATIVE_ARITH_P (operands[3])
15673    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15674   "* return output_387_binary_op (insn, operands);"
15675   [(set (attr "type")
15676         (if_then_else (eq_attr "alternative" "1")
15677            (if_then_else (match_operand:SF 3 "mult_operator" "")
15678               (const_string "ssemul")
15679               (const_string "sseadd"))
15680            (if_then_else (match_operand:SF 3 "mult_operator" "")
15681               (const_string "fmul")
15682               (const_string "fop"))))
15683    (set_attr "mode" "SF")])
15684
15685 (define_insn "*fop_sf_comm_sse"
15686   [(set (match_operand:SF 0 "register_operand" "=x")
15687         (match_operator:SF 3 "binary_fp_operator"
15688                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15689                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15690   "TARGET_SSE_MATH
15691    && COMMUTATIVE_ARITH_P (operands[3])
15692    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15693   "* return output_387_binary_op (insn, operands);"
15694   [(set (attr "type")
15695         (if_then_else (match_operand:SF 3 "mult_operator" "")
15696            (const_string "ssemul")
15697            (const_string "sseadd")))
15698    (set_attr "mode" "SF")])
15699
15700 (define_insn "*fop_sf_comm_i387"
15701   [(set (match_operand:SF 0 "register_operand" "=f")
15702         (match_operator:SF 3 "binary_fp_operator"
15703                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15704                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15705   "TARGET_80387
15706    && COMMUTATIVE_ARITH_P (operands[3])
15707    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15708   "* return output_387_binary_op (insn, operands);"
15709   [(set (attr "type")
15710         (if_then_else (match_operand:SF 3 "mult_operator" "")
15711            (const_string "fmul")
15712            (const_string "fop")))
15713    (set_attr "mode" "SF")])
15714
15715 (define_insn "*fop_sf_1_mixed"
15716   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15717         (match_operator:SF 3 "binary_fp_operator"
15718                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15719                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15720   "TARGET_MIX_SSE_I387
15721    && !COMMUTATIVE_ARITH_P (operands[3])
15722    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15723   "* return output_387_binary_op (insn, operands);"
15724   [(set (attr "type")
15725         (cond [(and (eq_attr "alternative" "2")
15726                     (match_operand:SF 3 "mult_operator" ""))
15727                  (const_string "ssemul")
15728                (and (eq_attr "alternative" "2")
15729                     (match_operand:SF 3 "div_operator" ""))
15730                  (const_string "ssediv")
15731                (eq_attr "alternative" "2")
15732                  (const_string "sseadd")
15733                (match_operand:SF 3 "mult_operator" "")
15734                  (const_string "fmul")
15735                (match_operand:SF 3 "div_operator" "")
15736                  (const_string "fdiv")
15737               ]
15738               (const_string "fop")))
15739    (set_attr "mode" "SF")])
15740
15741 (define_insn "*fop_sf_1_sse"
15742   [(set (match_operand:SF 0 "register_operand" "=x")
15743         (match_operator:SF 3 "binary_fp_operator"
15744                         [(match_operand:SF 1 "register_operand" "0")
15745                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15746   "TARGET_SSE_MATH
15747    && !COMMUTATIVE_ARITH_P (operands[3])"
15748   "* return output_387_binary_op (insn, operands);"
15749   [(set (attr "type")
15750         (cond [(match_operand:SF 3 "mult_operator" "")
15751                  (const_string "ssemul")
15752                (match_operand:SF 3 "div_operator" "")
15753                  (const_string "ssediv")
15754               ]
15755               (const_string "sseadd")))
15756    (set_attr "mode" "SF")])
15757
15758 ;; This pattern is not fully shadowed by the pattern above.
15759 (define_insn "*fop_sf_1_i387"
15760   [(set (match_operand:SF 0 "register_operand" "=f,f")
15761         (match_operator:SF 3 "binary_fp_operator"
15762                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15763                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15764   "TARGET_80387 && !TARGET_SSE_MATH
15765    && !COMMUTATIVE_ARITH_P (operands[3])
15766    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15767   "* return output_387_binary_op (insn, operands);"
15768   [(set (attr "type")
15769         (cond [(match_operand:SF 3 "mult_operator" "")
15770                  (const_string "fmul")
15771                (match_operand:SF 3 "div_operator" "")
15772                  (const_string "fdiv")
15773               ]
15774               (const_string "fop")))
15775    (set_attr "mode" "SF")])
15776
15777 ;; ??? Add SSE splitters for these!
15778 (define_insn "*fop_sf_2<mode>_i387"
15779   [(set (match_operand:SF 0 "register_operand" "=f,f")
15780         (match_operator:SF 3 "binary_fp_operator"
15781           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15782            (match_operand:SF 2 "register_operand" "0,0")]))]
15783   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15784   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15785   [(set (attr "type")
15786         (cond [(match_operand:SF 3 "mult_operator" "")
15787                  (const_string "fmul")
15788                (match_operand:SF 3 "div_operator" "")
15789                  (const_string "fdiv")
15790               ]
15791               (const_string "fop")))
15792    (set_attr "fp_int_src" "true")
15793    (set_attr "mode" "<MODE>")])
15794
15795 (define_insn "*fop_sf_3<mode>_i387"
15796   [(set (match_operand:SF 0 "register_operand" "=f,f")
15797         (match_operator:SF 3 "binary_fp_operator"
15798           [(match_operand:SF 1 "register_operand" "0,0")
15799            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15800   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15801   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15802   [(set (attr "type")
15803         (cond [(match_operand:SF 3 "mult_operator" "")
15804                  (const_string "fmul")
15805                (match_operand:SF 3 "div_operator" "")
15806                  (const_string "fdiv")
15807               ]
15808               (const_string "fop")))
15809    (set_attr "fp_int_src" "true")
15810    (set_attr "mode" "<MODE>")])
15811
15812 (define_insn "*fop_df_comm_mixed"
15813   [(set (match_operand:DF 0 "register_operand" "=f,x")
15814         (match_operator:DF 3 "binary_fp_operator"
15815           [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15816            (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15817   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15818    && COMMUTATIVE_ARITH_P (operands[3])
15819    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15820   "* return output_387_binary_op (insn, operands);"
15821   [(set (attr "type")
15822         (if_then_else (eq_attr "alternative" "1")
15823            (if_then_else (match_operand:DF 3 "mult_operator" "")
15824               (const_string "ssemul")
15825               (const_string "sseadd"))
15826            (if_then_else (match_operand:DF 3 "mult_operator" "")
15827               (const_string "fmul")
15828               (const_string "fop"))))
15829    (set_attr "mode" "DF")])
15830
15831 (define_insn "*fop_df_comm_sse"
15832   [(set (match_operand:DF 0 "register_operand" "=x")
15833         (match_operator:DF 3 "binary_fp_operator"
15834           [(match_operand:DF 1 "nonimmediate_operand" "%0")
15835            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15836   "TARGET_SSE2 && TARGET_SSE_MATH
15837    && COMMUTATIVE_ARITH_P (operands[3])
15838    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15839   "* return output_387_binary_op (insn, operands);"
15840   [(set (attr "type")
15841         (if_then_else (match_operand:DF 3 "mult_operator" "")
15842            (const_string "ssemul")
15843            (const_string "sseadd")))
15844    (set_attr "mode" "DF")])
15845
15846 (define_insn "*fop_df_comm_i387"
15847   [(set (match_operand:DF 0 "register_operand" "=f")
15848         (match_operator:DF 3 "binary_fp_operator"
15849                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15850                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15851   "TARGET_80387
15852    && COMMUTATIVE_ARITH_P (operands[3])
15853    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15854   "* return output_387_binary_op (insn, operands);"
15855   [(set (attr "type")
15856         (if_then_else (match_operand:DF 3 "mult_operator" "")
15857            (const_string "fmul")
15858            (const_string "fop")))
15859    (set_attr "mode" "DF")])
15860
15861 (define_insn "*fop_df_1_mixed"
15862   [(set (match_operand:DF 0 "register_operand" "=f,f,x")
15863         (match_operator:DF 3 "binary_fp_operator"
15864           [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15865            (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
15866   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15867    && !COMMUTATIVE_ARITH_P (operands[3])
15868    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15869   "* return output_387_binary_op (insn, operands);"
15870   [(set (attr "type")
15871         (cond [(and (eq_attr "alternative" "2")
15872                     (match_operand:DF 3 "mult_operator" ""))
15873                  (const_string "ssemul")
15874                (and (eq_attr "alternative" "2")
15875                     (match_operand:DF 3 "div_operator" ""))
15876                  (const_string "ssediv")
15877                (eq_attr "alternative" "2")
15878                  (const_string "sseadd")
15879                (match_operand:DF 3 "mult_operator" "")
15880                  (const_string "fmul")
15881                (match_operand:DF 3 "div_operator" "")
15882                  (const_string "fdiv")
15883               ]
15884               (const_string "fop")))
15885    (set_attr "mode" "DF")])
15886
15887 (define_insn "*fop_df_1_sse"
15888   [(set (match_operand:DF 0 "register_operand" "=x")
15889         (match_operator:DF 3 "binary_fp_operator"
15890           [(match_operand:DF 1 "register_operand" "0")
15891            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15892   "TARGET_SSE2 && TARGET_SSE_MATH
15893    && !COMMUTATIVE_ARITH_P (operands[3])"
15894   "* return output_387_binary_op (insn, operands);"
15895   [(set_attr "mode" "DF")
15896    (set (attr "type")
15897         (cond [(match_operand:DF 3 "mult_operator" "")
15898                  (const_string "ssemul")
15899                (match_operand:DF 3 "div_operator" "")
15900                  (const_string "ssediv")
15901               ]
15902               (const_string "sseadd")))])
15903
15904 ;; This pattern is not fully shadowed by the pattern above.
15905 (define_insn "*fop_df_1_i387"
15906   [(set (match_operand:DF 0 "register_operand" "=f,f")
15907         (match_operator:DF 3 "binary_fp_operator"
15908                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15909                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15910   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15911    && !COMMUTATIVE_ARITH_P (operands[3])
15912    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15913   "* return output_387_binary_op (insn, operands);"
15914   [(set (attr "type")
15915         (cond [(match_operand:DF 3 "mult_operator" "")
15916                  (const_string "fmul")
15917                (match_operand:DF 3 "div_operator" "")
15918                  (const_string "fdiv")
15919               ]
15920               (const_string "fop")))
15921    (set_attr "mode" "DF")])
15922
15923 ;; ??? Add SSE splitters for these!
15924 (define_insn "*fop_df_2<mode>_i387"
15925   [(set (match_operand:DF 0 "register_operand" "=f,f")
15926         (match_operator:DF 3 "binary_fp_operator"
15927            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15928             (match_operand:DF 2 "register_operand" "0,0")]))]
15929   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15930    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15931   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15932   [(set (attr "type")
15933         (cond [(match_operand:DF 3 "mult_operator" "")
15934                  (const_string "fmul")
15935                (match_operand:DF 3 "div_operator" "")
15936                  (const_string "fdiv")
15937               ]
15938               (const_string "fop")))
15939    (set_attr "fp_int_src" "true")
15940    (set_attr "mode" "<MODE>")])
15941
15942 (define_insn "*fop_df_3<mode>_i387"
15943   [(set (match_operand:DF 0 "register_operand" "=f,f")
15944         (match_operator:DF 3 "binary_fp_operator"
15945            [(match_operand:DF 1 "register_operand" "0,0")
15946             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15947   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15948    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15949   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15950   [(set (attr "type")
15951         (cond [(match_operand:DF 3 "mult_operator" "")
15952                  (const_string "fmul")
15953                (match_operand:DF 3 "div_operator" "")
15954                  (const_string "fdiv")
15955               ]
15956               (const_string "fop")))
15957    (set_attr "fp_int_src" "true")
15958    (set_attr "mode" "<MODE>")])
15959
15960 (define_insn "*fop_df_4_i387"
15961   [(set (match_operand:DF 0 "register_operand" "=f,f")
15962         (match_operator:DF 3 "binary_fp_operator"
15963            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15964             (match_operand:DF 2 "register_operand" "0,f")]))]
15965   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15966    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15967   "* return output_387_binary_op (insn, operands);"
15968   [(set (attr "type")
15969         (cond [(match_operand:DF 3 "mult_operator" "")
15970                  (const_string "fmul")
15971                (match_operand:DF 3 "div_operator" "")
15972                  (const_string "fdiv")
15973               ]
15974               (const_string "fop")))
15975    (set_attr "mode" "SF")])
15976
15977 (define_insn "*fop_df_5_i387"
15978   [(set (match_operand:DF 0 "register_operand" "=f,f")
15979         (match_operator:DF 3 "binary_fp_operator"
15980           [(match_operand:DF 1 "register_operand" "0,f")
15981            (float_extend:DF
15982             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15983   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15984   "* return output_387_binary_op (insn, operands);"
15985   [(set (attr "type")
15986         (cond [(match_operand:DF 3 "mult_operator" "")
15987                  (const_string "fmul")
15988                (match_operand:DF 3 "div_operator" "")
15989                  (const_string "fdiv")
15990               ]
15991               (const_string "fop")))
15992    (set_attr "mode" "SF")])
15993
15994 (define_insn "*fop_df_6_i387"
15995   [(set (match_operand:DF 0 "register_operand" "=f,f")
15996         (match_operator:DF 3 "binary_fp_operator"
15997           [(float_extend:DF
15998             (match_operand:SF 1 "register_operand" "0,f"))
15999            (float_extend:DF
16000             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16001   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16002   "* return output_387_binary_op (insn, operands);"
16003   [(set (attr "type")
16004         (cond [(match_operand:DF 3 "mult_operator" "")
16005                  (const_string "fmul")
16006                (match_operand:DF 3 "div_operator" "")
16007                  (const_string "fdiv")
16008               ]
16009               (const_string "fop")))
16010    (set_attr "mode" "SF")])
16011
16012 (define_insn "*fop_xf_comm_i387"
16013   [(set (match_operand:XF 0 "register_operand" "=f")
16014         (match_operator:XF 3 "binary_fp_operator"
16015                         [(match_operand:XF 1 "register_operand" "%0")
16016                          (match_operand:XF 2 "register_operand" "f")]))]
16017   "TARGET_80387
16018    && COMMUTATIVE_ARITH_P (operands[3])"
16019   "* return output_387_binary_op (insn, operands);"
16020   [(set (attr "type")
16021         (if_then_else (match_operand:XF 3 "mult_operator" "")
16022            (const_string "fmul")
16023            (const_string "fop")))
16024    (set_attr "mode" "XF")])
16025
16026 (define_insn "*fop_xf_1_i387"
16027   [(set (match_operand:XF 0 "register_operand" "=f,f")
16028         (match_operator:XF 3 "binary_fp_operator"
16029                         [(match_operand:XF 1 "register_operand" "0,f")
16030                          (match_operand:XF 2 "register_operand" "f,0")]))]
16031   "TARGET_80387
16032    && !COMMUTATIVE_ARITH_P (operands[3])"
16033   "* return output_387_binary_op (insn, operands);"
16034   [(set (attr "type")
16035         (cond [(match_operand:XF 3 "mult_operator" "")
16036                  (const_string "fmul")
16037                (match_operand:XF 3 "div_operator" "")
16038                  (const_string "fdiv")
16039               ]
16040               (const_string "fop")))
16041    (set_attr "mode" "XF")])
16042
16043 (define_insn "*fop_xf_2<mode>_i387"
16044   [(set (match_operand:XF 0 "register_operand" "=f,f")
16045         (match_operator:XF 3 "binary_fp_operator"
16046            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16047             (match_operand:XF 2 "register_operand" "0,0")]))]
16048   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16049   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16050   [(set (attr "type")
16051         (cond [(match_operand:XF 3 "mult_operator" "")
16052                  (const_string "fmul")
16053                (match_operand:XF 3 "div_operator" "")
16054                  (const_string "fdiv")
16055               ]
16056               (const_string "fop")))
16057    (set_attr "fp_int_src" "true")
16058    (set_attr "mode" "<MODE>")])
16059
16060 (define_insn "*fop_xf_3<mode>_i387"
16061   [(set (match_operand:XF 0 "register_operand" "=f,f")
16062         (match_operator:XF 3 "binary_fp_operator"
16063           [(match_operand:XF 1 "register_operand" "0,0")
16064            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16065   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16066   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16067   [(set (attr "type")
16068         (cond [(match_operand:XF 3 "mult_operator" "")
16069                  (const_string "fmul")
16070                (match_operand:XF 3 "div_operator" "")
16071                  (const_string "fdiv")
16072               ]
16073               (const_string "fop")))
16074    (set_attr "fp_int_src" "true")
16075    (set_attr "mode" "<MODE>")])
16076
16077 (define_insn "*fop_xf_4_i387"
16078   [(set (match_operand:XF 0 "register_operand" "=f,f")
16079         (match_operator:XF 3 "binary_fp_operator"
16080            [(float_extend:XF
16081               (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
16082             (match_operand:XF 2 "register_operand" "0,f")]))]
16083   "TARGET_80387"
16084   "* return output_387_binary_op (insn, operands);"
16085   [(set (attr "type")
16086         (cond [(match_operand:XF 3 "mult_operator" "")
16087                  (const_string "fmul")
16088                (match_operand:XF 3 "div_operator" "")
16089                  (const_string "fdiv")
16090               ]
16091               (const_string "fop")))
16092    (set_attr "mode" "SF")])
16093
16094 (define_insn "*fop_xf_5_i387"
16095   [(set (match_operand:XF 0 "register_operand" "=f,f")
16096         (match_operator:XF 3 "binary_fp_operator"
16097           [(match_operand:XF 1 "register_operand" "0,f")
16098            (float_extend:XF
16099              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
16100   "TARGET_80387"
16101   "* return output_387_binary_op (insn, operands);"
16102   [(set (attr "type")
16103         (cond [(match_operand:XF 3 "mult_operator" "")
16104                  (const_string "fmul")
16105                (match_operand:XF 3 "div_operator" "")
16106                  (const_string "fdiv")
16107               ]
16108               (const_string "fop")))
16109    (set_attr "mode" "SF")])
16110
16111 (define_insn "*fop_xf_6_i387"
16112   [(set (match_operand:XF 0 "register_operand" "=f,f")
16113         (match_operator:XF 3 "binary_fp_operator"
16114           [(float_extend:XF
16115              (match_operand:X87MODEF12 1 "register_operand" "0,f"))
16116            (float_extend:XF
16117              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
16118   "TARGET_80387"
16119   "* return output_387_binary_op (insn, operands);"
16120   [(set (attr "type")
16121         (cond [(match_operand:XF 3 "mult_operator" "")
16122                  (const_string "fmul")
16123                (match_operand:XF 3 "div_operator" "")
16124                  (const_string "fdiv")
16125               ]
16126               (const_string "fop")))
16127    (set_attr "mode" "SF")])
16128
16129 (define_split
16130   [(set (match_operand 0 "register_operand" "")
16131         (match_operator 3 "binary_fp_operator"
16132            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16133             (match_operand 2 "register_operand" "")]))]
16134   "TARGET_80387 && reload_completed
16135    && FLOAT_MODE_P (GET_MODE (operands[0]))"
16136   [(const_int 0)]
16137 {
16138   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16139   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16140   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16141                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16142                                           GET_MODE (operands[3]),
16143                                           operands[4],
16144                                           operands[2])));
16145   ix86_free_from_memory (GET_MODE (operands[1]));
16146   DONE;
16147 })
16148
16149 (define_split
16150   [(set (match_operand 0 "register_operand" "")
16151         (match_operator 3 "binary_fp_operator"
16152            [(match_operand 1 "register_operand" "")
16153             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16154   "TARGET_80387 && reload_completed
16155    && FLOAT_MODE_P (GET_MODE (operands[0]))"
16156   [(const_int 0)]
16157 {
16158   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16159   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16160   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16161                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16162                                           GET_MODE (operands[3]),
16163                                           operands[1],
16164                                           operands[4])));
16165   ix86_free_from_memory (GET_MODE (operands[2]));
16166   DONE;
16167 })
16168 \f
16169 ;; FPU special functions.
16170
16171 ;; This pattern implements a no-op XFmode truncation for
16172 ;; all fancy i386 XFmode math functions.
16173
16174 (define_insn "truncxf<mode>2_i387_noop_unspec"
16175   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16176         (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
16177         UNSPEC_TRUNC_NOOP))]
16178   "TARGET_USE_FANCY_MATH_387"
16179   "* return output_387_reg_move (insn, operands);"
16180   [(set_attr "type" "fmov")
16181    (set_attr "mode" "<MODE>")])
16182
16183 (define_insn "sqrtxf2"
16184   [(set (match_operand:XF 0 "register_operand" "=f")
16185         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16186   "TARGET_USE_FANCY_MATH_387"
16187   "fsqrt"
16188   [(set_attr "type" "fpspc")
16189    (set_attr "mode" "XF")
16190    (set_attr "athlon_decode" "direct")
16191    (set_attr "amdfam10_decode" "direct")])
16192
16193 (define_insn "sqrt_extend<mode>xf2_i387"
16194   [(set (match_operand:XF 0 "register_operand" "=f")
16195         (sqrt:XF
16196           (float_extend:XF
16197             (match_operand:X87MODEF12 1 "register_operand" "0"))))]
16198   "TARGET_USE_FANCY_MATH_387"
16199   "fsqrt"
16200   [(set_attr "type" "fpspc")
16201    (set_attr "mode" "XF")
16202    (set_attr "athlon_decode" "direct")   
16203    (set_attr "amdfam10_decode" "direct")])
16204
16205 (define_insn "*sqrt<mode>2_sse"
16206   [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
16207         (sqrt:SSEMODEF
16208           (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
16209   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16210   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16211   [(set_attr "type" "sse")
16212    (set_attr "mode" "<MODE>")
16213    (set_attr "athlon_decode" "*")
16214    (set_attr "amdfam10_decode" "*")])
16215
16216 (define_expand "sqrt<mode>2"
16217   [(set (match_operand:X87MODEF12 0 "register_operand" "")
16218         (sqrt:X87MODEF12
16219           (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
16220   "TARGET_USE_FANCY_MATH_387
16221    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16222 {
16223   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16224     {
16225       rtx op0 = gen_reg_rtx (XFmode);
16226       rtx op1 = force_reg (<MODE>mode, operands[1]);
16227
16228       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16229       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16230       DONE;
16231    }
16232 })
16233
16234 (define_insn "fpremxf4_i387"
16235   [(set (match_operand:XF 0 "register_operand" "=f")
16236         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16237                     (match_operand:XF 3 "register_operand" "1")]
16238                    UNSPEC_FPREM_F))
16239    (set (match_operand:XF 1 "register_operand" "=u")
16240         (unspec:XF [(match_dup 2) (match_dup 3)]
16241                    UNSPEC_FPREM_U))
16242    (set (reg:CCFP FPSR_REG)
16243         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
16244   "TARGET_USE_FANCY_MATH_387"
16245   "fprem"
16246   [(set_attr "type" "fpspc")
16247    (set_attr "mode" "XF")])
16248
16249 (define_expand "fmodxf3"
16250   [(use (match_operand:XF 0 "register_operand" ""))
16251    (use (match_operand:XF 1 "register_operand" ""))
16252    (use (match_operand:XF 2 "register_operand" ""))]
16253   "TARGET_USE_FANCY_MATH_387"
16254 {
16255   rtx label = gen_label_rtx ();
16256
16257   emit_label (label);
16258
16259   emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
16260                                 operands[1], operands[2]));
16261   ix86_emit_fp_unordered_jump (label);
16262
16263   emit_move_insn (operands[0], operands[1]);
16264   DONE;
16265 })
16266
16267 (define_expand "fmod<mode>3"
16268   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16269    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16270    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16271   "TARGET_USE_FANCY_MATH_387"
16272 {
16273   rtx label = gen_label_rtx ();
16274
16275   rtx op1 = gen_reg_rtx (XFmode);
16276   rtx op2 = gen_reg_rtx (XFmode);
16277
16278   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16279   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16280
16281   emit_label (label);
16282   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16283   ix86_emit_fp_unordered_jump (label);
16284
16285   /* Truncate the result properly for strict SSE math.  */
16286   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16287       && !TARGET_MIX_SSE_I387)
16288     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16289   else
16290     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16291
16292   DONE;
16293 })
16294
16295 (define_insn "fprem1xf4_i387"
16296   [(set (match_operand:XF 0 "register_operand" "=f")
16297         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16298                     (match_operand:XF 3 "register_operand" "1")]
16299                    UNSPEC_FPREM1_F))
16300    (set (match_operand:XF 1 "register_operand" "=u")
16301         (unspec:XF [(match_dup 2) (match_dup 3)]
16302                    UNSPEC_FPREM1_U))
16303    (set (reg:CCFP FPSR_REG)
16304         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
16305   "TARGET_USE_FANCY_MATH_387"
16306   "fprem1"
16307   [(set_attr "type" "fpspc")
16308    (set_attr "mode" "XF")])
16309
16310 (define_expand "remainderxf3"
16311   [(use (match_operand:XF 0 "register_operand" ""))
16312    (use (match_operand:XF 1 "register_operand" ""))
16313    (use (match_operand:XF 2 "register_operand" ""))]
16314   "TARGET_USE_FANCY_MATH_387"
16315 {
16316   rtx label = gen_label_rtx ();
16317
16318   emit_label (label);
16319
16320   emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
16321                                  operands[1], operands[2]));
16322   ix86_emit_fp_unordered_jump (label);
16323
16324   emit_move_insn (operands[0], operands[1]);
16325   DONE;
16326 })
16327
16328 (define_expand "remainder<mode>3"
16329   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16330    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16331    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16332   "TARGET_USE_FANCY_MATH_387"
16333 {
16334   rtx label = gen_label_rtx ();
16335
16336   rtx op1 = gen_reg_rtx (XFmode);
16337   rtx op2 = gen_reg_rtx (XFmode);
16338
16339   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16340   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16341
16342   emit_label (label);
16343
16344   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16345   ix86_emit_fp_unordered_jump (label);
16346
16347   /* Truncate the result properly for strict SSE math.  */
16348   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16349       && !TARGET_MIX_SSE_I387)
16350     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16351   else
16352     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16353
16354   DONE;
16355 })
16356
16357 (define_insn "*sinxf2_i387"
16358   [(set (match_operand:XF 0 "register_operand" "=f")
16359         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16360   "TARGET_USE_FANCY_MATH_387
16361    && flag_unsafe_math_optimizations"
16362   "fsin"
16363   [(set_attr "type" "fpspc")
16364    (set_attr "mode" "XF")])
16365
16366 (define_insn "*sin_extend<mode>xf2_i387"
16367   [(set (match_operand:XF 0 "register_operand" "=f")
16368         (unspec:XF [(float_extend:XF
16369                       (match_operand:X87MODEF12 1 "register_operand" "0"))]
16370                    UNSPEC_SIN))]
16371   "TARGET_USE_FANCY_MATH_387
16372    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16373        || TARGET_MIX_SSE_I387)
16374    && flag_unsafe_math_optimizations"
16375   "fsin"
16376   [(set_attr "type" "fpspc")
16377    (set_attr "mode" "XF")])
16378
16379 (define_insn "*cosxf2_i387"
16380   [(set (match_operand:XF 0 "register_operand" "=f")
16381         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16382   "TARGET_USE_FANCY_MATH_387
16383    && flag_unsafe_math_optimizations"
16384   "fcos"
16385   [(set_attr "type" "fpspc")
16386    (set_attr "mode" "XF")])
16387
16388 (define_insn "*cos_extend<mode>xf2_i387"
16389   [(set (match_operand:XF 0 "register_operand" "=f")
16390         (unspec:XF [(float_extend:XF
16391                       (match_operand:X87MODEF12 1 "register_operand" "0"))]
16392                    UNSPEC_COS))]
16393   "TARGET_USE_FANCY_MATH_387
16394    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16395        || TARGET_MIX_SSE_I387)
16396    && flag_unsafe_math_optimizations"
16397   "fcos"
16398   [(set_attr "type" "fpspc")
16399    (set_attr "mode" "XF")])
16400
16401 ;; When sincos pattern is defined, sin and cos builtin functions will be
16402 ;; expanded to sincos pattern with one of its outputs left unused.
16403 ;; CSE pass will figure out if two sincos patterns can be combined,
16404 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16405 ;; depending on the unused output.
16406
16407 (define_insn "sincosxf3"
16408   [(set (match_operand:XF 0 "register_operand" "=f")
16409         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16410                    UNSPEC_SINCOS_COS))
16411    (set (match_operand:XF 1 "register_operand" "=u")
16412         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16413   "TARGET_USE_FANCY_MATH_387
16414    && flag_unsafe_math_optimizations"
16415   "fsincos"
16416   [(set_attr "type" "fpspc")
16417    (set_attr "mode" "XF")])
16418
16419 (define_split
16420   [(set (match_operand:XF 0 "register_operand" "")
16421         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16422                    UNSPEC_SINCOS_COS))
16423    (set (match_operand:XF 1 "register_operand" "")
16424         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16425   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16426    && !reload_completed && !reload_in_progress"
16427   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16428   "")
16429
16430 (define_split
16431   [(set (match_operand:XF 0 "register_operand" "")
16432         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16433                    UNSPEC_SINCOS_COS))
16434    (set (match_operand:XF 1 "register_operand" "")
16435         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16436   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16437    && !reload_completed && !reload_in_progress"
16438   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16439   "")
16440
16441 (define_insn "sincos_extend<mode>xf3_i387"
16442   [(set (match_operand:XF 0 "register_operand" "=f")
16443         (unspec:XF [(float_extend:XF
16444                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16445                    UNSPEC_SINCOS_COS))
16446    (set (match_operand:XF 1 "register_operand" "=u")
16447         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16448   "TARGET_USE_FANCY_MATH_387
16449    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16450        || TARGET_MIX_SSE_I387)
16451    && flag_unsafe_math_optimizations"
16452   "fsincos"
16453   [(set_attr "type" "fpspc")
16454    (set_attr "mode" "XF")])
16455
16456 (define_split
16457   [(set (match_operand:XF 0 "register_operand" "")
16458         (unspec:XF [(float_extend:XF
16459                       (match_operand:X87MODEF12 2 "register_operand" ""))]
16460                    UNSPEC_SINCOS_COS))
16461    (set (match_operand:XF 1 "register_operand" "")
16462         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16463   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16464    && !reload_completed && !reload_in_progress"
16465   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16466   "")
16467
16468 (define_split
16469   [(set (match_operand:XF 0 "register_operand" "")
16470         (unspec:XF [(float_extend:XF
16471                       (match_operand:X87MODEF12 2 "register_operand" ""))]
16472                    UNSPEC_SINCOS_COS))
16473    (set (match_operand:XF 1 "register_operand" "")
16474         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16475   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16476    && !reload_completed && !reload_in_progress"
16477   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16478   "")
16479
16480 (define_expand "sincos<mode>3"
16481   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16482    (use (match_operand:X87MODEF12 1 "register_operand" ""))
16483    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16484   "TARGET_USE_FANCY_MATH_387
16485    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16486        || TARGET_MIX_SSE_I387)
16487    && flag_unsafe_math_optimizations"
16488 {
16489   rtx op0 = gen_reg_rtx (XFmode);
16490   rtx op1 = gen_reg_rtx (XFmode);
16491
16492   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16493   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16494   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16495   DONE;
16496 })
16497
16498 (define_insn "fptanxf4_i387"
16499   [(set (match_operand:XF 0 "register_operand" "=f")
16500         (match_operand:XF 3 "const_double_operand" "F"))
16501    (set (match_operand:XF 1 "register_operand" "=u")
16502         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16503                    UNSPEC_TAN))]
16504   "TARGET_USE_FANCY_MATH_387
16505    && flag_unsafe_math_optimizations
16506    && standard_80387_constant_p (operands[3]) == 2"
16507   "fptan"
16508   [(set_attr "type" "fpspc")
16509    (set_attr "mode" "XF")])
16510
16511 (define_insn "fptan_extend<mode>xf4_i387"
16512   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16513         (match_operand:X87MODEF12 3 "const_double_operand" "F"))
16514    (set (match_operand:XF 1 "register_operand" "=u")
16515         (unspec:XF [(float_extend:XF
16516                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16517                    UNSPEC_TAN))]
16518   "TARGET_USE_FANCY_MATH_387
16519    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16520        || TARGET_MIX_SSE_I387)
16521    && flag_unsafe_math_optimizations
16522    && standard_80387_constant_p (operands[3]) == 2"
16523   "fptan"
16524   [(set_attr "type" "fpspc")
16525    (set_attr "mode" "XF")])
16526
16527 (define_expand "tanxf2"
16528   [(use (match_operand:XF 0 "register_operand" ""))
16529    (use (match_operand:XF 1 "register_operand" ""))]
16530   "TARGET_USE_FANCY_MATH_387
16531    && flag_unsafe_math_optimizations"
16532 {
16533   rtx one = gen_reg_rtx (XFmode);
16534   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16535
16536   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16537   DONE;
16538 })
16539
16540 (define_expand "tan<mode>2"
16541   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16542    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16543   "TARGET_USE_FANCY_MATH_387
16544    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16545        || TARGET_MIX_SSE_I387)
16546    && flag_unsafe_math_optimizations"
16547 {
16548   rtx op0 = gen_reg_rtx (XFmode);
16549
16550   rtx one = gen_reg_rtx (<MODE>mode);
16551   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16552
16553   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16554                                              operands[1], op2));
16555   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16556   DONE;
16557 })
16558
16559 (define_insn "*fpatanxf3_i387"
16560   [(set (match_operand:XF 0 "register_operand" "=f")
16561         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16562                     (match_operand:XF 2 "register_operand" "u")]
16563                    UNSPEC_FPATAN))
16564    (clobber (match_scratch:XF 3 "=2"))]
16565   "TARGET_USE_FANCY_MATH_387
16566    && flag_unsafe_math_optimizations"
16567   "fpatan"
16568   [(set_attr "type" "fpspc")
16569    (set_attr "mode" "XF")])
16570
16571 (define_insn "fpatan_extend<mode>xf3_i387"
16572   [(set (match_operand:XF 0 "register_operand" "=f")
16573         (unspec:XF [(float_extend:XF
16574                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16575                     (float_extend:XF
16576                       (match_operand:X87MODEF12 2 "register_operand" "u"))]
16577                    UNSPEC_FPATAN))
16578    (clobber (match_scratch:XF 3 "=2"))]
16579   "TARGET_USE_FANCY_MATH_387
16580    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16581        || TARGET_MIX_SSE_I387)
16582    && flag_unsafe_math_optimizations"
16583   "fpatan"
16584   [(set_attr "type" "fpspc")
16585    (set_attr "mode" "XF")])
16586
16587 (define_expand "atan2xf3"
16588   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16589                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
16590                                (match_operand:XF 1 "register_operand" "")]
16591                               UNSPEC_FPATAN))
16592               (clobber (match_scratch:XF 3 ""))])]
16593   "TARGET_USE_FANCY_MATH_387
16594    && flag_unsafe_math_optimizations"
16595   "")
16596
16597 (define_expand "atan2<mode>3"
16598   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16599    (use (match_operand:X87MODEF12 1 "register_operand" ""))
16600    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16601   "TARGET_USE_FANCY_MATH_387
16602    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16603        || TARGET_MIX_SSE_I387)
16604    && flag_unsafe_math_optimizations"
16605 {
16606   rtx op0 = gen_reg_rtx (XFmode);
16607
16608   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16609   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16610   DONE;
16611 })
16612
16613 (define_expand "atanxf2"
16614   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16615                    (unspec:XF [(match_dup 2)
16616                                (match_operand:XF 1 "register_operand" "")]
16617                               UNSPEC_FPATAN))
16618               (clobber (match_scratch:XF 3 ""))])]
16619   "TARGET_USE_FANCY_MATH_387
16620    && flag_unsafe_math_optimizations"
16621 {
16622   operands[2] = gen_reg_rtx (XFmode);
16623   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16624 })
16625
16626 (define_expand "atan<mode>2"
16627   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16628    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16629   "TARGET_USE_FANCY_MATH_387
16630    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16631        || TARGET_MIX_SSE_I387)
16632    && flag_unsafe_math_optimizations"
16633 {
16634   rtx op0 = gen_reg_rtx (XFmode);
16635
16636   rtx op2 = gen_reg_rtx (<MODE>mode);
16637   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
16638
16639   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16640   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16641   DONE;
16642 })
16643
16644 (define_expand "asinxf2"
16645   [(set (match_dup 2)
16646         (mult:XF (match_operand:XF 1 "register_operand" "")
16647                  (match_dup 1)))
16648    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16649    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16650    (parallel [(set (match_operand:XF 0 "register_operand" "")
16651                    (unspec:XF [(match_dup 5) (match_dup 1)]
16652                               UNSPEC_FPATAN))
16653               (clobber (match_scratch:XF 6 ""))])]
16654   "TARGET_USE_FANCY_MATH_387
16655    && flag_unsafe_math_optimizations && !optimize_size"
16656 {
16657   int i;
16658
16659   for (i = 2; i < 6; i++)
16660     operands[i] = gen_reg_rtx (XFmode);
16661
16662   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16663 })
16664
16665 (define_expand "asin<mode>2"
16666   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16667    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16668  "TARGET_USE_FANCY_MATH_387
16669    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16670        || TARGET_MIX_SSE_I387)
16671    && flag_unsafe_math_optimizations && !optimize_size"
16672 {
16673   rtx op0 = gen_reg_rtx (XFmode);
16674   rtx op1 = gen_reg_rtx (XFmode);
16675
16676   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16677   emit_insn (gen_asinxf2 (op0, op1));
16678   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16679   DONE;
16680 })
16681
16682 (define_expand "acosxf2"
16683   [(set (match_dup 2)
16684         (mult:XF (match_operand:XF 1 "register_operand" "")
16685                  (match_dup 1)))
16686    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16687    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16688    (parallel [(set (match_operand:XF 0 "register_operand" "")
16689                    (unspec:XF [(match_dup 1) (match_dup 5)]
16690                               UNSPEC_FPATAN))
16691               (clobber (match_scratch:XF 6 ""))])]
16692   "TARGET_USE_FANCY_MATH_387
16693    && flag_unsafe_math_optimizations && !optimize_size"
16694 {
16695   int i;
16696
16697   for (i = 2; i < 6; i++)
16698     operands[i] = gen_reg_rtx (XFmode);
16699
16700   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16701 })
16702
16703 (define_expand "acos<mode>2"
16704   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16705    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16706  "TARGET_USE_FANCY_MATH_387
16707    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16708        || TARGET_MIX_SSE_I387)
16709    && flag_unsafe_math_optimizations && !optimize_size"
16710 {
16711   rtx op0 = gen_reg_rtx (XFmode);
16712   rtx op1 = gen_reg_rtx (XFmode);
16713
16714   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16715   emit_insn (gen_acosxf2 (op0, op1));
16716   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16717   DONE;
16718 })
16719
16720 (define_insn "fyl2xxf3_i387"
16721   [(set (match_operand:XF 0 "register_operand" "=f")
16722         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16723                     (match_operand:XF 2 "register_operand" "u")]
16724                    UNSPEC_FYL2X))
16725    (clobber (match_scratch:XF 3 "=2"))]
16726   "TARGET_USE_FANCY_MATH_387
16727    && flag_unsafe_math_optimizations"
16728   "fyl2x"
16729   [(set_attr "type" "fpspc")
16730    (set_attr "mode" "XF")])
16731
16732 (define_insn "fyl2x_extend<mode>xf3_i387"
16733   [(set (match_operand:XF 0 "register_operand" "=f")
16734         (unspec:XF [(float_extend:XF
16735                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16736                     (match_operand:XF 2 "register_operand" "u")]
16737                    UNSPEC_FYL2X))
16738    (clobber (match_scratch:XF 3 "=2"))]
16739   "TARGET_USE_FANCY_MATH_387
16740    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16741        || TARGET_MIX_SSE_I387)
16742    && flag_unsafe_math_optimizations"
16743   "fyl2x"
16744   [(set_attr "type" "fpspc")
16745    (set_attr "mode" "XF")])
16746
16747 (define_expand "logxf2"
16748   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16749                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16750                                (match_dup 2)] UNSPEC_FYL2X))
16751               (clobber (match_scratch:XF 3 ""))])]
16752   "TARGET_USE_FANCY_MATH_387
16753    && flag_unsafe_math_optimizations"
16754 {
16755   operands[2] = gen_reg_rtx (XFmode);
16756   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16757 })
16758
16759 (define_expand "log<mode>2"
16760   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16761    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16762   "TARGET_USE_FANCY_MATH_387
16763    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16764        || TARGET_MIX_SSE_I387)
16765    && flag_unsafe_math_optimizations"
16766 {
16767   rtx op0 = gen_reg_rtx (XFmode);
16768
16769   rtx op2 = gen_reg_rtx (XFmode);
16770   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16771
16772   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16773   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16774   DONE;
16775 })
16776
16777 (define_expand "log10xf2"
16778   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16779                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16780                                (match_dup 2)] UNSPEC_FYL2X))
16781               (clobber (match_scratch:XF 3 ""))])]
16782   "TARGET_USE_FANCY_MATH_387
16783    && flag_unsafe_math_optimizations"
16784 {
16785   operands[2] = gen_reg_rtx (XFmode);
16786   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16787 })
16788
16789 (define_expand "log10<mode>2"
16790   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16791    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16792   "TARGET_USE_FANCY_MATH_387
16793    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16794        || TARGET_MIX_SSE_I387)
16795    && flag_unsafe_math_optimizations"
16796 {
16797   rtx op0 = gen_reg_rtx (XFmode);
16798
16799   rtx op2 = gen_reg_rtx (XFmode);
16800   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16801
16802   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16803   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16804   DONE;
16805 })
16806
16807 (define_expand "log2xf2"
16808   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16809                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16810                                (match_dup 2)] UNSPEC_FYL2X))
16811               (clobber (match_scratch:XF 3 ""))])]
16812   "TARGET_USE_FANCY_MATH_387
16813    && flag_unsafe_math_optimizations"
16814 {
16815   operands[2] = gen_reg_rtx (XFmode);
16816   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16817 })
16818
16819 (define_expand "log2<mode>2"
16820   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16821    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16822   "TARGET_USE_FANCY_MATH_387
16823    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16824        || TARGET_MIX_SSE_I387)
16825    && flag_unsafe_math_optimizations"
16826 {
16827   rtx op0 = gen_reg_rtx (XFmode);
16828
16829   rtx op2 = gen_reg_rtx (XFmode);
16830   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16831
16832   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16833   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16834   DONE;
16835 })
16836
16837 (define_insn "fyl2xp1xf3_i387"
16838   [(set (match_operand:XF 0 "register_operand" "=f")
16839         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16840                     (match_operand:XF 2 "register_operand" "u")]
16841                    UNSPEC_FYL2XP1))
16842    (clobber (match_scratch:XF 3 "=2"))]
16843   "TARGET_USE_FANCY_MATH_387
16844    && flag_unsafe_math_optimizations"
16845   "fyl2xp1"
16846   [(set_attr "type" "fpspc")
16847    (set_attr "mode" "XF")])
16848
16849 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16850   [(set (match_operand:XF 0 "register_operand" "=f")
16851         (unspec:XF [(float_extend:XF
16852                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16853                     (match_operand:XF 2 "register_operand" "u")]
16854                    UNSPEC_FYL2XP1))
16855    (clobber (match_scratch:XF 3 "=2"))]
16856   "TARGET_USE_FANCY_MATH_387
16857    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16858        || TARGET_MIX_SSE_I387)
16859    && flag_unsafe_math_optimizations"
16860   "fyl2xp1"
16861   [(set_attr "type" "fpspc")
16862    (set_attr "mode" "XF")])
16863
16864 (define_expand "log1pxf2"
16865   [(use (match_operand:XF 0 "register_operand" ""))
16866    (use (match_operand:XF 1 "register_operand" ""))]
16867   "TARGET_USE_FANCY_MATH_387
16868    && flag_unsafe_math_optimizations && !optimize_size"
16869 {
16870   ix86_emit_i387_log1p (operands[0], operands[1]);
16871   DONE;
16872 })
16873
16874 (define_expand "log1p<mode>2"
16875   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16876    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16877   "TARGET_USE_FANCY_MATH_387
16878    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16879        || TARGET_MIX_SSE_I387)
16880    && flag_unsafe_math_optimizations && !optimize_size"
16881 {
16882   rtx op0 = gen_reg_rtx (XFmode);
16883
16884   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16885
16886   ix86_emit_i387_log1p (op0, operands[1]);
16887   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16888   DONE;
16889 })
16890
16891 (define_insn "fxtractxf3_i387"
16892   [(set (match_operand:XF 0 "register_operand" "=f")
16893         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16894                    UNSPEC_XTRACT_FRACT))
16895    (set (match_operand:XF 1 "register_operand" "=u")
16896         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16897   "TARGET_USE_FANCY_MATH_387
16898    && flag_unsafe_math_optimizations"
16899   "fxtract"
16900   [(set_attr "type" "fpspc")
16901    (set_attr "mode" "XF")])
16902
16903 (define_insn "fxtract_extend<mode>xf3_i387"
16904   [(set (match_operand:XF 0 "register_operand" "=f")
16905         (unspec:XF [(float_extend:XF
16906                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16907                    UNSPEC_XTRACT_FRACT))
16908    (set (match_operand:XF 1 "register_operand" "=u")
16909         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16910   "TARGET_USE_FANCY_MATH_387
16911    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16912        || TARGET_MIX_SSE_I387)
16913    && flag_unsafe_math_optimizations"
16914   "fxtract"
16915   [(set_attr "type" "fpspc")
16916    (set_attr "mode" "XF")])
16917
16918 (define_expand "logbxf2"
16919   [(parallel [(set (match_dup 2)
16920                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16921                               UNSPEC_XTRACT_FRACT))
16922               (set (match_operand:XF 0 "register_operand" "")
16923                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16924   "TARGET_USE_FANCY_MATH_387
16925    && flag_unsafe_math_optimizations"
16926 {
16927   operands[2] = gen_reg_rtx (XFmode);
16928 })
16929
16930 (define_expand "logb<mode>2"
16931   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16932    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16933   "TARGET_USE_FANCY_MATH_387
16934    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16935        || TARGET_MIX_SSE_I387)
16936    && flag_unsafe_math_optimizations"
16937 {
16938   rtx op0 = gen_reg_rtx (XFmode);
16939   rtx op1 = gen_reg_rtx (XFmode);
16940
16941   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16942   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16943   DONE;
16944 })
16945
16946 (define_expand "ilogbxf2"
16947   [(use (match_operand:SI 0 "register_operand" ""))
16948    (use (match_operand:XF 1 "register_operand" ""))]
16949   "TARGET_USE_FANCY_MATH_387
16950    && flag_unsafe_math_optimizations && !optimize_size"
16951 {
16952   rtx op0 = gen_reg_rtx (XFmode);
16953   rtx op1 = gen_reg_rtx (XFmode);
16954
16955   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16956   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16957   DONE;
16958 })
16959
16960 (define_expand "ilogb<mode>2"
16961   [(use (match_operand:SI 0 "register_operand" ""))
16962    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16963   "TARGET_USE_FANCY_MATH_387
16964    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16965        || TARGET_MIX_SSE_I387)
16966    && flag_unsafe_math_optimizations && !optimize_size"
16967 {
16968   rtx op0 = gen_reg_rtx (XFmode);
16969   rtx op1 = gen_reg_rtx (XFmode);
16970
16971   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16972   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16973   DONE;
16974 })
16975
16976 (define_insn "*f2xm1xf2_i387"
16977   [(set (match_operand:XF 0 "register_operand" "=f")
16978         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16979                    UNSPEC_F2XM1))]
16980   "TARGET_USE_FANCY_MATH_387
16981    && flag_unsafe_math_optimizations"
16982   "f2xm1"
16983   [(set_attr "type" "fpspc")
16984    (set_attr "mode" "XF")])
16985
16986 (define_insn "*fscalexf4_i387"
16987   [(set (match_operand:XF 0 "register_operand" "=f")
16988         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16989                     (match_operand:XF 3 "register_operand" "1")]
16990                    UNSPEC_FSCALE_FRACT))
16991    (set (match_operand:XF 1 "register_operand" "=u")
16992         (unspec:XF [(match_dup 2) (match_dup 3)]
16993                    UNSPEC_FSCALE_EXP))]
16994   "TARGET_USE_FANCY_MATH_387
16995    && flag_unsafe_math_optimizations"
16996   "fscale"
16997   [(set_attr "type" "fpspc")
16998    (set_attr "mode" "XF")])
16999
17000 (define_expand "expNcorexf3"
17001   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17002                                (match_operand:XF 2 "register_operand" "")))
17003    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17004    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17005    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17006    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17007    (parallel [(set (match_operand:XF 0 "register_operand" "")
17008                    (unspec:XF [(match_dup 8) (match_dup 4)]
17009                               UNSPEC_FSCALE_FRACT))
17010               (set (match_dup 9)
17011                    (unspec:XF [(match_dup 8) (match_dup 4)]
17012                               UNSPEC_FSCALE_EXP))])]
17013   "TARGET_USE_FANCY_MATH_387
17014    && flag_unsafe_math_optimizations && !optimize_size"
17015 {
17016   int i;
17017
17018   for (i = 3; i < 10; i++)
17019     operands[i] = gen_reg_rtx (XFmode);
17020
17021   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17022 })
17023
17024 (define_expand "expxf2"
17025   [(use (match_operand:XF 0 "register_operand" ""))
17026    (use (match_operand:XF 1 "register_operand" ""))]
17027   "TARGET_USE_FANCY_MATH_387
17028    && flag_unsafe_math_optimizations && !optimize_size"
17029 {
17030   rtx op2 = gen_reg_rtx (XFmode);
17031   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17032
17033   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17034   DONE;
17035 })
17036
17037 (define_expand "exp<mode>2"
17038   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17039    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17040  "TARGET_USE_FANCY_MATH_387
17041    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17042        || TARGET_MIX_SSE_I387)
17043    && flag_unsafe_math_optimizations && !optimize_size"
17044 {
17045   rtx op0 = gen_reg_rtx (XFmode);
17046   rtx op1 = gen_reg_rtx (XFmode);
17047
17048   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17049   emit_insn (gen_expxf2 (op0, op1));
17050   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17051   DONE;
17052 })
17053
17054 (define_expand "exp10xf2"
17055   [(use (match_operand:XF 0 "register_operand" ""))
17056    (use (match_operand:XF 1 "register_operand" ""))]
17057   "TARGET_USE_FANCY_MATH_387
17058    && flag_unsafe_math_optimizations && !optimize_size"
17059 {
17060   rtx op2 = gen_reg_rtx (XFmode);
17061   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17062
17063   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17064   DONE;
17065 })
17066
17067 (define_expand "exp10<mode>2"
17068   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17069    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17070  "TARGET_USE_FANCY_MATH_387
17071    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17072        || TARGET_MIX_SSE_I387)
17073    && flag_unsafe_math_optimizations && !optimize_size"
17074 {
17075   rtx op0 = gen_reg_rtx (XFmode);
17076   rtx op1 = gen_reg_rtx (XFmode);
17077
17078   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17079   emit_insn (gen_exp10xf2 (op0, op1));
17080   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17081   DONE;
17082 })
17083
17084 (define_expand "exp2xf2"
17085   [(use (match_operand:XF 0 "register_operand" ""))
17086    (use (match_operand:XF 1 "register_operand" ""))]
17087   "TARGET_USE_FANCY_MATH_387
17088    && flag_unsafe_math_optimizations && !optimize_size"
17089 {
17090   rtx op2 = gen_reg_rtx (XFmode);
17091   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17092
17093   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17094   DONE;
17095 })
17096
17097 (define_expand "exp2<mode>2"
17098   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17099    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17100  "TARGET_USE_FANCY_MATH_387
17101    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17102        || TARGET_MIX_SSE_I387)
17103    && flag_unsafe_math_optimizations && !optimize_size"
17104 {
17105   rtx op0 = gen_reg_rtx (XFmode);
17106   rtx op1 = gen_reg_rtx (XFmode);
17107
17108   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17109   emit_insn (gen_exp2xf2 (op0, op1));
17110   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17111   DONE;
17112 })
17113
17114 (define_expand "expm1xf2"
17115   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17116                                (match_dup 2)))
17117    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17118    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17119    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17120    (parallel [(set (match_dup 7)
17121                    (unspec:XF [(match_dup 6) (match_dup 4)]
17122                               UNSPEC_FSCALE_FRACT))
17123                    (set (match_dup 8)
17124                    (unspec:XF [(match_dup 6) (match_dup 4)]
17125                               UNSPEC_FSCALE_EXP))])
17126    (parallel [(set (match_dup 10)
17127                    (unspec:XF [(match_dup 9) (match_dup 8)]
17128                               UNSPEC_FSCALE_FRACT))
17129               (set (match_dup 11)
17130                    (unspec:XF [(match_dup 9) (match_dup 8)]
17131                               UNSPEC_FSCALE_EXP))])
17132    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17133    (set (match_operand:XF 0 "register_operand" "")
17134         (plus:XF (match_dup 12) (match_dup 7)))]
17135   "TARGET_USE_FANCY_MATH_387
17136    && flag_unsafe_math_optimizations && !optimize_size"
17137 {
17138   int i;
17139
17140   for (i = 2; i < 13; i++)
17141     operands[i] = gen_reg_rtx (XFmode);
17142  
17143   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17144   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
17145 })
17146
17147 (define_expand "expm1<mode>2"
17148   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17149    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17150  "TARGET_USE_FANCY_MATH_387
17151    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17152        || TARGET_MIX_SSE_I387)
17153    && flag_unsafe_math_optimizations && !optimize_size"
17154 {
17155   rtx op0 = gen_reg_rtx (XFmode);
17156   rtx op1 = gen_reg_rtx (XFmode);
17157
17158   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17159   emit_insn (gen_expm1xf2 (op0, op1));
17160   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17161   DONE;
17162 })
17163
17164 (define_expand "ldexpxf3"
17165   [(set (match_dup 3)
17166         (float:XF (match_operand:SI 2 "register_operand" "")))
17167    (parallel [(set (match_operand:XF 0 " register_operand" "")
17168                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17169                                (match_dup 3)]
17170                               UNSPEC_FSCALE_FRACT))
17171               (set (match_dup 4)
17172                    (unspec:XF [(match_dup 1) (match_dup 3)]
17173                               UNSPEC_FSCALE_EXP))])]
17174   "TARGET_USE_FANCY_MATH_387
17175    && flag_unsafe_math_optimizations && !optimize_size"
17176 {
17177   operands[3] = gen_reg_rtx (XFmode);
17178   operands[4] = gen_reg_rtx (XFmode);
17179 })
17180
17181 (define_expand "ldexp<mode>3"
17182   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17183    (use (match_operand:X87MODEF12 1 "general_operand" ""))
17184    (use (match_operand:SI 2 "register_operand" ""))]
17185  "TARGET_USE_FANCY_MATH_387
17186    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17187        || TARGET_MIX_SSE_I387)
17188    && flag_unsafe_math_optimizations && !optimize_size"
17189 {
17190   rtx op0 = gen_reg_rtx (XFmode);
17191   rtx op1 = gen_reg_rtx (XFmode);
17192
17193   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17194   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17195   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17196   DONE;
17197 })
17198 \f
17199
17200 (define_insn "frndintxf2"
17201   [(set (match_operand:XF 0 "register_operand" "=f")
17202         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17203          UNSPEC_FRNDINT))]
17204   "TARGET_USE_FANCY_MATH_387
17205    && flag_unsafe_math_optimizations"
17206   "frndint"
17207   [(set_attr "type" "fpspc")
17208    (set_attr "mode" "XF")])
17209
17210 (define_expand "rintdf2"
17211   [(use (match_operand:DF 0 "register_operand" ""))
17212    (use (match_operand:DF 1 "register_operand" ""))]
17213   "(TARGET_USE_FANCY_MATH_387
17214     && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17215     && flag_unsafe_math_optimizations)
17216    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17217        && !flag_trapping_math
17218        && !optimize_size)"
17219 {
17220   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17221       && !flag_trapping_math
17222       && !optimize_size)
17223     ix86_expand_rint (operand0, operand1);
17224   else
17225     {
17226       rtx op0 = gen_reg_rtx (XFmode);
17227       rtx op1 = gen_reg_rtx (XFmode);
17228
17229       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17230       emit_insn (gen_frndintxf2 (op0, op1));
17231
17232       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17233     }
17234   DONE;
17235 })
17236
17237 (define_expand "rintsf2"
17238   [(use (match_operand:SF 0 "register_operand" ""))
17239    (use (match_operand:SF 1 "register_operand" ""))]
17240   "(TARGET_USE_FANCY_MATH_387
17241     && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17242     && flag_unsafe_math_optimizations)
17243    || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17244        && !flag_trapping_math
17245        && !optimize_size)"
17246 {
17247   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17248       && !flag_trapping_math
17249       && !optimize_size)
17250     ix86_expand_rint (operand0, operand1);
17251   else
17252     {
17253       rtx op0 = gen_reg_rtx (XFmode);
17254       rtx op1 = gen_reg_rtx (XFmode);
17255
17256       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17257       emit_insn (gen_frndintxf2 (op0, op1));
17258
17259       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17260     }
17261   DONE;
17262 })
17263
17264 (define_expand "rintxf2"
17265   [(use (match_operand:XF 0 "register_operand" ""))
17266    (use (match_operand:XF 1 "register_operand" ""))]
17267   "TARGET_USE_FANCY_MATH_387
17268    && flag_unsafe_math_optimizations && !optimize_size"
17269 {
17270   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17271   DONE;
17272 })
17273
17274 (define_expand "roundsf2"
17275   [(match_operand:SF 0 "register_operand" "")
17276    (match_operand:SF 1 "nonimmediate_operand" "")]
17277   "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17278    && !flag_trapping_math && !flag_rounding_math
17279    && !optimize_size"
17280 {
17281   ix86_expand_round (operand0, operand1);
17282   DONE;
17283 })
17284
17285 (define_expand "rounddf2"
17286   [(match_operand:DF 0 "register_operand" "")
17287    (match_operand:DF 1 "nonimmediate_operand" "")]
17288   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17289    && !flag_trapping_math && !flag_rounding_math
17290    && !optimize_size"
17291 {
17292   if (TARGET_64BIT)
17293     ix86_expand_round (operand0, operand1);
17294   else
17295     ix86_expand_rounddf_32 (operand0, operand1);
17296   DONE;
17297 })
17298
17299 (define_insn_and_split "*fistdi2_1"
17300   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17301         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17302          UNSPEC_FIST))]
17303   "TARGET_USE_FANCY_MATH_387
17304    && !(reload_completed || reload_in_progress)"
17305   "#"
17306   "&& 1"
17307   [(const_int 0)]
17308 {
17309   if (memory_operand (operands[0], VOIDmode))
17310     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17311   else
17312     {
17313       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17314       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17315                                          operands[2]));
17316     }
17317   DONE;
17318 }
17319   [(set_attr "type" "fpspc")
17320    (set_attr "mode" "DI")])
17321
17322 (define_insn "fistdi2"
17323   [(set (match_operand:DI 0 "memory_operand" "=m")
17324         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17325          UNSPEC_FIST))
17326    (clobber (match_scratch:XF 2 "=&1f"))]
17327   "TARGET_USE_FANCY_MATH_387"
17328   "* return output_fix_trunc (insn, operands, 0);"
17329   [(set_attr "type" "fpspc")
17330    (set_attr "mode" "DI")])
17331
17332 (define_insn "fistdi2_with_temp"
17333   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17334         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17335          UNSPEC_FIST))
17336    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17337    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17338   "TARGET_USE_FANCY_MATH_387"
17339   "#"
17340   [(set_attr "type" "fpspc")
17341    (set_attr "mode" "DI")])
17342
17343 (define_split
17344   [(set (match_operand:DI 0 "register_operand" "")
17345         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17346          UNSPEC_FIST))
17347    (clobber (match_operand:DI 2 "memory_operand" ""))
17348    (clobber (match_scratch 3 ""))]
17349   "reload_completed"
17350   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17351               (clobber (match_dup 3))])
17352    (set (match_dup 0) (match_dup 2))]
17353   "")
17354
17355 (define_split
17356   [(set (match_operand:DI 0 "memory_operand" "")
17357         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17358          UNSPEC_FIST))
17359    (clobber (match_operand:DI 2 "memory_operand" ""))
17360    (clobber (match_scratch 3 ""))]
17361   "reload_completed"
17362   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17363               (clobber (match_dup 3))])]
17364   "")
17365
17366 (define_insn_and_split "*fist<mode>2_1"
17367   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17368         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17369          UNSPEC_FIST))]
17370   "TARGET_USE_FANCY_MATH_387
17371    && !(reload_completed || reload_in_progress)"
17372   "#"
17373   "&& 1"
17374   [(const_int 0)]
17375 {
17376   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17377   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17378                                         operands[2]));
17379   DONE;
17380 }
17381   [(set_attr "type" "fpspc")
17382    (set_attr "mode" "<MODE>")])
17383
17384 (define_insn "fist<mode>2"
17385   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17386         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17387          UNSPEC_FIST))]
17388   "TARGET_USE_FANCY_MATH_387"
17389   "* return output_fix_trunc (insn, operands, 0);"
17390   [(set_attr "type" "fpspc")
17391    (set_attr "mode" "<MODE>")])
17392
17393 (define_insn "fist<mode>2_with_temp"
17394   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17395         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17396          UNSPEC_FIST))
17397    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17398   "TARGET_USE_FANCY_MATH_387"
17399   "#"
17400   [(set_attr "type" "fpspc")
17401    (set_attr "mode" "<MODE>")])
17402
17403 (define_split
17404   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17405         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17406          UNSPEC_FIST))
17407    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17408   "reload_completed"
17409   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17410                        UNSPEC_FIST))
17411    (set (match_dup 0) (match_dup 2))]
17412   "")
17413
17414 (define_split
17415   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17416         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17417          UNSPEC_FIST))
17418    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17419   "reload_completed"
17420   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17421                        UNSPEC_FIST))]
17422   "")
17423
17424 (define_expand "lrintxf<mode>2"
17425   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17426      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17427       UNSPEC_FIST))]
17428   "TARGET_USE_FANCY_MATH_387"
17429   "")
17430
17431 (define_expand "lrint<mode>di2"
17432   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17433      (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
17434       UNSPEC_FIX_NOTRUNC))]
17435   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
17436   "")
17437
17438 (define_expand "lrint<mode>si2"
17439   [(set (match_operand:SI 0 "nonimmediate_operand" "")
17440      (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
17441       UNSPEC_FIX_NOTRUNC))]
17442   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17443   "")
17444
17445 (define_expand "lround<mode>di2"
17446   [(match_operand:DI 0 "nonimmediate_operand" "")
17447    (match_operand:SSEMODEF 1 "register_operand" "")]
17448   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17449    && !flag_trapping_math && !flag_rounding_math
17450    && !optimize_size"
17451 {
17452   ix86_expand_lround (operand0, operand1);
17453   DONE;
17454 })
17455
17456 (define_expand "lround<mode>si2"
17457   [(match_operand:SI 0 "nonimmediate_operand" "")
17458    (match_operand:SSEMODEF 1 "register_operand" "")]
17459   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17460    && !flag_trapping_math && !flag_rounding_math
17461    && !optimize_size"
17462 {
17463   ix86_expand_lround (operand0, operand1);
17464   DONE;
17465 })
17466
17467 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17468 (define_insn_and_split "frndintxf2_floor"
17469   [(set (match_operand:XF 0 "register_operand" "=f")
17470         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17471          UNSPEC_FRNDINT_FLOOR))
17472    (clobber (reg:CC FLAGS_REG))]
17473   "TARGET_USE_FANCY_MATH_387
17474    && flag_unsafe_math_optimizations
17475    && !(reload_completed || reload_in_progress)"
17476   "#"
17477   "&& 1"
17478   [(const_int 0)]
17479 {
17480   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17481
17482   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17483   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17484
17485   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17486                                         operands[2], operands[3]));
17487   DONE;
17488 }
17489   [(set_attr "type" "frndint")
17490    (set_attr "i387_cw" "floor")
17491    (set_attr "mode" "XF")])
17492
17493 (define_insn "frndintxf2_floor_i387"
17494   [(set (match_operand:XF 0 "register_operand" "=f")
17495         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17496          UNSPEC_FRNDINT_FLOOR))
17497    (use (match_operand:HI 2 "memory_operand" "m"))
17498    (use (match_operand:HI 3 "memory_operand" "m"))]
17499   "TARGET_USE_FANCY_MATH_387
17500    && flag_unsafe_math_optimizations"
17501   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17502   [(set_attr "type" "frndint")
17503    (set_attr "i387_cw" "floor")
17504    (set_attr "mode" "XF")])
17505
17506 (define_expand "floorxf2"
17507   [(use (match_operand:XF 0 "register_operand" ""))
17508    (use (match_operand:XF 1 "register_operand" ""))]
17509   "TARGET_USE_FANCY_MATH_387
17510    && flag_unsafe_math_optimizations && !optimize_size"
17511 {
17512   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17513   DONE;
17514 })
17515
17516 (define_expand "floordf2"
17517   [(use (match_operand:DF 0 "register_operand" ""))
17518    (use (match_operand:DF 1 "register_operand" ""))]
17519   "((TARGET_USE_FANCY_MATH_387
17520      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17521      && flag_unsafe_math_optimizations)
17522     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17523         && !flag_trapping_math))
17524    && !optimize_size"
17525 {
17526   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17527       && !flag_trapping_math)
17528     {
17529       if (TARGET_64BIT)
17530         ix86_expand_floorceil (operand0, operand1, true);
17531       else
17532         ix86_expand_floorceildf_32 (operand0, operand1, true);
17533     }
17534   else
17535     {
17536       rtx op0 = gen_reg_rtx (XFmode);
17537       rtx op1 = gen_reg_rtx (XFmode);
17538
17539       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17540       emit_insn (gen_frndintxf2_floor (op0, op1));
17541
17542       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17543     }
17544   DONE;
17545 })
17546
17547 (define_expand "floorsf2"
17548   [(use (match_operand:SF 0 "register_operand" ""))
17549    (use (match_operand:SF 1 "register_operand" ""))]
17550   "((TARGET_USE_FANCY_MATH_387
17551      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17552      && flag_unsafe_math_optimizations)
17553     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17554         && !flag_trapping_math))
17555    && !optimize_size"
17556 {
17557   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17558       && !flag_trapping_math)
17559     ix86_expand_floorceil (operand0, operand1, true);
17560   else
17561     {
17562       rtx op0 = gen_reg_rtx (XFmode);
17563       rtx op1 = gen_reg_rtx (XFmode);
17564
17565       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17566       emit_insn (gen_frndintxf2_floor (op0, op1));
17567
17568       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17569     }
17570   DONE;
17571 })
17572
17573 (define_insn_and_split "*fist<mode>2_floor_1"
17574   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17575         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17576          UNSPEC_FIST_FLOOR))
17577    (clobber (reg:CC FLAGS_REG))]
17578   "TARGET_USE_FANCY_MATH_387
17579    && flag_unsafe_math_optimizations
17580    && !(reload_completed || reload_in_progress)"
17581   "#"
17582   "&& 1"
17583   [(const_int 0)]
17584 {
17585   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17586
17587   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17588   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17589   if (memory_operand (operands[0], VOIDmode))
17590     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17591                                       operands[2], operands[3]));
17592   else
17593     {
17594       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17595       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17596                                                   operands[2], operands[3],
17597                                                   operands[4]));
17598     }
17599   DONE;
17600 }
17601   [(set_attr "type" "fistp")
17602    (set_attr "i387_cw" "floor")
17603    (set_attr "mode" "<MODE>")])
17604
17605 (define_insn "fistdi2_floor"
17606   [(set (match_operand:DI 0 "memory_operand" "=m")
17607         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17608          UNSPEC_FIST_FLOOR))
17609    (use (match_operand:HI 2 "memory_operand" "m"))
17610    (use (match_operand:HI 3 "memory_operand" "m"))
17611    (clobber (match_scratch:XF 4 "=&1f"))]
17612   "TARGET_USE_FANCY_MATH_387
17613    && flag_unsafe_math_optimizations"
17614   "* return output_fix_trunc (insn, operands, 0);"
17615   [(set_attr "type" "fistp")
17616    (set_attr "i387_cw" "floor")
17617    (set_attr "mode" "DI")])
17618
17619 (define_insn "fistdi2_floor_with_temp"
17620   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17621         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17622          UNSPEC_FIST_FLOOR))
17623    (use (match_operand:HI 2 "memory_operand" "m,m"))
17624    (use (match_operand:HI 3 "memory_operand" "m,m"))
17625    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17626    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17627   "TARGET_USE_FANCY_MATH_387
17628    && flag_unsafe_math_optimizations"
17629   "#"
17630   [(set_attr "type" "fistp")
17631    (set_attr "i387_cw" "floor")
17632    (set_attr "mode" "DI")])
17633
17634 (define_split
17635   [(set (match_operand:DI 0 "register_operand" "")
17636         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17637          UNSPEC_FIST_FLOOR))
17638    (use (match_operand:HI 2 "memory_operand" ""))
17639    (use (match_operand:HI 3 "memory_operand" ""))
17640    (clobber (match_operand:DI 4 "memory_operand" ""))
17641    (clobber (match_scratch 5 ""))]
17642   "reload_completed"
17643   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17644               (use (match_dup 2))
17645               (use (match_dup 3))
17646               (clobber (match_dup 5))])
17647    (set (match_dup 0) (match_dup 4))]
17648   "")
17649
17650 (define_split
17651   [(set (match_operand:DI 0 "memory_operand" "")
17652         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17653          UNSPEC_FIST_FLOOR))
17654    (use (match_operand:HI 2 "memory_operand" ""))
17655    (use (match_operand:HI 3 "memory_operand" ""))
17656    (clobber (match_operand:DI 4 "memory_operand" ""))
17657    (clobber (match_scratch 5 ""))]
17658   "reload_completed"
17659   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17660               (use (match_dup 2))
17661               (use (match_dup 3))
17662               (clobber (match_dup 5))])]
17663   "")
17664
17665 (define_insn "fist<mode>2_floor"
17666   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17667         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17668          UNSPEC_FIST_FLOOR))
17669    (use (match_operand:HI 2 "memory_operand" "m"))
17670    (use (match_operand:HI 3 "memory_operand" "m"))]
17671   "TARGET_USE_FANCY_MATH_387
17672    && flag_unsafe_math_optimizations"
17673   "* return output_fix_trunc (insn, operands, 0);"
17674   [(set_attr "type" "fistp")
17675    (set_attr "i387_cw" "floor")
17676    (set_attr "mode" "<MODE>")])
17677
17678 (define_insn "fist<mode>2_floor_with_temp"
17679   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17680         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17681          UNSPEC_FIST_FLOOR))
17682    (use (match_operand:HI 2 "memory_operand" "m,m"))
17683    (use (match_operand:HI 3 "memory_operand" "m,m"))
17684    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17685   "TARGET_USE_FANCY_MATH_387
17686    && flag_unsafe_math_optimizations"
17687   "#"
17688   [(set_attr "type" "fistp")
17689    (set_attr "i387_cw" "floor")
17690    (set_attr "mode" "<MODE>")])
17691
17692 (define_split
17693   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17694         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17695          UNSPEC_FIST_FLOOR))
17696    (use (match_operand:HI 2 "memory_operand" ""))
17697    (use (match_operand:HI 3 "memory_operand" ""))
17698    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17699   "reload_completed"
17700   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17701                                   UNSPEC_FIST_FLOOR))
17702               (use (match_dup 2))
17703               (use (match_dup 3))])
17704    (set (match_dup 0) (match_dup 4))]
17705   "")
17706
17707 (define_split
17708   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17709         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17710          UNSPEC_FIST_FLOOR))
17711    (use (match_operand:HI 2 "memory_operand" ""))
17712    (use (match_operand:HI 3 "memory_operand" ""))
17713    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17714   "reload_completed"
17715   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17716                                   UNSPEC_FIST_FLOOR))
17717               (use (match_dup 2))
17718               (use (match_dup 3))])]
17719   "")
17720
17721 (define_expand "lfloorxf<mode>2"
17722   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17723                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17724                     UNSPEC_FIST_FLOOR))
17725               (clobber (reg:CC FLAGS_REG))])]
17726   "TARGET_USE_FANCY_MATH_387
17727    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17728    && flag_unsafe_math_optimizations"
17729   "")
17730
17731 (define_expand "lfloor<mode>di2"
17732   [(match_operand:DI 0 "nonimmediate_operand" "")
17733    (match_operand:SSEMODEF 1 "register_operand" "")]
17734   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17735    && !flag_trapping_math
17736    && !optimize_size"
17737 {
17738   ix86_expand_lfloorceil (operand0, operand1, true);
17739   DONE;
17740 })
17741
17742 (define_expand "lfloor<mode>si2"
17743   [(match_operand:SI 0 "nonimmediate_operand" "")
17744    (match_operand:SSEMODEF 1 "register_operand" "")]
17745   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17746    && !flag_trapping_math
17747    && (!optimize_size || !TARGET_64BIT)"
17748 {
17749   ix86_expand_lfloorceil (operand0, operand1, true);
17750   DONE;
17751 })
17752
17753 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17754 (define_insn_and_split "frndintxf2_ceil"
17755   [(set (match_operand:XF 0 "register_operand" "=f")
17756         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17757          UNSPEC_FRNDINT_CEIL))
17758    (clobber (reg:CC FLAGS_REG))]
17759   "TARGET_USE_FANCY_MATH_387
17760    && flag_unsafe_math_optimizations
17761    && !(reload_completed || reload_in_progress)"
17762   "#"
17763   "&& 1"
17764   [(const_int 0)]
17765 {
17766   ix86_optimize_mode_switching[I387_CEIL] = 1;
17767
17768   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17769   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17770
17771   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17772                                        operands[2], operands[3]));
17773   DONE;
17774 }
17775   [(set_attr "type" "frndint")
17776    (set_attr "i387_cw" "ceil")
17777    (set_attr "mode" "XF")])
17778
17779 (define_insn "frndintxf2_ceil_i387"
17780   [(set (match_operand:XF 0 "register_operand" "=f")
17781         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17782          UNSPEC_FRNDINT_CEIL))
17783    (use (match_operand:HI 2 "memory_operand" "m"))
17784    (use (match_operand:HI 3 "memory_operand" "m"))]
17785   "TARGET_USE_FANCY_MATH_387
17786    && flag_unsafe_math_optimizations"
17787   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17788   [(set_attr "type" "frndint")
17789    (set_attr "i387_cw" "ceil")
17790    (set_attr "mode" "XF")])
17791
17792 (define_expand "ceilxf2"
17793   [(use (match_operand:XF 0 "register_operand" ""))
17794    (use (match_operand:XF 1 "register_operand" ""))]
17795   "TARGET_USE_FANCY_MATH_387
17796    && flag_unsafe_math_optimizations && !optimize_size"
17797 {
17798   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17799   DONE;
17800 })
17801
17802 (define_expand "ceildf2"
17803   [(use (match_operand:DF 0 "register_operand" ""))
17804    (use (match_operand:DF 1 "register_operand" ""))]
17805   "((TARGET_USE_FANCY_MATH_387
17806      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17807      && flag_unsafe_math_optimizations)
17808     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17809         && !flag_trapping_math))
17810    && !optimize_size"
17811 {
17812   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17813       && !flag_trapping_math)
17814     {
17815       if (TARGET_64BIT)
17816         ix86_expand_floorceil (operand0, operand1, false);
17817       else
17818         ix86_expand_floorceildf_32 (operand0, operand1, false);
17819     }
17820   else
17821     {
17822       rtx op0 = gen_reg_rtx (XFmode);
17823       rtx op1 = gen_reg_rtx (XFmode);
17824
17825       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17826       emit_insn (gen_frndintxf2_ceil (op0, op1));
17827
17828       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17829     }
17830   DONE;
17831 })
17832
17833 (define_expand "ceilsf2"
17834   [(use (match_operand:SF 0 "register_operand" ""))
17835    (use (match_operand:SF 1 "register_operand" ""))]
17836   "((TARGET_USE_FANCY_MATH_387
17837      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17838      && flag_unsafe_math_optimizations)
17839     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17840         && !flag_trapping_math))
17841    && !optimize_size"
17842 {
17843   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17844       && !flag_trapping_math)
17845     ix86_expand_floorceil (operand0, operand1, false);
17846   else
17847     {
17848       rtx op0 = gen_reg_rtx (XFmode);
17849       rtx op1 = gen_reg_rtx (XFmode);
17850
17851       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17852       emit_insn (gen_frndintxf2_ceil (op0, op1));
17853
17854       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17855     }
17856   DONE;
17857 })
17858
17859 (define_insn_and_split "*fist<mode>2_ceil_1"
17860   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17861         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17862          UNSPEC_FIST_CEIL))
17863    (clobber (reg:CC FLAGS_REG))]
17864   "TARGET_USE_FANCY_MATH_387
17865    && flag_unsafe_math_optimizations
17866    && !(reload_completed || reload_in_progress)"
17867   "#"
17868   "&& 1"
17869   [(const_int 0)]
17870 {
17871   ix86_optimize_mode_switching[I387_CEIL] = 1;
17872
17873   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17874   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17875   if (memory_operand (operands[0], VOIDmode))
17876     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17877                                      operands[2], operands[3]));
17878   else
17879     {
17880       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17881       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17882                                                  operands[2], operands[3],
17883                                                  operands[4]));
17884     }
17885   DONE;
17886 }
17887   [(set_attr "type" "fistp")
17888    (set_attr "i387_cw" "ceil")
17889    (set_attr "mode" "<MODE>")])
17890
17891 (define_insn "fistdi2_ceil"
17892   [(set (match_operand:DI 0 "memory_operand" "=m")
17893         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17894          UNSPEC_FIST_CEIL))
17895    (use (match_operand:HI 2 "memory_operand" "m"))
17896    (use (match_operand:HI 3 "memory_operand" "m"))
17897    (clobber (match_scratch:XF 4 "=&1f"))]
17898   "TARGET_USE_FANCY_MATH_387
17899    && flag_unsafe_math_optimizations"
17900   "* return output_fix_trunc (insn, operands, 0);"
17901   [(set_attr "type" "fistp")
17902    (set_attr "i387_cw" "ceil")
17903    (set_attr "mode" "DI")])
17904
17905 (define_insn "fistdi2_ceil_with_temp"
17906   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17907         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17908          UNSPEC_FIST_CEIL))
17909    (use (match_operand:HI 2 "memory_operand" "m,m"))
17910    (use (match_operand:HI 3 "memory_operand" "m,m"))
17911    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17912    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17913   "TARGET_USE_FANCY_MATH_387
17914    && flag_unsafe_math_optimizations"
17915   "#"
17916   [(set_attr "type" "fistp")
17917    (set_attr "i387_cw" "ceil")
17918    (set_attr "mode" "DI")])
17919
17920 (define_split
17921   [(set (match_operand:DI 0 "register_operand" "")
17922         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17923          UNSPEC_FIST_CEIL))
17924    (use (match_operand:HI 2 "memory_operand" ""))
17925    (use (match_operand:HI 3 "memory_operand" ""))
17926    (clobber (match_operand:DI 4 "memory_operand" ""))
17927    (clobber (match_scratch 5 ""))]
17928   "reload_completed"
17929   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17930               (use (match_dup 2))
17931               (use (match_dup 3))
17932               (clobber (match_dup 5))])
17933    (set (match_dup 0) (match_dup 4))]
17934   "")
17935
17936 (define_split
17937   [(set (match_operand:DI 0 "memory_operand" "")
17938         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17939          UNSPEC_FIST_CEIL))
17940    (use (match_operand:HI 2 "memory_operand" ""))
17941    (use (match_operand:HI 3 "memory_operand" ""))
17942    (clobber (match_operand:DI 4 "memory_operand" ""))
17943    (clobber (match_scratch 5 ""))]
17944   "reload_completed"
17945   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17946               (use (match_dup 2))
17947               (use (match_dup 3))
17948               (clobber (match_dup 5))])]
17949   "")
17950
17951 (define_insn "fist<mode>2_ceil"
17952   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17953         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17954          UNSPEC_FIST_CEIL))
17955    (use (match_operand:HI 2 "memory_operand" "m"))
17956    (use (match_operand:HI 3 "memory_operand" "m"))]
17957   "TARGET_USE_FANCY_MATH_387
17958    && flag_unsafe_math_optimizations"
17959   "* return output_fix_trunc (insn, operands, 0);"
17960   [(set_attr "type" "fistp")
17961    (set_attr "i387_cw" "ceil")
17962    (set_attr "mode" "<MODE>")])
17963
17964 (define_insn "fist<mode>2_ceil_with_temp"
17965   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17966         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17967          UNSPEC_FIST_CEIL))
17968    (use (match_operand:HI 2 "memory_operand" "m,m"))
17969    (use (match_operand:HI 3 "memory_operand" "m,m"))
17970    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17971   "TARGET_USE_FANCY_MATH_387
17972    && flag_unsafe_math_optimizations"
17973   "#"
17974   [(set_attr "type" "fistp")
17975    (set_attr "i387_cw" "ceil")
17976    (set_attr "mode" "<MODE>")])
17977
17978 (define_split
17979   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17980         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17981          UNSPEC_FIST_CEIL))
17982    (use (match_operand:HI 2 "memory_operand" ""))
17983    (use (match_operand:HI 3 "memory_operand" ""))
17984    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17985   "reload_completed"
17986   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17987                                   UNSPEC_FIST_CEIL))
17988               (use (match_dup 2))
17989               (use (match_dup 3))])
17990    (set (match_dup 0) (match_dup 4))]
17991   "")
17992
17993 (define_split
17994   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17995         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17996          UNSPEC_FIST_CEIL))
17997    (use (match_operand:HI 2 "memory_operand" ""))
17998    (use (match_operand:HI 3 "memory_operand" ""))
17999    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18000   "reload_completed"
18001   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18002                                   UNSPEC_FIST_CEIL))
18003               (use (match_dup 2))
18004               (use (match_dup 3))])]
18005   "")
18006
18007 (define_expand "lceilxf<mode>2"
18008   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18009                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18010                     UNSPEC_FIST_CEIL))
18011               (clobber (reg:CC FLAGS_REG))])]
18012   "TARGET_USE_FANCY_MATH_387
18013    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18014    && flag_unsafe_math_optimizations"
18015   "")
18016
18017 (define_expand "lceil<mode>di2"
18018   [(match_operand:DI 0 "nonimmediate_operand" "")
18019    (match_operand:SSEMODEF 1 "register_operand" "")]
18020   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18021    && !flag_trapping_math"
18022 {
18023   ix86_expand_lfloorceil (operand0, operand1, false);
18024   DONE;
18025 })
18026
18027 (define_expand "lceil<mode>si2"
18028   [(match_operand:SI 0 "nonimmediate_operand" "")
18029    (match_operand:SSEMODEF 1 "register_operand" "")]
18030   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18031    && !flag_trapping_math"
18032 {
18033   ix86_expand_lfloorceil (operand0, operand1, false);
18034   DONE;
18035 })
18036
18037 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18038 (define_insn_and_split "frndintxf2_trunc"
18039   [(set (match_operand:XF 0 "register_operand" "=f")
18040         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18041          UNSPEC_FRNDINT_TRUNC))
18042    (clobber (reg:CC FLAGS_REG))]
18043   "TARGET_USE_FANCY_MATH_387
18044    && flag_unsafe_math_optimizations
18045    && !(reload_completed || reload_in_progress)"
18046   "#"
18047   "&& 1"
18048   [(const_int 0)]
18049 {
18050   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18051
18052   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18053   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18054
18055   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18056                                         operands[2], operands[3]));
18057   DONE;
18058 }
18059   [(set_attr "type" "frndint")
18060    (set_attr "i387_cw" "trunc")
18061    (set_attr "mode" "XF")])
18062
18063 (define_insn "frndintxf2_trunc_i387"
18064   [(set (match_operand:XF 0 "register_operand" "=f")
18065         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18066          UNSPEC_FRNDINT_TRUNC))
18067    (use (match_operand:HI 2 "memory_operand" "m"))
18068    (use (match_operand:HI 3 "memory_operand" "m"))]
18069   "TARGET_USE_FANCY_MATH_387
18070    && flag_unsafe_math_optimizations"
18071   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18072   [(set_attr "type" "frndint")
18073    (set_attr "i387_cw" "trunc")
18074    (set_attr "mode" "XF")])
18075
18076 (define_expand "btruncxf2"
18077   [(use (match_operand:XF 0 "register_operand" ""))
18078    (use (match_operand:XF 1 "register_operand" ""))]
18079   "TARGET_USE_FANCY_MATH_387
18080    && flag_unsafe_math_optimizations && !optimize_size"
18081 {
18082   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18083   DONE;
18084 })
18085
18086 (define_expand "btruncdf2"
18087   [(use (match_operand:DF 0 "register_operand" ""))
18088    (use (match_operand:DF 1 "register_operand" ""))]
18089   "((TARGET_USE_FANCY_MATH_387
18090      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18091      && flag_unsafe_math_optimizations)
18092     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18093         && !flag_trapping_math))
18094    && !optimize_size"
18095 {
18096   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18097       && !flag_trapping_math)
18098     {
18099       if (TARGET_64BIT)
18100         ix86_expand_trunc (operand0, operand1);
18101       else
18102         ix86_expand_truncdf_32 (operand0, operand1);
18103     }
18104   else
18105     {
18106       rtx op0 = gen_reg_rtx (XFmode);
18107       rtx op1 = gen_reg_rtx (XFmode);
18108
18109       emit_insn (gen_extenddfxf2 (op1, operands[1]));
18110       emit_insn (gen_frndintxf2_trunc (op0, op1));
18111
18112       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18113     }
18114   DONE;
18115 })
18116
18117 (define_expand "btruncsf2"
18118   [(use (match_operand:SF 0 "register_operand" ""))
18119    (use (match_operand:SF 1 "register_operand" ""))]
18120   "((TARGET_USE_FANCY_MATH_387
18121      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18122      && flag_unsafe_math_optimizations)
18123     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18124         && !flag_trapping_math))
18125    && !optimize_size"
18126 {
18127   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18128       && !flag_trapping_math)
18129     ix86_expand_trunc (operand0, operand1);
18130   else
18131     {
18132       rtx op0 = gen_reg_rtx (XFmode);
18133       rtx op1 = gen_reg_rtx (XFmode);
18134
18135       emit_insn (gen_extendsfxf2 (op1, operands[1]));
18136       emit_insn (gen_frndintxf2_trunc (op0, op1));
18137
18138       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18139     }
18140   DONE;
18141 })
18142
18143 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18144 (define_insn_and_split "frndintxf2_mask_pm"
18145   [(set (match_operand:XF 0 "register_operand" "=f")
18146         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18147          UNSPEC_FRNDINT_MASK_PM))
18148    (clobber (reg:CC FLAGS_REG))]
18149   "TARGET_USE_FANCY_MATH_387
18150    && flag_unsafe_math_optimizations
18151    && !(reload_completed || reload_in_progress)"
18152   "#"
18153   "&& 1"
18154   [(const_int 0)]
18155 {
18156   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18157
18158   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18159   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18160
18161   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18162                                           operands[2], operands[3]));
18163   DONE;
18164 }
18165   [(set_attr "type" "frndint")
18166    (set_attr "i387_cw" "mask_pm")
18167    (set_attr "mode" "XF")])
18168
18169 (define_insn "frndintxf2_mask_pm_i387"
18170   [(set (match_operand:XF 0 "register_operand" "=f")
18171         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18172          UNSPEC_FRNDINT_MASK_PM))
18173    (use (match_operand:HI 2 "memory_operand" "m"))
18174    (use (match_operand:HI 3 "memory_operand" "m"))]
18175   "TARGET_USE_FANCY_MATH_387
18176    && flag_unsafe_math_optimizations"
18177   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18178   [(set_attr "type" "frndint")
18179    (set_attr "i387_cw" "mask_pm")
18180    (set_attr "mode" "XF")])
18181
18182 (define_expand "nearbyintxf2"
18183   [(use (match_operand:XF 0 "register_operand" ""))
18184    (use (match_operand:XF 1 "register_operand" ""))]
18185   "TARGET_USE_FANCY_MATH_387
18186    && flag_unsafe_math_optimizations"
18187 {
18188   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18189
18190   DONE;
18191 })
18192
18193 (define_expand "nearbyintdf2"
18194   [(use (match_operand:DF 0 "register_operand" ""))
18195    (use (match_operand:DF 1 "register_operand" ""))]
18196   "TARGET_USE_FANCY_MATH_387
18197    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18198    && flag_unsafe_math_optimizations"
18199 {
18200   rtx op0 = gen_reg_rtx (XFmode);
18201   rtx op1 = gen_reg_rtx (XFmode);
18202
18203   emit_insn (gen_extenddfxf2 (op1, operands[1]));
18204   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18205
18206   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18207   DONE;
18208 })
18209
18210 (define_expand "nearbyintsf2"
18211   [(use (match_operand:SF 0 "register_operand" ""))
18212    (use (match_operand:SF 1 "register_operand" ""))]
18213   "TARGET_USE_FANCY_MATH_387
18214    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18215    && flag_unsafe_math_optimizations"
18216 {
18217   rtx op0 = gen_reg_rtx (XFmode);
18218   rtx op1 = gen_reg_rtx (XFmode);
18219
18220   emit_insn (gen_extendsfxf2 (op1, operands[1]));
18221   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18222
18223   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18224   DONE;
18225 })
18226
18227 (define_insn "fxam<mode>2_i387"
18228   [(set (match_operand:HI 0 "register_operand" "=a")
18229         (unspec:HI
18230           [(match_operand:X87MODEF 1 "register_operand" "f")]
18231           UNSPEC_FXAM))]
18232   "TARGET_USE_FANCY_MATH_387"
18233   "fxam\n\tfnstsw\t%0"
18234   [(set_attr "type" "multi")
18235    (set_attr "unit" "i387")
18236    (set_attr "mode" "<MODE>")])
18237
18238 (define_expand "isinf<mode>2"
18239   [(use (match_operand:SI 0 "register_operand" ""))
18240    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18241   "TARGET_USE_FANCY_MATH_387
18242   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18243       || TARGET_MIX_SSE_I387)"
18244 {
18245   rtx mask = GEN_INT (0x45);
18246   rtx val = GEN_INT (0x05);
18247
18248   rtx cond;
18249
18250   rtx scratch = gen_reg_rtx (HImode);
18251   rtx res = gen_reg_rtx (QImode);
18252
18253   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18254   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18255   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18256   cond = gen_rtx_fmt_ee (EQ, QImode,
18257                          gen_rtx_REG (CCmode, FLAGS_REG),
18258                          const0_rtx);
18259   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18260   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18261   DONE;
18262 })
18263
18264 \f
18265 ;; Block operation instructions
18266
18267 (define_expand "movmemsi"
18268   [(use (match_operand:BLK 0 "memory_operand" ""))
18269    (use (match_operand:BLK 1 "memory_operand" ""))
18270    (use (match_operand:SI 2 "nonmemory_operand" ""))
18271    (use (match_operand:SI 3 "const_int_operand" ""))
18272    (use (match_operand:SI 4 "const_int_operand" ""))
18273    (use (match_operand:SI 5 "const_int_operand" ""))]
18274   ""
18275 {
18276  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18277                          operands[4], operands[5]))
18278    DONE;
18279  else
18280    FAIL;
18281 })
18282
18283 (define_expand "movmemdi"
18284   [(use (match_operand:BLK 0 "memory_operand" ""))
18285    (use (match_operand:BLK 1 "memory_operand" ""))
18286    (use (match_operand:DI 2 "nonmemory_operand" ""))
18287    (use (match_operand:DI 3 "const_int_operand" ""))
18288    (use (match_operand:SI 4 "const_int_operand" ""))
18289    (use (match_operand:SI 5 "const_int_operand" ""))]
18290   "TARGET_64BIT"
18291 {
18292  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18293                          operands[4], operands[5]))
18294    DONE;
18295  else
18296    FAIL;
18297 })
18298
18299 ;; Most CPUs don't like single string operations
18300 ;; Handle this case here to simplify previous expander.
18301
18302 (define_expand "strmov"
18303   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18304    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18305    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18306               (clobber (reg:CC FLAGS_REG))])
18307    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18308               (clobber (reg:CC FLAGS_REG))])]
18309   ""
18310 {
18311   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18312
18313   /* If .md ever supports :P for Pmode, these can be directly
18314      in the pattern above.  */
18315   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18316   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18317
18318   if (TARGET_SINGLE_STRINGOP || optimize_size)
18319     {
18320       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18321                                       operands[2], operands[3],
18322                                       operands[5], operands[6]));
18323       DONE;
18324     }
18325
18326   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18327 })
18328
18329 (define_expand "strmov_singleop"
18330   [(parallel [(set (match_operand 1 "memory_operand" "")
18331                    (match_operand 3 "memory_operand" ""))
18332               (set (match_operand 0 "register_operand" "")
18333                    (match_operand 4 "" ""))
18334               (set (match_operand 2 "register_operand" "")
18335                    (match_operand 5 "" ""))])]
18336   "TARGET_SINGLE_STRINGOP || optimize_size"
18337   "")
18338
18339 (define_insn "*strmovdi_rex_1"
18340   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18341         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18342    (set (match_operand:DI 0 "register_operand" "=D")
18343         (plus:DI (match_dup 2)
18344                  (const_int 8)))
18345    (set (match_operand:DI 1 "register_operand" "=S")
18346         (plus:DI (match_dup 3)
18347                  (const_int 8)))]
18348   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18349   "movsq"
18350   [(set_attr "type" "str")
18351    (set_attr "mode" "DI")
18352    (set_attr "memory" "both")])
18353
18354 (define_insn "*strmovsi_1"
18355   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18356         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18357    (set (match_operand:SI 0 "register_operand" "=D")
18358         (plus:SI (match_dup 2)
18359                  (const_int 4)))
18360    (set (match_operand:SI 1 "register_operand" "=S")
18361         (plus:SI (match_dup 3)
18362                  (const_int 4)))]
18363   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18364   "{movsl|movsd}"
18365   [(set_attr "type" "str")
18366    (set_attr "mode" "SI")
18367    (set_attr "memory" "both")])
18368
18369 (define_insn "*strmovsi_rex_1"
18370   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18371         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18372    (set (match_operand:DI 0 "register_operand" "=D")
18373         (plus:DI (match_dup 2)
18374                  (const_int 4)))
18375    (set (match_operand:DI 1 "register_operand" "=S")
18376         (plus:DI (match_dup 3)
18377                  (const_int 4)))]
18378   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18379   "{movsl|movsd}"
18380   [(set_attr "type" "str")
18381    (set_attr "mode" "SI")
18382    (set_attr "memory" "both")])
18383
18384 (define_insn "*strmovhi_1"
18385   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18386         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18387    (set (match_operand:SI 0 "register_operand" "=D")
18388         (plus:SI (match_dup 2)
18389                  (const_int 2)))
18390    (set (match_operand:SI 1 "register_operand" "=S")
18391         (plus:SI (match_dup 3)
18392                  (const_int 2)))]
18393   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18394   "movsw"
18395   [(set_attr "type" "str")
18396    (set_attr "memory" "both")
18397    (set_attr "mode" "HI")])
18398
18399 (define_insn "*strmovhi_rex_1"
18400   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18401         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18402    (set (match_operand:DI 0 "register_operand" "=D")
18403         (plus:DI (match_dup 2)
18404                  (const_int 2)))
18405    (set (match_operand:DI 1 "register_operand" "=S")
18406         (plus:DI (match_dup 3)
18407                  (const_int 2)))]
18408   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18409   "movsw"
18410   [(set_attr "type" "str")
18411    (set_attr "memory" "both")
18412    (set_attr "mode" "HI")])
18413
18414 (define_insn "*strmovqi_1"
18415   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18416         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18417    (set (match_operand:SI 0 "register_operand" "=D")
18418         (plus:SI (match_dup 2)
18419                  (const_int 1)))
18420    (set (match_operand:SI 1 "register_operand" "=S")
18421         (plus:SI (match_dup 3)
18422                  (const_int 1)))]
18423   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18424   "movsb"
18425   [(set_attr "type" "str")
18426    (set_attr "memory" "both")
18427    (set_attr "mode" "QI")])
18428
18429 (define_insn "*strmovqi_rex_1"
18430   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18431         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18432    (set (match_operand:DI 0 "register_operand" "=D")
18433         (plus:DI (match_dup 2)
18434                  (const_int 1)))
18435    (set (match_operand:DI 1 "register_operand" "=S")
18436         (plus:DI (match_dup 3)
18437                  (const_int 1)))]
18438   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18439   "movsb"
18440   [(set_attr "type" "str")
18441    (set_attr "memory" "both")
18442    (set_attr "mode" "QI")])
18443
18444 (define_expand "rep_mov"
18445   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18446               (set (match_operand 0 "register_operand" "")
18447                    (match_operand 5 "" ""))
18448               (set (match_operand 2 "register_operand" "")
18449                    (match_operand 6 "" ""))
18450               (set (match_operand 1 "memory_operand" "")
18451                    (match_operand 3 "memory_operand" ""))
18452               (use (match_dup 4))])]
18453   ""
18454   "")
18455
18456 (define_insn "*rep_movdi_rex64"
18457   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18458    (set (match_operand:DI 0 "register_operand" "=D")
18459         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18460                             (const_int 3))
18461                  (match_operand:DI 3 "register_operand" "0")))
18462    (set (match_operand:DI 1 "register_operand" "=S")
18463         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18464                  (match_operand:DI 4 "register_operand" "1")))
18465    (set (mem:BLK (match_dup 3))
18466         (mem:BLK (match_dup 4)))
18467    (use (match_dup 5))]
18468   "TARGET_64BIT"
18469   "{rep\;movsq|rep movsq}"
18470   [(set_attr "type" "str")
18471    (set_attr "prefix_rep" "1")
18472    (set_attr "memory" "both")
18473    (set_attr "mode" "DI")])
18474
18475 (define_insn "*rep_movsi"
18476   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18477    (set (match_operand:SI 0 "register_operand" "=D")
18478         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18479                             (const_int 2))
18480                  (match_operand:SI 3 "register_operand" "0")))
18481    (set (match_operand:SI 1 "register_operand" "=S")
18482         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18483                  (match_operand:SI 4 "register_operand" "1")))
18484    (set (mem:BLK (match_dup 3))
18485         (mem:BLK (match_dup 4)))
18486    (use (match_dup 5))]
18487   "!TARGET_64BIT"
18488   "{rep\;movsl|rep movsd}"
18489   [(set_attr "type" "str")
18490    (set_attr "prefix_rep" "1")
18491    (set_attr "memory" "both")
18492    (set_attr "mode" "SI")])
18493
18494 (define_insn "*rep_movsi_rex64"
18495   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18496    (set (match_operand:DI 0 "register_operand" "=D")
18497         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18498                             (const_int 2))
18499                  (match_operand:DI 3 "register_operand" "0")))
18500    (set (match_operand:DI 1 "register_operand" "=S")
18501         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18502                  (match_operand:DI 4 "register_operand" "1")))
18503    (set (mem:BLK (match_dup 3))
18504         (mem:BLK (match_dup 4)))
18505    (use (match_dup 5))]
18506   "TARGET_64BIT"
18507   "{rep\;movsl|rep movsd}"
18508   [(set_attr "type" "str")
18509    (set_attr "prefix_rep" "1")
18510    (set_attr "memory" "both")
18511    (set_attr "mode" "SI")])
18512
18513 (define_insn "*rep_movqi"
18514   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18515    (set (match_operand:SI 0 "register_operand" "=D")
18516         (plus:SI (match_operand:SI 3 "register_operand" "0")
18517                  (match_operand:SI 5 "register_operand" "2")))
18518    (set (match_operand:SI 1 "register_operand" "=S")
18519         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18520    (set (mem:BLK (match_dup 3))
18521         (mem:BLK (match_dup 4)))
18522    (use (match_dup 5))]
18523   "!TARGET_64BIT"
18524   "{rep\;movsb|rep movsb}"
18525   [(set_attr "type" "str")
18526    (set_attr "prefix_rep" "1")
18527    (set_attr "memory" "both")
18528    (set_attr "mode" "SI")])
18529
18530 (define_insn "*rep_movqi_rex64"
18531   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18532    (set (match_operand:DI 0 "register_operand" "=D")
18533         (plus:DI (match_operand:DI 3 "register_operand" "0")
18534                  (match_operand:DI 5 "register_operand" "2")))
18535    (set (match_operand:DI 1 "register_operand" "=S")
18536         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18537    (set (mem:BLK (match_dup 3))
18538         (mem:BLK (match_dup 4)))
18539    (use (match_dup 5))]
18540   "TARGET_64BIT"
18541   "{rep\;movsb|rep movsb}"
18542   [(set_attr "type" "str")
18543    (set_attr "prefix_rep" "1")
18544    (set_attr "memory" "both")
18545    (set_attr "mode" "SI")])
18546
18547 (define_expand "setmemsi"
18548    [(use (match_operand:BLK 0 "memory_operand" ""))
18549     (use (match_operand:SI 1 "nonmemory_operand" ""))
18550     (use (match_operand 2 "const_int_operand" ""))
18551     (use (match_operand 3 "const_int_operand" ""))
18552     (use (match_operand:SI 4 "const_int_operand" ""))
18553     (use (match_operand:SI 5 "const_int_operand" ""))]
18554   ""
18555 {
18556  if (ix86_expand_setmem (operands[0], operands[1],
18557                          operands[2], operands[3],
18558                          operands[4], operands[5]))
18559    DONE;
18560  else
18561    FAIL;
18562 })
18563
18564 (define_expand "setmemdi"
18565    [(use (match_operand:BLK 0 "memory_operand" ""))
18566     (use (match_operand:DI 1 "nonmemory_operand" ""))
18567     (use (match_operand 2 "const_int_operand" ""))
18568     (use (match_operand 3 "const_int_operand" ""))
18569     (use (match_operand 4 "const_int_operand" ""))
18570     (use (match_operand 5 "const_int_operand" ""))]
18571   "TARGET_64BIT"
18572 {
18573  if (ix86_expand_setmem (operands[0], operands[1],
18574                          operands[2], operands[3],
18575                          operands[4], operands[5]))
18576    DONE;
18577  else
18578    FAIL;
18579 })
18580
18581 ;; Most CPUs don't like single string operations
18582 ;; Handle this case here to simplify previous expander.
18583
18584 (define_expand "strset"
18585   [(set (match_operand 1 "memory_operand" "")
18586         (match_operand 2 "register_operand" ""))
18587    (parallel [(set (match_operand 0 "register_operand" "")
18588                    (match_dup 3))
18589               (clobber (reg:CC FLAGS_REG))])]
18590   ""
18591 {
18592   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18593     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18594
18595   /* If .md ever supports :P for Pmode, this can be directly
18596      in the pattern above.  */
18597   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18598                               GEN_INT (GET_MODE_SIZE (GET_MODE
18599                                                       (operands[2]))));
18600   if (TARGET_SINGLE_STRINGOP || optimize_size)
18601     {
18602       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18603                                       operands[3]));
18604       DONE;
18605     }
18606 })
18607
18608 (define_expand "strset_singleop"
18609   [(parallel [(set (match_operand 1 "memory_operand" "")
18610                    (match_operand 2 "register_operand" ""))
18611               (set (match_operand 0 "register_operand" "")
18612                    (match_operand 3 "" ""))])]
18613   "TARGET_SINGLE_STRINGOP || optimize_size"
18614   "")
18615
18616 (define_insn "*strsetdi_rex_1"
18617   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18618         (match_operand:DI 2 "register_operand" "a"))
18619    (set (match_operand:DI 0 "register_operand" "=D")
18620         (plus:DI (match_dup 1)
18621                  (const_int 8)))]
18622   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18623   "stosq"
18624   [(set_attr "type" "str")
18625    (set_attr "memory" "store")
18626    (set_attr "mode" "DI")])
18627
18628 (define_insn "*strsetsi_1"
18629   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18630         (match_operand:SI 2 "register_operand" "a"))
18631    (set (match_operand:SI 0 "register_operand" "=D")
18632         (plus:SI (match_dup 1)
18633                  (const_int 4)))]
18634   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18635   "{stosl|stosd}"
18636   [(set_attr "type" "str")
18637    (set_attr "memory" "store")
18638    (set_attr "mode" "SI")])
18639
18640 (define_insn "*strsetsi_rex_1"
18641   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18642         (match_operand:SI 2 "register_operand" "a"))
18643    (set (match_operand:DI 0 "register_operand" "=D")
18644         (plus:DI (match_dup 1)
18645                  (const_int 4)))]
18646   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18647   "{stosl|stosd}"
18648   [(set_attr "type" "str")
18649    (set_attr "memory" "store")
18650    (set_attr "mode" "SI")])
18651
18652 (define_insn "*strsethi_1"
18653   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18654         (match_operand:HI 2 "register_operand" "a"))
18655    (set (match_operand:SI 0 "register_operand" "=D")
18656         (plus:SI (match_dup 1)
18657                  (const_int 2)))]
18658   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18659   "stosw"
18660   [(set_attr "type" "str")
18661    (set_attr "memory" "store")
18662    (set_attr "mode" "HI")])
18663
18664 (define_insn "*strsethi_rex_1"
18665   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18666         (match_operand:HI 2 "register_operand" "a"))
18667    (set (match_operand:DI 0 "register_operand" "=D")
18668         (plus:DI (match_dup 1)
18669                  (const_int 2)))]
18670   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18671   "stosw"
18672   [(set_attr "type" "str")
18673    (set_attr "memory" "store")
18674    (set_attr "mode" "HI")])
18675
18676 (define_insn "*strsetqi_1"
18677   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18678         (match_operand:QI 2 "register_operand" "a"))
18679    (set (match_operand:SI 0 "register_operand" "=D")
18680         (plus:SI (match_dup 1)
18681                  (const_int 1)))]
18682   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18683   "stosb"
18684   [(set_attr "type" "str")
18685    (set_attr "memory" "store")
18686    (set_attr "mode" "QI")])
18687
18688 (define_insn "*strsetqi_rex_1"
18689   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18690         (match_operand:QI 2 "register_operand" "a"))
18691    (set (match_operand:DI 0 "register_operand" "=D")
18692         (plus:DI (match_dup 1)
18693                  (const_int 1)))]
18694   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18695   "stosb"
18696   [(set_attr "type" "str")
18697    (set_attr "memory" "store")
18698    (set_attr "mode" "QI")])
18699
18700 (define_expand "rep_stos"
18701   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18702               (set (match_operand 0 "register_operand" "")
18703                    (match_operand 4 "" ""))
18704               (set (match_operand 2 "memory_operand" "") (const_int 0))
18705               (use (match_operand 3 "register_operand" ""))
18706               (use (match_dup 1))])]
18707   ""
18708   "")
18709
18710 (define_insn "*rep_stosdi_rex64"
18711   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18712    (set (match_operand:DI 0 "register_operand" "=D")
18713         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18714                             (const_int 3))
18715                  (match_operand:DI 3 "register_operand" "0")))
18716    (set (mem:BLK (match_dup 3))
18717         (const_int 0))
18718    (use (match_operand:DI 2 "register_operand" "a"))
18719    (use (match_dup 4))]
18720   "TARGET_64BIT"
18721   "{rep\;stosq|rep stosq}"
18722   [(set_attr "type" "str")
18723    (set_attr "prefix_rep" "1")
18724    (set_attr "memory" "store")
18725    (set_attr "mode" "DI")])
18726
18727 (define_insn "*rep_stossi"
18728   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18729    (set (match_operand:SI 0 "register_operand" "=D")
18730         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18731                             (const_int 2))
18732                  (match_operand:SI 3 "register_operand" "0")))
18733    (set (mem:BLK (match_dup 3))
18734         (const_int 0))
18735    (use (match_operand:SI 2 "register_operand" "a"))
18736    (use (match_dup 4))]
18737   "!TARGET_64BIT"
18738   "{rep\;stosl|rep stosd}"
18739   [(set_attr "type" "str")
18740    (set_attr "prefix_rep" "1")
18741    (set_attr "memory" "store")
18742    (set_attr "mode" "SI")])
18743
18744 (define_insn "*rep_stossi_rex64"
18745   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18746    (set (match_operand:DI 0 "register_operand" "=D")
18747         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18748                             (const_int 2))
18749                  (match_operand:DI 3 "register_operand" "0")))
18750    (set (mem:BLK (match_dup 3))
18751         (const_int 0))
18752    (use (match_operand:SI 2 "register_operand" "a"))
18753    (use (match_dup 4))]
18754   "TARGET_64BIT"
18755   "{rep\;stosl|rep stosd}"
18756   [(set_attr "type" "str")
18757    (set_attr "prefix_rep" "1")
18758    (set_attr "memory" "store")
18759    (set_attr "mode" "SI")])
18760
18761 (define_insn "*rep_stosqi"
18762   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18763    (set (match_operand:SI 0 "register_operand" "=D")
18764         (plus:SI (match_operand:SI 3 "register_operand" "0")
18765                  (match_operand:SI 4 "register_operand" "1")))
18766    (set (mem:BLK (match_dup 3))
18767         (const_int 0))
18768    (use (match_operand:QI 2 "register_operand" "a"))
18769    (use (match_dup 4))]
18770   "!TARGET_64BIT"
18771   "{rep\;stosb|rep stosb}"
18772   [(set_attr "type" "str")
18773    (set_attr "prefix_rep" "1")
18774    (set_attr "memory" "store")
18775    (set_attr "mode" "QI")])
18776
18777 (define_insn "*rep_stosqi_rex64"
18778   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18779    (set (match_operand:DI 0 "register_operand" "=D")
18780         (plus:DI (match_operand:DI 3 "register_operand" "0")
18781                  (match_operand:DI 4 "register_operand" "1")))
18782    (set (mem:BLK (match_dup 3))
18783         (const_int 0))
18784    (use (match_operand:QI 2 "register_operand" "a"))
18785    (use (match_dup 4))]
18786   "TARGET_64BIT"
18787   "{rep\;stosb|rep stosb}"
18788   [(set_attr "type" "str")
18789    (set_attr "prefix_rep" "1")
18790    (set_attr "memory" "store")
18791    (set_attr "mode" "QI")])
18792
18793 (define_expand "cmpstrnsi"
18794   [(set (match_operand:SI 0 "register_operand" "")
18795         (compare:SI (match_operand:BLK 1 "general_operand" "")
18796                     (match_operand:BLK 2 "general_operand" "")))
18797    (use (match_operand 3 "general_operand" ""))
18798    (use (match_operand 4 "immediate_operand" ""))]
18799   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18800 {
18801   rtx addr1, addr2, out, outlow, count, countreg, align;
18802
18803   /* Can't use this if the user has appropriated esi or edi.  */
18804   if (global_regs[4] || global_regs[5])
18805     FAIL;
18806
18807   out = operands[0];
18808   if (!REG_P (out))
18809     out = gen_reg_rtx (SImode);
18810
18811   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18812   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18813   if (addr1 != XEXP (operands[1], 0))
18814     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18815   if (addr2 != XEXP (operands[2], 0))
18816     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18817
18818   count = operands[3];
18819   countreg = ix86_zero_extend_to_Pmode (count);
18820
18821   /* %%% Iff we are testing strict equality, we can use known alignment
18822      to good advantage.  This may be possible with combine, particularly
18823      once cc0 is dead.  */
18824   align = operands[4];
18825
18826   if (CONST_INT_P (count))
18827     {
18828       if (INTVAL (count) == 0)
18829         {
18830           emit_move_insn (operands[0], const0_rtx);
18831           DONE;
18832         }
18833       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18834                                      operands[1], operands[2]));
18835     }
18836   else
18837     {
18838       if (TARGET_64BIT)
18839         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18840       else
18841         emit_insn (gen_cmpsi_1 (countreg, countreg));
18842       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18843                                   operands[1], operands[2]));
18844     }
18845
18846   outlow = gen_lowpart (QImode, out);
18847   emit_insn (gen_cmpintqi (outlow));
18848   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18849
18850   if (operands[0] != out)
18851     emit_move_insn (operands[0], out);
18852
18853   DONE;
18854 })
18855
18856 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18857
18858 (define_expand "cmpintqi"
18859   [(set (match_dup 1)
18860         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18861    (set (match_dup 2)
18862         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18863    (parallel [(set (match_operand:QI 0 "register_operand" "")
18864                    (minus:QI (match_dup 1)
18865                              (match_dup 2)))
18866               (clobber (reg:CC FLAGS_REG))])]
18867   ""
18868   "operands[1] = gen_reg_rtx (QImode);
18869    operands[2] = gen_reg_rtx (QImode);")
18870
18871 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18872 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18873
18874 (define_expand "cmpstrnqi_nz_1"
18875   [(parallel [(set (reg:CC FLAGS_REG)
18876                    (compare:CC (match_operand 4 "memory_operand" "")
18877                                (match_operand 5 "memory_operand" "")))
18878               (use (match_operand 2 "register_operand" ""))
18879               (use (match_operand:SI 3 "immediate_operand" ""))
18880               (clobber (match_operand 0 "register_operand" ""))
18881               (clobber (match_operand 1 "register_operand" ""))
18882               (clobber (match_dup 2))])]
18883   ""
18884   "")
18885
18886 (define_insn "*cmpstrnqi_nz_1"
18887   [(set (reg:CC FLAGS_REG)
18888         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18889                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18890    (use (match_operand:SI 6 "register_operand" "2"))
18891    (use (match_operand:SI 3 "immediate_operand" "i"))
18892    (clobber (match_operand:SI 0 "register_operand" "=S"))
18893    (clobber (match_operand:SI 1 "register_operand" "=D"))
18894    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18895   "!TARGET_64BIT"
18896   "repz{\;| }cmpsb"
18897   [(set_attr "type" "str")
18898    (set_attr "mode" "QI")
18899    (set_attr "prefix_rep" "1")])
18900
18901 (define_insn "*cmpstrnqi_nz_rex_1"
18902   [(set (reg:CC FLAGS_REG)
18903         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18904                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18905    (use (match_operand:DI 6 "register_operand" "2"))
18906    (use (match_operand:SI 3 "immediate_operand" "i"))
18907    (clobber (match_operand:DI 0 "register_operand" "=S"))
18908    (clobber (match_operand:DI 1 "register_operand" "=D"))
18909    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18910   "TARGET_64BIT"
18911   "repz{\;| }cmpsb"
18912   [(set_attr "type" "str")
18913    (set_attr "mode" "QI")
18914    (set_attr "prefix_rep" "1")])
18915
18916 ;; The same, but the count is not known to not be zero.
18917
18918 (define_expand "cmpstrnqi_1"
18919   [(parallel [(set (reg:CC FLAGS_REG)
18920                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18921                                      (const_int 0))
18922                   (compare:CC (match_operand 4 "memory_operand" "")
18923                               (match_operand 5 "memory_operand" ""))
18924                   (const_int 0)))
18925               (use (match_operand:SI 3 "immediate_operand" ""))
18926               (use (reg:CC FLAGS_REG))
18927               (clobber (match_operand 0 "register_operand" ""))
18928               (clobber (match_operand 1 "register_operand" ""))
18929               (clobber (match_dup 2))])]
18930   ""
18931   "")
18932
18933 (define_insn "*cmpstrnqi_1"
18934   [(set (reg:CC FLAGS_REG)
18935         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18936                              (const_int 0))
18937           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18938                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18939           (const_int 0)))
18940    (use (match_operand:SI 3 "immediate_operand" "i"))
18941    (use (reg:CC FLAGS_REG))
18942    (clobber (match_operand:SI 0 "register_operand" "=S"))
18943    (clobber (match_operand:SI 1 "register_operand" "=D"))
18944    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18945   "!TARGET_64BIT"
18946   "repz{\;| }cmpsb"
18947   [(set_attr "type" "str")
18948    (set_attr "mode" "QI")
18949    (set_attr "prefix_rep" "1")])
18950
18951 (define_insn "*cmpstrnqi_rex_1"
18952   [(set (reg:CC FLAGS_REG)
18953         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18954                              (const_int 0))
18955           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18956                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18957           (const_int 0)))
18958    (use (match_operand:SI 3 "immediate_operand" "i"))
18959    (use (reg:CC FLAGS_REG))
18960    (clobber (match_operand:DI 0 "register_operand" "=S"))
18961    (clobber (match_operand:DI 1 "register_operand" "=D"))
18962    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18963   "TARGET_64BIT"
18964   "repz{\;| }cmpsb"
18965   [(set_attr "type" "str")
18966    (set_attr "mode" "QI")
18967    (set_attr "prefix_rep" "1")])
18968
18969 (define_expand "strlensi"
18970   [(set (match_operand:SI 0 "register_operand" "")
18971         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18972                     (match_operand:QI 2 "immediate_operand" "")
18973                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18974   ""
18975 {
18976  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18977    DONE;
18978  else
18979    FAIL;
18980 })
18981
18982 (define_expand "strlendi"
18983   [(set (match_operand:DI 0 "register_operand" "")
18984         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18985                     (match_operand:QI 2 "immediate_operand" "")
18986                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18987   ""
18988 {
18989  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18990    DONE;
18991  else
18992    FAIL;
18993 })
18994
18995 (define_expand "strlenqi_1"
18996   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18997               (clobber (match_operand 1 "register_operand" ""))
18998               (clobber (reg:CC FLAGS_REG))])]
18999   ""
19000   "")
19001
19002 (define_insn "*strlenqi_1"
19003   [(set (match_operand:SI 0 "register_operand" "=&c")
19004         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19005                     (match_operand:QI 2 "register_operand" "a")
19006                     (match_operand:SI 3 "immediate_operand" "i")
19007                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19008    (clobber (match_operand:SI 1 "register_operand" "=D"))
19009    (clobber (reg:CC FLAGS_REG))]
19010   "!TARGET_64BIT"
19011   "repnz{\;| }scasb"
19012   [(set_attr "type" "str")
19013    (set_attr "mode" "QI")
19014    (set_attr "prefix_rep" "1")])
19015
19016 (define_insn "*strlenqi_rex_1"
19017   [(set (match_operand:DI 0 "register_operand" "=&c")
19018         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19019                     (match_operand:QI 2 "register_operand" "a")
19020                     (match_operand:DI 3 "immediate_operand" "i")
19021                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19022    (clobber (match_operand:DI 1 "register_operand" "=D"))
19023    (clobber (reg:CC FLAGS_REG))]
19024   "TARGET_64BIT"
19025   "repnz{\;| }scasb"
19026   [(set_attr "type" "str")
19027    (set_attr "mode" "QI")
19028    (set_attr "prefix_rep" "1")])
19029
19030 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19031 ;; handled in combine, but it is not currently up to the task.
19032 ;; When used for their truth value, the cmpstrn* expanders generate
19033 ;; code like this:
19034 ;;
19035 ;;   repz cmpsb
19036 ;;   seta       %al
19037 ;;   setb       %dl
19038 ;;   cmpb       %al, %dl
19039 ;;   jcc        label
19040 ;;
19041 ;; The intermediate three instructions are unnecessary.
19042
19043 ;; This one handles cmpstrn*_nz_1...
19044 (define_peephole2
19045   [(parallel[
19046      (set (reg:CC FLAGS_REG)
19047           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19048                       (mem:BLK (match_operand 5 "register_operand" ""))))
19049      (use (match_operand 6 "register_operand" ""))
19050      (use (match_operand:SI 3 "immediate_operand" ""))
19051      (clobber (match_operand 0 "register_operand" ""))
19052      (clobber (match_operand 1 "register_operand" ""))
19053      (clobber (match_operand 2 "register_operand" ""))])
19054    (set (match_operand:QI 7 "register_operand" "")
19055         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19056    (set (match_operand:QI 8 "register_operand" "")
19057         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19058    (set (reg FLAGS_REG)
19059         (compare (match_dup 7) (match_dup 8)))
19060   ]
19061   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19062   [(parallel[
19063      (set (reg:CC FLAGS_REG)
19064           (compare:CC (mem:BLK (match_dup 4))
19065                       (mem:BLK (match_dup 5))))
19066      (use (match_dup 6))
19067      (use (match_dup 3))
19068      (clobber (match_dup 0))
19069      (clobber (match_dup 1))
19070      (clobber (match_dup 2))])]
19071   "")
19072
19073 ;; ...and this one handles cmpstrn*_1.
19074 (define_peephole2
19075   [(parallel[
19076      (set (reg:CC FLAGS_REG)
19077           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19078                                (const_int 0))
19079             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19080                         (mem:BLK (match_operand 5 "register_operand" "")))
19081             (const_int 0)))
19082      (use (match_operand:SI 3 "immediate_operand" ""))
19083      (use (reg:CC FLAGS_REG))
19084      (clobber (match_operand 0 "register_operand" ""))
19085      (clobber (match_operand 1 "register_operand" ""))
19086      (clobber (match_operand 2 "register_operand" ""))])
19087    (set (match_operand:QI 7 "register_operand" "")
19088         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19089    (set (match_operand:QI 8 "register_operand" "")
19090         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19091    (set (reg FLAGS_REG)
19092         (compare (match_dup 7) (match_dup 8)))
19093   ]
19094   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19095   [(parallel[
19096      (set (reg:CC FLAGS_REG)
19097           (if_then_else:CC (ne (match_dup 6)
19098                                (const_int 0))
19099             (compare:CC (mem:BLK (match_dup 4))
19100                         (mem:BLK (match_dup 5)))
19101             (const_int 0)))
19102      (use (match_dup 3))
19103      (use (reg:CC FLAGS_REG))
19104      (clobber (match_dup 0))
19105      (clobber (match_dup 1))
19106      (clobber (match_dup 2))])]
19107   "")
19108
19109
19110 \f
19111 ;; Conditional move instructions.
19112
19113 (define_expand "movdicc"
19114   [(set (match_operand:DI 0 "register_operand" "")
19115         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19116                          (match_operand:DI 2 "general_operand" "")
19117                          (match_operand:DI 3 "general_operand" "")))]
19118   "TARGET_64BIT"
19119   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19120
19121 (define_insn "x86_movdicc_0_m1_rex64"
19122   [(set (match_operand:DI 0 "register_operand" "=r")
19123         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19124           (const_int -1)
19125           (const_int 0)))
19126    (clobber (reg:CC FLAGS_REG))]
19127   "TARGET_64BIT"
19128   "sbb{q}\t%0, %0"
19129   ; Since we don't have the proper number of operands for an alu insn,
19130   ; fill in all the blanks.
19131   [(set_attr "type" "alu")
19132    (set_attr "pent_pair" "pu")
19133    (set_attr "memory" "none")
19134    (set_attr "imm_disp" "false")
19135    (set_attr "mode" "DI")
19136    (set_attr "length_immediate" "0")])
19137
19138 (define_insn "*movdicc_c_rex64"
19139   [(set (match_operand:DI 0 "register_operand" "=r,r")
19140         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19141                                 [(reg FLAGS_REG) (const_int 0)])
19142                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19143                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19144   "TARGET_64BIT && TARGET_CMOVE
19145    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19146   "@
19147    cmov%O2%C1\t{%2, %0|%0, %2}
19148    cmov%O2%c1\t{%3, %0|%0, %3}"
19149   [(set_attr "type" "icmov")
19150    (set_attr "mode" "DI")])
19151
19152 (define_expand "movsicc"
19153   [(set (match_operand:SI 0 "register_operand" "")
19154         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19155                          (match_operand:SI 2 "general_operand" "")
19156                          (match_operand:SI 3 "general_operand" "")))]
19157   ""
19158   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19159
19160 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19161 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19162 ;; So just document what we're doing explicitly.
19163
19164 (define_insn "x86_movsicc_0_m1"
19165   [(set (match_operand:SI 0 "register_operand" "=r")
19166         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19167           (const_int -1)
19168           (const_int 0)))
19169    (clobber (reg:CC FLAGS_REG))]
19170   ""
19171   "sbb{l}\t%0, %0"
19172   ; Since we don't have the proper number of operands for an alu insn,
19173   ; fill in all the blanks.
19174   [(set_attr "type" "alu")
19175    (set_attr "pent_pair" "pu")
19176    (set_attr "memory" "none")
19177    (set_attr "imm_disp" "false")
19178    (set_attr "mode" "SI")
19179    (set_attr "length_immediate" "0")])
19180
19181 (define_insn "*movsicc_noc"
19182   [(set (match_operand:SI 0 "register_operand" "=r,r")
19183         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19184                                 [(reg FLAGS_REG) (const_int 0)])
19185                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19186                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19187   "TARGET_CMOVE
19188    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19189   "@
19190    cmov%O2%C1\t{%2, %0|%0, %2}
19191    cmov%O2%c1\t{%3, %0|%0, %3}"
19192   [(set_attr "type" "icmov")
19193    (set_attr "mode" "SI")])
19194
19195 (define_expand "movhicc"
19196   [(set (match_operand:HI 0 "register_operand" "")
19197         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19198                          (match_operand:HI 2 "general_operand" "")
19199                          (match_operand:HI 3 "general_operand" "")))]
19200   "TARGET_HIMODE_MATH"
19201   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19202
19203 (define_insn "*movhicc_noc"
19204   [(set (match_operand:HI 0 "register_operand" "=r,r")
19205         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19206                                 [(reg FLAGS_REG) (const_int 0)])
19207                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19208                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19209   "TARGET_CMOVE
19210    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19211   "@
19212    cmov%O2%C1\t{%2, %0|%0, %2}
19213    cmov%O2%c1\t{%3, %0|%0, %3}"
19214   [(set_attr "type" "icmov")
19215    (set_attr "mode" "HI")])
19216
19217 (define_expand "movqicc"
19218   [(set (match_operand:QI 0 "register_operand" "")
19219         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19220                          (match_operand:QI 2 "general_operand" "")
19221                          (match_operand:QI 3 "general_operand" "")))]
19222   "TARGET_QIMODE_MATH"
19223   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19224
19225 (define_insn_and_split "*movqicc_noc"
19226   [(set (match_operand:QI 0 "register_operand" "=r,r")
19227         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19228                                 [(match_operand 4 "flags_reg_operand" "")
19229                                  (const_int 0)])
19230                       (match_operand:QI 2 "register_operand" "r,0")
19231                       (match_operand:QI 3 "register_operand" "0,r")))]
19232   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19233   "#"
19234   "&& reload_completed"
19235   [(set (match_dup 0)
19236         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19237                       (match_dup 2)
19238                       (match_dup 3)))]
19239   "operands[0] = gen_lowpart (SImode, operands[0]);
19240    operands[2] = gen_lowpart (SImode, operands[2]);
19241    operands[3] = gen_lowpart (SImode, operands[3]);"
19242   [(set_attr "type" "icmov")
19243    (set_attr "mode" "SI")])
19244
19245 (define_expand "movsfcc"
19246   [(set (match_operand:SF 0 "register_operand" "")
19247         (if_then_else:SF (match_operand 1 "comparison_operator" "")
19248                          (match_operand:SF 2 "register_operand" "")
19249                          (match_operand:SF 3 "register_operand" "")))]
19250   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19251   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19252
19253 (define_insn "*movsfcc_1_387"
19254   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19255         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19256                                 [(reg FLAGS_REG) (const_int 0)])
19257                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19258                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19259   "TARGET_80387 && TARGET_CMOVE
19260    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19261   "@
19262    fcmov%F1\t{%2, %0|%0, %2}
19263    fcmov%f1\t{%3, %0|%0, %3}
19264    cmov%O2%C1\t{%2, %0|%0, %2}
19265    cmov%O2%c1\t{%3, %0|%0, %3}"
19266   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19267    (set_attr "mode" "SF,SF,SI,SI")])
19268
19269 (define_expand "movdfcc"
19270   [(set (match_operand:DF 0 "register_operand" "")
19271         (if_then_else:DF (match_operand 1 "comparison_operator" "")
19272                          (match_operand:DF 2 "register_operand" "")
19273                          (match_operand:DF 3 "register_operand" "")))]
19274   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19275   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19276
19277 (define_insn "*movdfcc_1"
19278   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19279         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19280                                 [(reg FLAGS_REG) (const_int 0)])
19281                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19282                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19283   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19284    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19285   "@
19286    fcmov%F1\t{%2, %0|%0, %2}
19287    fcmov%f1\t{%3, %0|%0, %3}
19288    #
19289    #"
19290   [(set_attr "type" "fcmov,fcmov,multi,multi")
19291    (set_attr "mode" "DF")])
19292
19293 (define_insn "*movdfcc_1_rex64"
19294   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19295         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19296                                 [(reg FLAGS_REG) (const_int 0)])
19297                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19298                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19299   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19300    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19301   "@
19302    fcmov%F1\t{%2, %0|%0, %2}
19303    fcmov%f1\t{%3, %0|%0, %3}
19304    cmov%O2%C1\t{%2, %0|%0, %2}
19305    cmov%O2%c1\t{%3, %0|%0, %3}"
19306   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19307    (set_attr "mode" "DF")])
19308
19309 (define_split
19310   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19311         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19312                                 [(match_operand 4 "flags_reg_operand" "")
19313                                  (const_int 0)])
19314                       (match_operand:DF 2 "nonimmediate_operand" "")
19315                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19316   "!TARGET_64BIT && reload_completed"
19317   [(set (match_dup 2)
19318         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19319                       (match_dup 5)
19320                       (match_dup 7)))
19321    (set (match_dup 3)
19322         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19323                       (match_dup 6)
19324                       (match_dup 8)))]
19325   "split_di (operands+2, 1, operands+5, operands+6);
19326    split_di (operands+3, 1, operands+7, operands+8);
19327    split_di (operands, 1, operands+2, operands+3);")
19328
19329 (define_expand "movxfcc"
19330   [(set (match_operand:XF 0 "register_operand" "")
19331         (if_then_else:XF (match_operand 1 "comparison_operator" "")
19332                          (match_operand:XF 2 "register_operand" "")
19333                          (match_operand:XF 3 "register_operand" "")))]
19334   "TARGET_80387 && TARGET_CMOVE"
19335   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19336
19337 (define_insn "*movxfcc_1"
19338   [(set (match_operand:XF 0 "register_operand" "=f,f")
19339         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19340                                 [(reg FLAGS_REG) (const_int 0)])
19341                       (match_operand:XF 2 "register_operand" "f,0")
19342                       (match_operand:XF 3 "register_operand" "0,f")))]
19343   "TARGET_80387 && TARGET_CMOVE"
19344   "@
19345    fcmov%F1\t{%2, %0|%0, %2}
19346    fcmov%f1\t{%3, %0|%0, %3}"
19347   [(set_attr "type" "fcmov")
19348    (set_attr "mode" "XF")])
19349
19350 ;; These versions of the min/max patterns are intentionally ignorant of
19351 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19352 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19353 ;; are undefined in this condition, we're certain this is correct.
19354
19355 (define_insn "sminsf3"
19356   [(set (match_operand:SF 0 "register_operand" "=x")
19357         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19358                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19359   "TARGET_SSE_MATH"
19360   "minss\t{%2, %0|%0, %2}"
19361   [(set_attr "type" "sseadd")
19362    (set_attr "mode" "SF")])
19363
19364 (define_insn "smaxsf3"
19365   [(set (match_operand:SF 0 "register_operand" "=x")
19366         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19367                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19368   "TARGET_SSE_MATH"
19369   "maxss\t{%2, %0|%0, %2}"
19370   [(set_attr "type" "sseadd")
19371    (set_attr "mode" "SF")])
19372
19373 (define_insn "smindf3"
19374   [(set (match_operand:DF 0 "register_operand" "=x")
19375         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19376                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19377   "TARGET_SSE2 && TARGET_SSE_MATH"
19378   "minsd\t{%2, %0|%0, %2}"
19379   [(set_attr "type" "sseadd")
19380    (set_attr "mode" "DF")])
19381
19382 (define_insn "smaxdf3"
19383   [(set (match_operand:DF 0 "register_operand" "=x")
19384         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19385                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19386   "TARGET_SSE2 && TARGET_SSE_MATH"
19387   "maxsd\t{%2, %0|%0, %2}"
19388   [(set_attr "type" "sseadd")
19389    (set_attr "mode" "DF")])
19390
19391 ;; These versions of the min/max patterns implement exactly the operations
19392 ;;   min = (op1 < op2 ? op1 : op2)
19393 ;;   max = (!(op1 < op2) ? op1 : op2)
19394 ;; Their operands are not commutative, and thus they may be used in the
19395 ;; presence of -0.0 and NaN.
19396
19397 (define_insn "*ieee_sminsf3"
19398   [(set (match_operand:SF 0 "register_operand" "=x")
19399         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19400                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19401                    UNSPEC_IEEE_MIN))]
19402   "TARGET_SSE_MATH"
19403   "minss\t{%2, %0|%0, %2}"
19404   [(set_attr "type" "sseadd")
19405    (set_attr "mode" "SF")])
19406
19407 (define_insn "*ieee_smaxsf3"
19408   [(set (match_operand:SF 0 "register_operand" "=x")
19409         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19410                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19411                    UNSPEC_IEEE_MAX))]
19412   "TARGET_SSE_MATH"
19413   "maxss\t{%2, %0|%0, %2}"
19414   [(set_attr "type" "sseadd")
19415    (set_attr "mode" "SF")])
19416
19417 (define_insn "*ieee_smindf3"
19418   [(set (match_operand:DF 0 "register_operand" "=x")
19419         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19420                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19421                    UNSPEC_IEEE_MIN))]
19422   "TARGET_SSE2 && TARGET_SSE_MATH"
19423   "minsd\t{%2, %0|%0, %2}"
19424   [(set_attr "type" "sseadd")
19425    (set_attr "mode" "DF")])
19426
19427 (define_insn "*ieee_smaxdf3"
19428   [(set (match_operand:DF 0 "register_operand" "=x")
19429         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19430                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19431                    UNSPEC_IEEE_MAX))]
19432   "TARGET_SSE2 && TARGET_SSE_MATH"
19433   "maxsd\t{%2, %0|%0, %2}"
19434   [(set_attr "type" "sseadd")
19435    (set_attr "mode" "DF")])
19436
19437 ;; Make two stack loads independent:
19438 ;;   fld aa              fld aa
19439 ;;   fld %st(0)     ->   fld bb
19440 ;;   fmul bb             fmul %st(1), %st
19441 ;;
19442 ;; Actually we only match the last two instructions for simplicity.
19443 (define_peephole2
19444   [(set (match_operand 0 "fp_register_operand" "")
19445         (match_operand 1 "fp_register_operand" ""))
19446    (set (match_dup 0)
19447         (match_operator 2 "binary_fp_operator"
19448            [(match_dup 0)
19449             (match_operand 3 "memory_operand" "")]))]
19450   "REGNO (operands[0]) != REGNO (operands[1])"
19451   [(set (match_dup 0) (match_dup 3))
19452    (set (match_dup 0) (match_dup 4))]
19453
19454   ;; The % modifier is not operational anymore in peephole2's, so we have to
19455   ;; swap the operands manually in the case of addition and multiplication.
19456   "if (COMMUTATIVE_ARITH_P (operands[2]))
19457      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19458                                  operands[0], operands[1]);
19459    else
19460      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19461                                  operands[1], operands[0]);")
19462
19463 ;; Conditional addition patterns
19464 (define_expand "addqicc"
19465   [(match_operand:QI 0 "register_operand" "")
19466    (match_operand 1 "comparison_operator" "")
19467    (match_operand:QI 2 "register_operand" "")
19468    (match_operand:QI 3 "const_int_operand" "")]
19469   ""
19470   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19471
19472 (define_expand "addhicc"
19473   [(match_operand:HI 0 "register_operand" "")
19474    (match_operand 1 "comparison_operator" "")
19475    (match_operand:HI 2 "register_operand" "")
19476    (match_operand:HI 3 "const_int_operand" "")]
19477   ""
19478   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19479
19480 (define_expand "addsicc"
19481   [(match_operand:SI 0 "register_operand" "")
19482    (match_operand 1 "comparison_operator" "")
19483    (match_operand:SI 2 "register_operand" "")
19484    (match_operand:SI 3 "const_int_operand" "")]
19485   ""
19486   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19487
19488 (define_expand "adddicc"
19489   [(match_operand:DI 0 "register_operand" "")
19490    (match_operand 1 "comparison_operator" "")
19491    (match_operand:DI 2 "register_operand" "")
19492    (match_operand:DI 3 "const_int_operand" "")]
19493   "TARGET_64BIT"
19494   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19495
19496 \f
19497 ;; Misc patterns (?)
19498
19499 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19500 ;; Otherwise there will be nothing to keep
19501 ;;
19502 ;; [(set (reg ebp) (reg esp))]
19503 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19504 ;;  (clobber (eflags)]
19505 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19506 ;;
19507 ;; in proper program order.
19508 (define_insn "pro_epilogue_adjust_stack_1"
19509   [(set (match_operand:SI 0 "register_operand" "=r,r")
19510         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19511                  (match_operand:SI 2 "immediate_operand" "i,i")))
19512    (clobber (reg:CC FLAGS_REG))
19513    (clobber (mem:BLK (scratch)))]
19514   "!TARGET_64BIT"
19515 {
19516   switch (get_attr_type (insn))
19517     {
19518     case TYPE_IMOV:
19519       return "mov{l}\t{%1, %0|%0, %1}";
19520
19521     case TYPE_ALU:
19522       if (CONST_INT_P (operands[2])
19523           && (INTVAL (operands[2]) == 128
19524               || (INTVAL (operands[2]) < 0
19525                   && INTVAL (operands[2]) != -128)))
19526         {
19527           operands[2] = GEN_INT (-INTVAL (operands[2]));
19528           return "sub{l}\t{%2, %0|%0, %2}";
19529         }
19530       return "add{l}\t{%2, %0|%0, %2}";
19531
19532     case TYPE_LEA:
19533       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19534       return "lea{l}\t{%a2, %0|%0, %a2}";
19535
19536     default:
19537       gcc_unreachable ();
19538     }
19539 }
19540   [(set (attr "type")
19541         (cond [(eq_attr "alternative" "0")
19542                  (const_string "alu")
19543                (match_operand:SI 2 "const0_operand" "")
19544                  (const_string "imov")
19545               ]
19546               (const_string "lea")))
19547    (set_attr "mode" "SI")])
19548
19549 (define_insn "pro_epilogue_adjust_stack_rex64"
19550   [(set (match_operand:DI 0 "register_operand" "=r,r")
19551         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19552                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19553    (clobber (reg:CC FLAGS_REG))
19554    (clobber (mem:BLK (scratch)))]
19555   "TARGET_64BIT"
19556 {
19557   switch (get_attr_type (insn))
19558     {
19559     case TYPE_IMOV:
19560       return "mov{q}\t{%1, %0|%0, %1}";
19561
19562     case TYPE_ALU:
19563       if (CONST_INT_P (operands[2])
19564           /* Avoid overflows.  */
19565           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19566           && (INTVAL (operands[2]) == 128
19567               || (INTVAL (operands[2]) < 0
19568                   && INTVAL (operands[2]) != -128)))
19569         {
19570           operands[2] = GEN_INT (-INTVAL (operands[2]));
19571           return "sub{q}\t{%2, %0|%0, %2}";
19572         }
19573       return "add{q}\t{%2, %0|%0, %2}";
19574
19575     case TYPE_LEA:
19576       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19577       return "lea{q}\t{%a2, %0|%0, %a2}";
19578
19579     default:
19580       gcc_unreachable ();
19581     }
19582 }
19583   [(set (attr "type")
19584         (cond [(eq_attr "alternative" "0")
19585                  (const_string "alu")
19586                (match_operand:DI 2 "const0_operand" "")
19587                  (const_string "imov")
19588               ]
19589               (const_string "lea")))
19590    (set_attr "mode" "DI")])
19591
19592 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19593   [(set (match_operand:DI 0 "register_operand" "=r,r")
19594         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19595                  (match_operand:DI 3 "immediate_operand" "i,i")))
19596    (use (match_operand:DI 2 "register_operand" "r,r"))
19597    (clobber (reg:CC FLAGS_REG))
19598    (clobber (mem:BLK (scratch)))]
19599   "TARGET_64BIT"
19600 {
19601   switch (get_attr_type (insn))
19602     {
19603     case TYPE_ALU:
19604       return "add{q}\t{%2, %0|%0, %2}";
19605
19606     case TYPE_LEA:
19607       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19608       return "lea{q}\t{%a2, %0|%0, %a2}";
19609
19610     default:
19611       gcc_unreachable ();
19612     }
19613 }
19614   [(set_attr "type" "alu,lea")
19615    (set_attr "mode" "DI")])
19616
19617 (define_expand "allocate_stack_worker"
19618   [(match_operand:SI 0 "register_operand" "")]
19619   "TARGET_STACK_PROBE"
19620 {
19621   if (reload_completed)
19622     {
19623       if (TARGET_64BIT)
19624         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19625       else
19626         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19627     }
19628   else
19629     {
19630       if (TARGET_64BIT)
19631         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19632       else
19633         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19634     }
19635   DONE;
19636 })
19637
19638 (define_insn "allocate_stack_worker_1"
19639   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19640     UNSPECV_STACK_PROBE)
19641    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19642    (clobber (match_scratch:SI 1 "=0"))
19643    (clobber (reg:CC FLAGS_REG))]
19644   "!TARGET_64BIT && TARGET_STACK_PROBE"
19645   "call\t__alloca"
19646   [(set_attr "type" "multi")
19647    (set_attr "length" "5")])
19648
19649 (define_expand "allocate_stack_worker_postreload"
19650   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19651                                     UNSPECV_STACK_PROBE)
19652               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19653               (clobber (match_dup 0))
19654               (clobber (reg:CC FLAGS_REG))])]
19655   ""
19656   "")
19657
19658 (define_insn "allocate_stack_worker_rex64"
19659   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19660     UNSPECV_STACK_PROBE)
19661    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19662    (clobber (match_scratch:DI 1 "=0"))
19663    (clobber (reg:CC FLAGS_REG))]
19664   "TARGET_64BIT && TARGET_STACK_PROBE"
19665   "call\t__alloca"
19666   [(set_attr "type" "multi")
19667    (set_attr "length" "5")])
19668
19669 (define_expand "allocate_stack_worker_rex64_postreload"
19670   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19671                                     UNSPECV_STACK_PROBE)
19672               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19673               (clobber (match_dup 0))
19674               (clobber (reg:CC FLAGS_REG))])]
19675   ""
19676   "")
19677
19678 (define_expand "allocate_stack"
19679   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19680                    (minus:SI (reg:SI SP_REG)
19681                              (match_operand:SI 1 "general_operand" "")))
19682               (clobber (reg:CC FLAGS_REG))])
19683    (parallel [(set (reg:SI SP_REG)
19684                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
19685               (clobber (reg:CC FLAGS_REG))])]
19686   "TARGET_STACK_PROBE"
19687 {
19688 #ifdef CHECK_STACK_LIMIT
19689   if (CONST_INT_P (operands[1])
19690       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19691     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19692                            operands[1]));
19693   else
19694 #endif
19695     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19696                                                             operands[1])));
19697
19698   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19699   DONE;
19700 })
19701
19702 (define_expand "builtin_setjmp_receiver"
19703   [(label_ref (match_operand 0 "" ""))]
19704   "!TARGET_64BIT && flag_pic"
19705 {
19706   if (TARGET_MACHO)
19707     {
19708       rtx xops[3];
19709       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19710       rtx label_rtx = gen_label_rtx ();
19711       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19712       xops[0] = xops[1] = picreg;
19713       xops[2] = gen_rtx_CONST (SImode,
19714                   gen_rtx_MINUS (SImode,
19715                     gen_rtx_LABEL_REF (SImode, label_rtx),
19716                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19717       ix86_expand_binary_operator (MINUS, SImode, xops);
19718     }
19719   else
19720     emit_insn (gen_set_got (pic_offset_table_rtx));
19721   DONE;
19722 })
19723 \f
19724 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19725
19726 (define_split
19727   [(set (match_operand 0 "register_operand" "")
19728         (match_operator 3 "promotable_binary_operator"
19729            [(match_operand 1 "register_operand" "")
19730             (match_operand 2 "aligned_operand" "")]))
19731    (clobber (reg:CC FLAGS_REG))]
19732   "! TARGET_PARTIAL_REG_STALL && reload_completed
19733    && ((GET_MODE (operands[0]) == HImode
19734         && ((!optimize_size && !TARGET_FAST_PREFIX)
19735             /* ??? next two lines just !satisfies_constraint_K (...) */
19736             || !CONST_INT_P (operands[2])
19737             || satisfies_constraint_K (operands[2])))
19738        || (GET_MODE (operands[0]) == QImode
19739            && (TARGET_PROMOTE_QImode || optimize_size)))"
19740   [(parallel [(set (match_dup 0)
19741                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19742               (clobber (reg:CC FLAGS_REG))])]
19743   "operands[0] = gen_lowpart (SImode, operands[0]);
19744    operands[1] = gen_lowpart (SImode, operands[1]);
19745    if (GET_CODE (operands[3]) != ASHIFT)
19746      operands[2] = gen_lowpart (SImode, operands[2]);
19747    PUT_MODE (operands[3], SImode);")
19748
19749 ; Promote the QImode tests, as i386 has encoding of the AND
19750 ; instruction with 32-bit sign-extended immediate and thus the
19751 ; instruction size is unchanged, except in the %eax case for
19752 ; which it is increased by one byte, hence the ! optimize_size.
19753 (define_split
19754   [(set (match_operand 0 "flags_reg_operand" "")
19755         (match_operator 2 "compare_operator"
19756           [(and (match_operand 3 "aligned_operand" "")
19757                 (match_operand 4 "const_int_operand" ""))
19758            (const_int 0)]))
19759    (set (match_operand 1 "register_operand" "")
19760         (and (match_dup 3) (match_dup 4)))]
19761   "! TARGET_PARTIAL_REG_STALL && reload_completed
19762    /* Ensure that the operand will remain sign-extended immediate.  */
19763    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19764    && ! optimize_size
19765    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19766        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19767   [(parallel [(set (match_dup 0)
19768                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19769                                     (const_int 0)]))
19770               (set (match_dup 1)
19771                    (and:SI (match_dup 3) (match_dup 4)))])]
19772 {
19773   operands[4]
19774     = gen_int_mode (INTVAL (operands[4])
19775                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19776   operands[1] = gen_lowpart (SImode, operands[1]);
19777   operands[3] = gen_lowpart (SImode, operands[3]);
19778 })
19779
19780 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19781 ; the TEST instruction with 32-bit sign-extended immediate and thus
19782 ; the instruction size would at least double, which is not what we
19783 ; want even with ! optimize_size.
19784 (define_split
19785   [(set (match_operand 0 "flags_reg_operand" "")
19786         (match_operator 1 "compare_operator"
19787           [(and (match_operand:HI 2 "aligned_operand" "")
19788                 (match_operand:HI 3 "const_int_operand" ""))
19789            (const_int 0)]))]
19790   "! TARGET_PARTIAL_REG_STALL && reload_completed
19791    /* Ensure that the operand will remain sign-extended immediate.  */
19792    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19793    && ! TARGET_FAST_PREFIX
19794    && ! optimize_size"
19795   [(set (match_dup 0)
19796         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19797                          (const_int 0)]))]
19798 {
19799   operands[3]
19800     = gen_int_mode (INTVAL (operands[3])
19801                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19802   operands[2] = gen_lowpart (SImode, operands[2]);
19803 })
19804
19805 (define_split
19806   [(set (match_operand 0 "register_operand" "")
19807         (neg (match_operand 1 "register_operand" "")))
19808    (clobber (reg:CC FLAGS_REG))]
19809   "! TARGET_PARTIAL_REG_STALL && reload_completed
19810    && (GET_MODE (operands[0]) == HImode
19811        || (GET_MODE (operands[0]) == QImode
19812            && (TARGET_PROMOTE_QImode || optimize_size)))"
19813   [(parallel [(set (match_dup 0)
19814                    (neg:SI (match_dup 1)))
19815               (clobber (reg:CC FLAGS_REG))])]
19816   "operands[0] = gen_lowpart (SImode, operands[0]);
19817    operands[1] = gen_lowpart (SImode, operands[1]);")
19818
19819 (define_split
19820   [(set (match_operand 0 "register_operand" "")
19821         (not (match_operand 1 "register_operand" "")))]
19822   "! TARGET_PARTIAL_REG_STALL && reload_completed
19823    && (GET_MODE (operands[0]) == HImode
19824        || (GET_MODE (operands[0]) == QImode
19825            && (TARGET_PROMOTE_QImode || optimize_size)))"
19826   [(set (match_dup 0)
19827         (not:SI (match_dup 1)))]
19828   "operands[0] = gen_lowpart (SImode, operands[0]);
19829    operands[1] = gen_lowpart (SImode, operands[1]);")
19830
19831 (define_split
19832   [(set (match_operand 0 "register_operand" "")
19833         (if_then_else (match_operator 1 "comparison_operator"
19834                                 [(reg FLAGS_REG) (const_int 0)])
19835                       (match_operand 2 "register_operand" "")
19836                       (match_operand 3 "register_operand" "")))]
19837   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19838    && (GET_MODE (operands[0]) == HImode
19839        || (GET_MODE (operands[0]) == QImode
19840            && (TARGET_PROMOTE_QImode || optimize_size)))"
19841   [(set (match_dup 0)
19842         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19843   "operands[0] = gen_lowpart (SImode, operands[0]);
19844    operands[2] = gen_lowpart (SImode, operands[2]);
19845    operands[3] = gen_lowpart (SImode, operands[3]);")
19846
19847 \f
19848 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19849 ;; transform a complex memory operation into two memory to register operations.
19850
19851 ;; Don't push memory operands
19852 (define_peephole2
19853   [(set (match_operand:SI 0 "push_operand" "")
19854         (match_operand:SI 1 "memory_operand" ""))
19855    (match_scratch:SI 2 "r")]
19856   "!optimize_size && !TARGET_PUSH_MEMORY
19857    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19858   [(set (match_dup 2) (match_dup 1))
19859    (set (match_dup 0) (match_dup 2))]
19860   "")
19861
19862 (define_peephole2
19863   [(set (match_operand:DI 0 "push_operand" "")
19864         (match_operand:DI 1 "memory_operand" ""))
19865    (match_scratch:DI 2 "r")]
19866   "!optimize_size && !TARGET_PUSH_MEMORY
19867    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19868   [(set (match_dup 2) (match_dup 1))
19869    (set (match_dup 0) (match_dup 2))]
19870   "")
19871
19872 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19873 ;; SImode pushes.
19874 (define_peephole2
19875   [(set (match_operand:SF 0 "push_operand" "")
19876         (match_operand:SF 1 "memory_operand" ""))
19877    (match_scratch:SF 2 "r")]
19878   "!optimize_size && !TARGET_PUSH_MEMORY
19879    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19880   [(set (match_dup 2) (match_dup 1))
19881    (set (match_dup 0) (match_dup 2))]
19882   "")
19883
19884 (define_peephole2
19885   [(set (match_operand:HI 0 "push_operand" "")
19886         (match_operand:HI 1 "memory_operand" ""))
19887    (match_scratch:HI 2 "r")]
19888   "!optimize_size && !TARGET_PUSH_MEMORY
19889    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19890   [(set (match_dup 2) (match_dup 1))
19891    (set (match_dup 0) (match_dup 2))]
19892   "")
19893
19894 (define_peephole2
19895   [(set (match_operand:QI 0 "push_operand" "")
19896         (match_operand:QI 1 "memory_operand" ""))
19897    (match_scratch:QI 2 "q")]
19898   "!optimize_size && !TARGET_PUSH_MEMORY
19899    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19900   [(set (match_dup 2) (match_dup 1))
19901    (set (match_dup 0) (match_dup 2))]
19902   "")
19903
19904 ;; Don't move an immediate directly to memory when the instruction
19905 ;; gets too big.
19906 (define_peephole2
19907   [(match_scratch:SI 1 "r")
19908    (set (match_operand:SI 0 "memory_operand" "")
19909         (const_int 0))]
19910   "! optimize_size
19911    && ! TARGET_USE_MOV0
19912    && TARGET_SPLIT_LONG_MOVES
19913    && get_attr_length (insn) >= ix86_cost->large_insn
19914    && peep2_regno_dead_p (0, FLAGS_REG)"
19915   [(parallel [(set (match_dup 1) (const_int 0))
19916               (clobber (reg:CC FLAGS_REG))])
19917    (set (match_dup 0) (match_dup 1))]
19918   "")
19919
19920 (define_peephole2
19921   [(match_scratch:HI 1 "r")
19922    (set (match_operand:HI 0 "memory_operand" "")
19923         (const_int 0))]
19924   "! optimize_size
19925    && ! TARGET_USE_MOV0
19926    && TARGET_SPLIT_LONG_MOVES
19927    && get_attr_length (insn) >= ix86_cost->large_insn
19928    && peep2_regno_dead_p (0, FLAGS_REG)"
19929   [(parallel [(set (match_dup 2) (const_int 0))
19930               (clobber (reg:CC FLAGS_REG))])
19931    (set (match_dup 0) (match_dup 1))]
19932   "operands[2] = gen_lowpart (SImode, operands[1]);")
19933
19934 (define_peephole2
19935   [(match_scratch:QI 1 "q")
19936    (set (match_operand:QI 0 "memory_operand" "")
19937         (const_int 0))]
19938   "! optimize_size
19939    && ! TARGET_USE_MOV0
19940    && TARGET_SPLIT_LONG_MOVES
19941    && get_attr_length (insn) >= ix86_cost->large_insn
19942    && peep2_regno_dead_p (0, FLAGS_REG)"
19943   [(parallel [(set (match_dup 2) (const_int 0))
19944               (clobber (reg:CC FLAGS_REG))])
19945    (set (match_dup 0) (match_dup 1))]
19946   "operands[2] = gen_lowpart (SImode, operands[1]);")
19947
19948 (define_peephole2
19949   [(match_scratch:SI 2 "r")
19950    (set (match_operand:SI 0 "memory_operand" "")
19951         (match_operand:SI 1 "immediate_operand" ""))]
19952   "! optimize_size
19953    && get_attr_length (insn) >= ix86_cost->large_insn
19954    && TARGET_SPLIT_LONG_MOVES"
19955   [(set (match_dup 2) (match_dup 1))
19956    (set (match_dup 0) (match_dup 2))]
19957   "")
19958
19959 (define_peephole2
19960   [(match_scratch:HI 2 "r")
19961    (set (match_operand:HI 0 "memory_operand" "")
19962         (match_operand:HI 1 "immediate_operand" ""))]
19963   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19964   && TARGET_SPLIT_LONG_MOVES"
19965   [(set (match_dup 2) (match_dup 1))
19966    (set (match_dup 0) (match_dup 2))]
19967   "")
19968
19969 (define_peephole2
19970   [(match_scratch:QI 2 "q")
19971    (set (match_operand:QI 0 "memory_operand" "")
19972         (match_operand:QI 1 "immediate_operand" ""))]
19973   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19974   && TARGET_SPLIT_LONG_MOVES"
19975   [(set (match_dup 2) (match_dup 1))
19976    (set (match_dup 0) (match_dup 2))]
19977   "")
19978
19979 ;; Don't compare memory with zero, load and use a test instead.
19980 (define_peephole2
19981   [(set (match_operand 0 "flags_reg_operand" "")
19982         (match_operator 1 "compare_operator"
19983           [(match_operand:SI 2 "memory_operand" "")
19984            (const_int 0)]))
19985    (match_scratch:SI 3 "r")]
19986   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19987   [(set (match_dup 3) (match_dup 2))
19988    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19989   "")
19990
19991 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19992 ;; Don't split NOTs with a displacement operand, because resulting XOR
19993 ;; will not be pairable anyway.
19994 ;;
19995 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19996 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19997 ;; so this split helps here as well.
19998 ;;
19999 ;; Note: Can't do this as a regular split because we can't get proper
20000 ;; lifetime information then.
20001
20002 (define_peephole2
20003   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20004         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20005   "!optimize_size
20006    && peep2_regno_dead_p (0, FLAGS_REG)
20007    && ((TARGET_PENTIUM
20008         && (!MEM_P (operands[0])
20009             || !memory_displacement_operand (operands[0], SImode)))
20010        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
20011   [(parallel [(set (match_dup 0)
20012                    (xor:SI (match_dup 1) (const_int -1)))
20013               (clobber (reg:CC FLAGS_REG))])]
20014   "")
20015
20016 (define_peephole2
20017   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20018         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20019   "!optimize_size
20020    && peep2_regno_dead_p (0, FLAGS_REG)
20021    && ((TARGET_PENTIUM
20022         && (!MEM_P (operands[0])
20023             || !memory_displacement_operand (operands[0], HImode)))
20024        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
20025   [(parallel [(set (match_dup 0)
20026                    (xor:HI (match_dup 1) (const_int -1)))
20027               (clobber (reg:CC FLAGS_REG))])]
20028   "")
20029
20030 (define_peephole2
20031   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20032         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20033   "!optimize_size
20034    && peep2_regno_dead_p (0, FLAGS_REG)
20035    && ((TARGET_PENTIUM
20036         && (!MEM_P (operands[0])
20037             || !memory_displacement_operand (operands[0], QImode)))
20038        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
20039   [(parallel [(set (match_dup 0)
20040                    (xor:QI (match_dup 1) (const_int -1)))
20041               (clobber (reg:CC FLAGS_REG))])]
20042   "")
20043
20044 ;; Non pairable "test imm, reg" instructions can be translated to
20045 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20046 ;; byte opcode instead of two, have a short form for byte operands),
20047 ;; so do it for other CPUs as well.  Given that the value was dead,
20048 ;; this should not create any new dependencies.  Pass on the sub-word
20049 ;; versions if we're concerned about partial register stalls.
20050
20051 (define_peephole2
20052   [(set (match_operand 0 "flags_reg_operand" "")
20053         (match_operator 1 "compare_operator"
20054           [(and:SI (match_operand:SI 2 "register_operand" "")
20055                    (match_operand:SI 3 "immediate_operand" ""))
20056            (const_int 0)]))]
20057   "ix86_match_ccmode (insn, CCNOmode)
20058    && (true_regnum (operands[2]) != 0
20059        || satisfies_constraint_K (operands[3]))
20060    && peep2_reg_dead_p (1, operands[2])"
20061   [(parallel
20062      [(set (match_dup 0)
20063            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20064                             (const_int 0)]))
20065       (set (match_dup 2)
20066            (and:SI (match_dup 2) (match_dup 3)))])]
20067   "")
20068
20069 ;; We don't need to handle HImode case, because it will be promoted to SImode
20070 ;; on ! TARGET_PARTIAL_REG_STALL
20071
20072 (define_peephole2
20073   [(set (match_operand 0 "flags_reg_operand" "")
20074         (match_operator 1 "compare_operator"
20075           [(and:QI (match_operand:QI 2 "register_operand" "")
20076                    (match_operand:QI 3 "immediate_operand" ""))
20077            (const_int 0)]))]
20078   "! TARGET_PARTIAL_REG_STALL
20079    && ix86_match_ccmode (insn, CCNOmode)
20080    && true_regnum (operands[2]) != 0
20081    && peep2_reg_dead_p (1, operands[2])"
20082   [(parallel
20083      [(set (match_dup 0)
20084            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20085                             (const_int 0)]))
20086       (set (match_dup 2)
20087            (and:QI (match_dup 2) (match_dup 3)))])]
20088   "")
20089
20090 (define_peephole2
20091   [(set (match_operand 0 "flags_reg_operand" "")
20092         (match_operator 1 "compare_operator"
20093           [(and:SI
20094              (zero_extract:SI
20095                (match_operand 2 "ext_register_operand" "")
20096                (const_int 8)
20097                (const_int 8))
20098              (match_operand 3 "const_int_operand" ""))
20099            (const_int 0)]))]
20100   "! TARGET_PARTIAL_REG_STALL
20101    && ix86_match_ccmode (insn, CCNOmode)
20102    && true_regnum (operands[2]) != 0
20103    && peep2_reg_dead_p (1, operands[2])"
20104   [(parallel [(set (match_dup 0)
20105                    (match_op_dup 1
20106                      [(and:SI
20107                         (zero_extract:SI
20108                           (match_dup 2)
20109                           (const_int 8)
20110                           (const_int 8))
20111                         (match_dup 3))
20112                       (const_int 0)]))
20113               (set (zero_extract:SI (match_dup 2)
20114                                     (const_int 8)
20115                                     (const_int 8))
20116                    (and:SI
20117                      (zero_extract:SI
20118                        (match_dup 2)
20119                        (const_int 8)
20120                        (const_int 8))
20121                      (match_dup 3)))])]
20122   "")
20123
20124 ;; Don't do logical operations with memory inputs.
20125 (define_peephole2
20126   [(match_scratch:SI 2 "r")
20127    (parallel [(set (match_operand:SI 0 "register_operand" "")
20128                    (match_operator:SI 3 "arith_or_logical_operator"
20129                      [(match_dup 0)
20130                       (match_operand:SI 1 "memory_operand" "")]))
20131               (clobber (reg:CC FLAGS_REG))])]
20132   "! optimize_size && ! TARGET_READ_MODIFY"
20133   [(set (match_dup 2) (match_dup 1))
20134    (parallel [(set (match_dup 0)
20135                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20136               (clobber (reg:CC FLAGS_REG))])]
20137   "")
20138
20139 (define_peephole2
20140   [(match_scratch:SI 2 "r")
20141    (parallel [(set (match_operand:SI 0 "register_operand" "")
20142                    (match_operator:SI 3 "arith_or_logical_operator"
20143                      [(match_operand:SI 1 "memory_operand" "")
20144                       (match_dup 0)]))
20145               (clobber (reg:CC FLAGS_REG))])]
20146   "! optimize_size && ! TARGET_READ_MODIFY"
20147   [(set (match_dup 2) (match_dup 1))
20148    (parallel [(set (match_dup 0)
20149                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20150               (clobber (reg:CC FLAGS_REG))])]
20151   "")
20152
20153 ; Don't do logical operations with memory outputs
20154 ;
20155 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20156 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20157 ; the same decoder scheduling characteristics as the original.
20158
20159 (define_peephole2
20160   [(match_scratch:SI 2 "r")
20161    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20162                    (match_operator:SI 3 "arith_or_logical_operator"
20163                      [(match_dup 0)
20164                       (match_operand:SI 1 "nonmemory_operand" "")]))
20165               (clobber (reg:CC FLAGS_REG))])]
20166   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20167   [(set (match_dup 2) (match_dup 0))
20168    (parallel [(set (match_dup 2)
20169                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20170               (clobber (reg:CC FLAGS_REG))])
20171    (set (match_dup 0) (match_dup 2))]
20172   "")
20173
20174 (define_peephole2
20175   [(match_scratch:SI 2 "r")
20176    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20177                    (match_operator:SI 3 "arith_or_logical_operator"
20178                      [(match_operand:SI 1 "nonmemory_operand" "")
20179                       (match_dup 0)]))
20180               (clobber (reg:CC FLAGS_REG))])]
20181   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20182   [(set (match_dup 2) (match_dup 0))
20183    (parallel [(set (match_dup 2)
20184                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20185               (clobber (reg:CC FLAGS_REG))])
20186    (set (match_dup 0) (match_dup 2))]
20187   "")
20188
20189 ;; Attempt to always use XOR for zeroing registers.
20190 (define_peephole2
20191   [(set (match_operand 0 "register_operand" "")
20192         (match_operand 1 "const0_operand" ""))]
20193   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20194    && (! TARGET_USE_MOV0 || optimize_size)
20195    && GENERAL_REG_P (operands[0])
20196    && peep2_regno_dead_p (0, FLAGS_REG)"
20197   [(parallel [(set (match_dup 0) (const_int 0))
20198               (clobber (reg:CC FLAGS_REG))])]
20199 {
20200   operands[0] = gen_lowpart (word_mode, operands[0]);
20201 })
20202
20203 (define_peephole2
20204   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20205         (const_int 0))]
20206   "(GET_MODE (operands[0]) == QImode
20207     || GET_MODE (operands[0]) == HImode)
20208    && (! TARGET_USE_MOV0 || optimize_size)
20209    && peep2_regno_dead_p (0, FLAGS_REG)"
20210   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20211               (clobber (reg:CC FLAGS_REG))])])
20212
20213 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20214 (define_peephole2
20215   [(set (match_operand 0 "register_operand" "")
20216         (const_int -1))]
20217   "(GET_MODE (operands[0]) == HImode
20218     || GET_MODE (operands[0]) == SImode
20219     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20220    && (optimize_size || TARGET_PENTIUM)
20221    && peep2_regno_dead_p (0, FLAGS_REG)"
20222   [(parallel [(set (match_dup 0) (const_int -1))
20223               (clobber (reg:CC FLAGS_REG))])]
20224   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20225                               operands[0]);")
20226
20227 ;; Attempt to convert simple leas to adds. These can be created by
20228 ;; move expanders.
20229 (define_peephole2
20230   [(set (match_operand:SI 0 "register_operand" "")
20231         (plus:SI (match_dup 0)
20232                  (match_operand:SI 1 "nonmemory_operand" "")))]
20233   "peep2_regno_dead_p (0, FLAGS_REG)"
20234   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20235               (clobber (reg:CC FLAGS_REG))])]
20236   "")
20237
20238 (define_peephole2
20239   [(set (match_operand:SI 0 "register_operand" "")
20240         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20241                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20242   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20243   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20244               (clobber (reg:CC FLAGS_REG))])]
20245   "operands[2] = gen_lowpart (SImode, operands[2]);")
20246
20247 (define_peephole2
20248   [(set (match_operand:DI 0 "register_operand" "")
20249         (plus:DI (match_dup 0)
20250                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20251   "peep2_regno_dead_p (0, FLAGS_REG)"
20252   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20253               (clobber (reg:CC FLAGS_REG))])]
20254   "")
20255
20256 (define_peephole2
20257   [(set (match_operand:SI 0 "register_operand" "")
20258         (mult:SI (match_dup 0)
20259                  (match_operand:SI 1 "const_int_operand" "")))]
20260   "exact_log2 (INTVAL (operands[1])) >= 0
20261    && peep2_regno_dead_p (0, FLAGS_REG)"
20262   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20263               (clobber (reg:CC FLAGS_REG))])]
20264   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20265
20266 (define_peephole2
20267   [(set (match_operand:DI 0 "register_operand" "")
20268         (mult:DI (match_dup 0)
20269                  (match_operand:DI 1 "const_int_operand" "")))]
20270   "exact_log2 (INTVAL (operands[1])) >= 0
20271    && peep2_regno_dead_p (0, FLAGS_REG)"
20272   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20273               (clobber (reg:CC FLAGS_REG))])]
20274   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20275
20276 (define_peephole2
20277   [(set (match_operand:SI 0 "register_operand" "")
20278         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20279                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20280   "exact_log2 (INTVAL (operands[2])) >= 0
20281    && REGNO (operands[0]) == REGNO (operands[1])
20282    && peep2_regno_dead_p (0, FLAGS_REG)"
20283   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20284               (clobber (reg:CC FLAGS_REG))])]
20285   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20286
20287 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20288 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20289 ;; many CPUs it is also faster, since special hardware to avoid esp
20290 ;; dependencies is present.
20291
20292 ;; While some of these conversions may be done using splitters, we use peepholes
20293 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20294
20295 ;; Convert prologue esp subtractions to push.
20296 ;; We need register to push.  In order to keep verify_flow_info happy we have
20297 ;; two choices
20298 ;; - use scratch and clobber it in order to avoid dependencies
20299 ;; - use already live register
20300 ;; We can't use the second way right now, since there is no reliable way how to
20301 ;; verify that given register is live.  First choice will also most likely in
20302 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20303 ;; call clobbered registers are dead.  We may want to use base pointer as an
20304 ;; alternative when no register is available later.
20305
20306 (define_peephole2
20307   [(match_scratch:SI 0 "r")
20308    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20309               (clobber (reg:CC FLAGS_REG))
20310               (clobber (mem:BLK (scratch)))])]
20311   "optimize_size || !TARGET_SUB_ESP_4"
20312   [(clobber (match_dup 0))
20313    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20314               (clobber (mem:BLK (scratch)))])])
20315
20316 (define_peephole2
20317   [(match_scratch:SI 0 "r")
20318    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20319               (clobber (reg:CC FLAGS_REG))
20320               (clobber (mem:BLK (scratch)))])]
20321   "optimize_size || !TARGET_SUB_ESP_8"
20322   [(clobber (match_dup 0))
20323    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20324    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20325               (clobber (mem:BLK (scratch)))])])
20326
20327 ;; Convert esp subtractions to push.
20328 (define_peephole2
20329   [(match_scratch:SI 0 "r")
20330    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20331               (clobber (reg:CC FLAGS_REG))])]
20332   "optimize_size || !TARGET_SUB_ESP_4"
20333   [(clobber (match_dup 0))
20334    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20335
20336 (define_peephole2
20337   [(match_scratch:SI 0 "r")
20338    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20339               (clobber (reg:CC FLAGS_REG))])]
20340   "optimize_size || !TARGET_SUB_ESP_8"
20341   [(clobber (match_dup 0))
20342    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20343    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20344
20345 ;; Convert epilogue deallocator to pop.
20346 (define_peephole2
20347   [(match_scratch:SI 0 "r")
20348    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20349               (clobber (reg:CC FLAGS_REG))
20350               (clobber (mem:BLK (scratch)))])]
20351   "optimize_size || !TARGET_ADD_ESP_4"
20352   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20353               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20354               (clobber (mem:BLK (scratch)))])]
20355   "")
20356
20357 ;; Two pops case is tricky, since pop causes dependency on destination register.
20358 ;; We use two registers if available.
20359 (define_peephole2
20360   [(match_scratch:SI 0 "r")
20361    (match_scratch:SI 1 "r")
20362    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20363               (clobber (reg:CC FLAGS_REG))
20364               (clobber (mem:BLK (scratch)))])]
20365   "optimize_size || !TARGET_ADD_ESP_8"
20366   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20367               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20368               (clobber (mem:BLK (scratch)))])
20369    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20370               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20371   "")
20372
20373 (define_peephole2
20374   [(match_scratch:SI 0 "r")
20375    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20376               (clobber (reg:CC FLAGS_REG))
20377               (clobber (mem:BLK (scratch)))])]
20378   "optimize_size"
20379   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20380               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20381               (clobber (mem:BLK (scratch)))])
20382    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20383               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20384   "")
20385
20386 ;; Convert esp additions to pop.
20387 (define_peephole2
20388   [(match_scratch:SI 0 "r")
20389    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20390               (clobber (reg:CC FLAGS_REG))])]
20391   ""
20392   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20393               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20394   "")
20395
20396 ;; Two pops case is tricky, since pop causes dependency on destination register.
20397 ;; We use two registers if available.
20398 (define_peephole2
20399   [(match_scratch:SI 0 "r")
20400    (match_scratch:SI 1 "r")
20401    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20402               (clobber (reg:CC FLAGS_REG))])]
20403   ""
20404   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20405               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20406    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20407               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20408   "")
20409
20410 (define_peephole2
20411   [(match_scratch:SI 0 "r")
20412    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20413               (clobber (reg:CC FLAGS_REG))])]
20414   "optimize_size"
20415   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20416               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20417    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20418               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20419   "")
20420 \f
20421 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20422 ;; required and register dies.  Similarly for 128 to plus -128.
20423 (define_peephole2
20424   [(set (match_operand 0 "flags_reg_operand" "")
20425         (match_operator 1 "compare_operator"
20426           [(match_operand 2 "register_operand" "")
20427            (match_operand 3 "const_int_operand" "")]))]
20428   "(INTVAL (operands[3]) == -1
20429     || INTVAL (operands[3]) == 1
20430     || INTVAL (operands[3]) == 128)
20431    && ix86_match_ccmode (insn, CCGCmode)
20432    && peep2_reg_dead_p (1, operands[2])"
20433   [(parallel [(set (match_dup 0)
20434                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20435               (clobber (match_dup 2))])]
20436   "")
20437 \f
20438 (define_peephole2
20439   [(match_scratch:DI 0 "r")
20440    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20441               (clobber (reg:CC FLAGS_REG))
20442               (clobber (mem:BLK (scratch)))])]
20443   "optimize_size || !TARGET_SUB_ESP_4"
20444   [(clobber (match_dup 0))
20445    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20446               (clobber (mem:BLK (scratch)))])])
20447
20448 (define_peephole2
20449   [(match_scratch:DI 0 "r")
20450    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20451               (clobber (reg:CC FLAGS_REG))
20452               (clobber (mem:BLK (scratch)))])]
20453   "optimize_size || !TARGET_SUB_ESP_8"
20454   [(clobber (match_dup 0))
20455    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20456    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20457               (clobber (mem:BLK (scratch)))])])
20458
20459 ;; Convert esp subtractions to push.
20460 (define_peephole2
20461   [(match_scratch:DI 0 "r")
20462    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20463               (clobber (reg:CC FLAGS_REG))])]
20464   "optimize_size || !TARGET_SUB_ESP_4"
20465   [(clobber (match_dup 0))
20466    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20467
20468 (define_peephole2
20469   [(match_scratch:DI 0 "r")
20470    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20471               (clobber (reg:CC FLAGS_REG))])]
20472   "optimize_size || !TARGET_SUB_ESP_8"
20473   [(clobber (match_dup 0))
20474    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20475    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20476
20477 ;; Convert epilogue deallocator to pop.
20478 (define_peephole2
20479   [(match_scratch:DI 0 "r")
20480    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20481               (clobber (reg:CC FLAGS_REG))
20482               (clobber (mem:BLK (scratch)))])]
20483   "optimize_size || !TARGET_ADD_ESP_4"
20484   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20485               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20486               (clobber (mem:BLK (scratch)))])]
20487   "")
20488
20489 ;; Two pops case is tricky, since pop causes dependency on destination register.
20490 ;; We use two registers if available.
20491 (define_peephole2
20492   [(match_scratch:DI 0 "r")
20493    (match_scratch:DI 1 "r")
20494    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20495               (clobber (reg:CC FLAGS_REG))
20496               (clobber (mem:BLK (scratch)))])]
20497   "optimize_size || !TARGET_ADD_ESP_8"
20498   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20499               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20500               (clobber (mem:BLK (scratch)))])
20501    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20502               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20503   "")
20504
20505 (define_peephole2
20506   [(match_scratch:DI 0 "r")
20507    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20508               (clobber (reg:CC FLAGS_REG))
20509               (clobber (mem:BLK (scratch)))])]
20510   "optimize_size"
20511   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20512               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20513               (clobber (mem:BLK (scratch)))])
20514    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20515               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20516   "")
20517
20518 ;; Convert esp additions to pop.
20519 (define_peephole2
20520   [(match_scratch:DI 0 "r")
20521    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20522               (clobber (reg:CC FLAGS_REG))])]
20523   ""
20524   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20525               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20526   "")
20527
20528 ;; Two pops case is tricky, since pop causes dependency on destination register.
20529 ;; We use two registers if available.
20530 (define_peephole2
20531   [(match_scratch:DI 0 "r")
20532    (match_scratch:DI 1 "r")
20533    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20534               (clobber (reg:CC FLAGS_REG))])]
20535   ""
20536   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20537               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20538    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20539               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20540   "")
20541
20542 (define_peephole2
20543   [(match_scratch:DI 0 "r")
20544    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20545               (clobber (reg:CC FLAGS_REG))])]
20546   "optimize_size"
20547   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20548               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20549    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20550               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20551   "")
20552 \f
20553 ;; Convert imul by three, five and nine into lea
20554 (define_peephole2
20555   [(parallel
20556     [(set (match_operand:SI 0 "register_operand" "")
20557           (mult:SI (match_operand:SI 1 "register_operand" "")
20558                    (match_operand:SI 2 "const_int_operand" "")))
20559      (clobber (reg:CC FLAGS_REG))])]
20560   "INTVAL (operands[2]) == 3
20561    || INTVAL (operands[2]) == 5
20562    || INTVAL (operands[2]) == 9"
20563   [(set (match_dup 0)
20564         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20565                  (match_dup 1)))]
20566   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20567
20568 (define_peephole2
20569   [(parallel
20570     [(set (match_operand:SI 0 "register_operand" "")
20571           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20572                    (match_operand:SI 2 "const_int_operand" "")))
20573      (clobber (reg:CC FLAGS_REG))])]
20574   "!optimize_size
20575    && (INTVAL (operands[2]) == 3
20576        || INTVAL (operands[2]) == 5
20577        || INTVAL (operands[2]) == 9)"
20578   [(set (match_dup 0) (match_dup 1))
20579    (set (match_dup 0)
20580         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20581                  (match_dup 0)))]
20582   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20583
20584 (define_peephole2
20585   [(parallel
20586     [(set (match_operand:DI 0 "register_operand" "")
20587           (mult:DI (match_operand:DI 1 "register_operand" "")
20588                    (match_operand:DI 2 "const_int_operand" "")))
20589      (clobber (reg:CC FLAGS_REG))])]
20590   "TARGET_64BIT
20591    && (INTVAL (operands[2]) == 3
20592        || INTVAL (operands[2]) == 5
20593        || INTVAL (operands[2]) == 9)"
20594   [(set (match_dup 0)
20595         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20596                  (match_dup 1)))]
20597   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20598
20599 (define_peephole2
20600   [(parallel
20601     [(set (match_operand:DI 0 "register_operand" "")
20602           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20603                    (match_operand:DI 2 "const_int_operand" "")))
20604      (clobber (reg:CC FLAGS_REG))])]
20605   "TARGET_64BIT
20606    && !optimize_size
20607    && (INTVAL (operands[2]) == 3
20608        || INTVAL (operands[2]) == 5
20609        || INTVAL (operands[2]) == 9)"
20610   [(set (match_dup 0) (match_dup 1))
20611    (set (match_dup 0)
20612         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20613                  (match_dup 0)))]
20614   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20615
20616 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20617 ;; imul $32bit_imm, reg, reg is direct decoded.
20618 (define_peephole2
20619   [(match_scratch:DI 3 "r")
20620    (parallel [(set (match_operand:DI 0 "register_operand" "")
20621                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20622                             (match_operand:DI 2 "immediate_operand" "")))
20623               (clobber (reg:CC FLAGS_REG))])]
20624   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20625    && !satisfies_constraint_K (operands[2])"
20626   [(set (match_dup 3) (match_dup 1))
20627    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20628               (clobber (reg:CC FLAGS_REG))])]
20629 "")
20630
20631 (define_peephole2
20632   [(match_scratch:SI 3 "r")
20633    (parallel [(set (match_operand:SI 0 "register_operand" "")
20634                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20635                             (match_operand:SI 2 "immediate_operand" "")))
20636               (clobber (reg:CC FLAGS_REG))])]
20637   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20638    && !satisfies_constraint_K (operands[2])"
20639   [(set (match_dup 3) (match_dup 1))
20640    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20641               (clobber (reg:CC FLAGS_REG))])]
20642 "")
20643
20644 (define_peephole2
20645   [(match_scratch:SI 3 "r")
20646    (parallel [(set (match_operand:DI 0 "register_operand" "")
20647                    (zero_extend:DI
20648                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20649                               (match_operand:SI 2 "immediate_operand" ""))))
20650               (clobber (reg:CC FLAGS_REG))])]
20651   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20652    && !satisfies_constraint_K (operands[2])"
20653   [(set (match_dup 3) (match_dup 1))
20654    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20655               (clobber (reg:CC FLAGS_REG))])]
20656 "")
20657
20658 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20659 ;; Convert it into imul reg, reg
20660 ;; It would be better to force assembler to encode instruction using long
20661 ;; immediate, but there is apparently no way to do so.
20662 (define_peephole2
20663   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20664                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20665                             (match_operand:DI 2 "const_int_operand" "")))
20666               (clobber (reg:CC FLAGS_REG))])
20667    (match_scratch:DI 3 "r")]
20668   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20669    && satisfies_constraint_K (operands[2])"
20670   [(set (match_dup 3) (match_dup 2))
20671    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20672               (clobber (reg:CC FLAGS_REG))])]
20673 {
20674   if (!rtx_equal_p (operands[0], operands[1]))
20675     emit_move_insn (operands[0], operands[1]);
20676 })
20677
20678 (define_peephole2
20679   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20680                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20681                             (match_operand:SI 2 "const_int_operand" "")))
20682               (clobber (reg:CC FLAGS_REG))])
20683    (match_scratch:SI 3 "r")]
20684   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20685    && satisfies_constraint_K (operands[2])"
20686   [(set (match_dup 3) (match_dup 2))
20687    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20688               (clobber (reg:CC FLAGS_REG))])]
20689 {
20690   if (!rtx_equal_p (operands[0], operands[1]))
20691     emit_move_insn (operands[0], operands[1]);
20692 })
20693
20694 (define_peephole2
20695   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20696                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20697                             (match_operand:HI 2 "immediate_operand" "")))
20698               (clobber (reg:CC FLAGS_REG))])
20699    (match_scratch:HI 3 "r")]
20700   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size"
20701   [(set (match_dup 3) (match_dup 2))
20702    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20703               (clobber (reg:CC FLAGS_REG))])]
20704 {
20705   if (!rtx_equal_p (operands[0], operands[1]))
20706     emit_move_insn (operands[0], operands[1]);
20707 })
20708
20709 ;; After splitting up read-modify operations, array accesses with memory
20710 ;; operands might end up in form:
20711 ;;  sall    $2, %eax
20712 ;;  movl    4(%esp), %edx
20713 ;;  addl    %edx, %eax
20714 ;; instead of pre-splitting:
20715 ;;  sall    $2, %eax
20716 ;;  addl    4(%esp), %eax
20717 ;; Turn it into:
20718 ;;  movl    4(%esp), %edx
20719 ;;  leal    (%edx,%eax,4), %eax
20720
20721 (define_peephole2
20722   [(parallel [(set (match_operand 0 "register_operand" "")
20723                    (ashift (match_operand 1 "register_operand" "")
20724                            (match_operand 2 "const_int_operand" "")))
20725                (clobber (reg:CC FLAGS_REG))])
20726    (set (match_operand 3 "register_operand")
20727         (match_operand 4 "x86_64_general_operand" ""))
20728    (parallel [(set (match_operand 5 "register_operand" "")
20729                    (plus (match_operand 6 "register_operand" "")
20730                          (match_operand 7 "register_operand" "")))
20731                    (clobber (reg:CC FLAGS_REG))])]
20732   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20733    /* Validate MODE for lea.  */
20734    && ((!TARGET_PARTIAL_REG_STALL
20735         && (GET_MODE (operands[0]) == QImode
20736             || GET_MODE (operands[0]) == HImode))
20737        || GET_MODE (operands[0]) == SImode
20738        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20739    /* We reorder load and the shift.  */
20740    && !rtx_equal_p (operands[1], operands[3])
20741    && !reg_overlap_mentioned_p (operands[0], operands[4])
20742    /* Last PLUS must consist of operand 0 and 3.  */
20743    && !rtx_equal_p (operands[0], operands[3])
20744    && (rtx_equal_p (operands[3], operands[6])
20745        || rtx_equal_p (operands[3], operands[7]))
20746    && (rtx_equal_p (operands[0], operands[6])
20747        || rtx_equal_p (operands[0], operands[7]))
20748    /* The intermediate operand 0 must die or be same as output.  */
20749    && (rtx_equal_p (operands[0], operands[5])
20750        || peep2_reg_dead_p (3, operands[0]))"
20751   [(set (match_dup 3) (match_dup 4))
20752    (set (match_dup 0) (match_dup 1))]
20753 {
20754   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20755   int scale = 1 << INTVAL (operands[2]);
20756   rtx index = gen_lowpart (Pmode, operands[1]);
20757   rtx base = gen_lowpart (Pmode, operands[3]);
20758   rtx dest = gen_lowpart (mode, operands[5]);
20759
20760   operands[1] = gen_rtx_PLUS (Pmode, base,
20761                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20762   if (mode != Pmode)
20763     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20764   operands[0] = dest;
20765 })
20766 \f
20767 ;; Call-value patterns last so that the wildcard operand does not
20768 ;; disrupt insn-recog's switch tables.
20769
20770 (define_insn "*call_value_pop_0"
20771   [(set (match_operand 0 "" "")
20772         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20773               (match_operand:SI 2 "" "")))
20774    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20775                             (match_operand:SI 3 "immediate_operand" "")))]
20776   "!TARGET_64BIT"
20777 {
20778   if (SIBLING_CALL_P (insn))
20779     return "jmp\t%P1";
20780   else
20781     return "call\t%P1";
20782 }
20783   [(set_attr "type" "callv")])
20784
20785 (define_insn "*call_value_pop_1"
20786   [(set (match_operand 0 "" "")
20787         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20788               (match_operand:SI 2 "" "")))
20789    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20790                             (match_operand:SI 3 "immediate_operand" "i")))]
20791   "!TARGET_64BIT"
20792 {
20793   if (constant_call_address_operand (operands[1], Pmode))
20794     {
20795       if (SIBLING_CALL_P (insn))
20796         return "jmp\t%P1";
20797       else
20798         return "call\t%P1";
20799     }
20800   if (SIBLING_CALL_P (insn))
20801     return "jmp\t%A1";
20802   else
20803     return "call\t%A1";
20804 }
20805   [(set_attr "type" "callv")])
20806
20807 (define_insn "*call_value_0"
20808   [(set (match_operand 0 "" "")
20809         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20810               (match_operand:SI 2 "" "")))]
20811   "!TARGET_64BIT"
20812 {
20813   if (SIBLING_CALL_P (insn))
20814     return "jmp\t%P1";
20815   else
20816     return "call\t%P1";
20817 }
20818   [(set_attr "type" "callv")])
20819
20820 (define_insn "*call_value_0_rex64"
20821   [(set (match_operand 0 "" "")
20822         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20823               (match_operand:DI 2 "const_int_operand" "")))]
20824   "TARGET_64BIT"
20825 {
20826   if (SIBLING_CALL_P (insn))
20827     return "jmp\t%P1";
20828   else
20829     return "call\t%P1";
20830 }
20831   [(set_attr "type" "callv")])
20832
20833 (define_insn "*call_value_1"
20834   [(set (match_operand 0 "" "")
20835         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20836               (match_operand:SI 2 "" "")))]
20837   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20838 {
20839   if (constant_call_address_operand (operands[1], Pmode))
20840     return "call\t%P1";
20841   return "call\t%A1";
20842 }
20843   [(set_attr "type" "callv")])
20844
20845 (define_insn "*sibcall_value_1"
20846   [(set (match_operand 0 "" "")
20847         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20848               (match_operand:SI 2 "" "")))]
20849   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20850 {
20851   if (constant_call_address_operand (operands[1], Pmode))
20852     return "jmp\t%P1";
20853   return "jmp\t%A1";
20854 }
20855   [(set_attr "type" "callv")])
20856
20857 (define_insn "*call_value_1_rex64"
20858   [(set (match_operand 0 "" "")
20859         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20860               (match_operand:DI 2 "" "")))]
20861   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20862 {
20863   if (constant_call_address_operand (operands[1], Pmode))
20864     return "call\t%P1";
20865   return "call\t%A1";
20866 }
20867   [(set_attr "type" "callv")])
20868
20869 (define_insn "*sibcall_value_1_rex64"
20870   [(set (match_operand 0 "" "")
20871         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20872               (match_operand:DI 2 "" "")))]
20873   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20874   "jmp\t%P1"
20875   [(set_attr "type" "callv")])
20876
20877 (define_insn "*sibcall_value_1_rex64_v"
20878   [(set (match_operand 0 "" "")
20879         (call (mem:QI (reg:DI R11_REG))
20880               (match_operand:DI 1 "" "")))]
20881   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20882   "jmp\t*%%r11"
20883   [(set_attr "type" "callv")])
20884 \f
20885 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20886 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20887 ;; caught for use by garbage collectors and the like.  Using an insn that
20888 ;; maps to SIGILL makes it more likely the program will rightfully die.
20889 ;; Keeping with tradition, "6" is in honor of #UD.
20890 (define_insn "trap"
20891   [(trap_if (const_int 1) (const_int 6))]
20892   ""
20893   { return ASM_SHORT "0x0b0f"; }
20894   [(set_attr "length" "2")])
20895
20896 (define_expand "sse_prologue_save"
20897   [(parallel [(set (match_operand:BLK 0 "" "")
20898                    (unspec:BLK [(reg:DI 21)
20899                                 (reg:DI 22)
20900                                 (reg:DI 23)
20901                                 (reg:DI 24)
20902                                 (reg:DI 25)
20903                                 (reg:DI 26)
20904                                 (reg:DI 27)
20905                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20906               (use (match_operand:DI 1 "register_operand" ""))
20907               (use (match_operand:DI 2 "immediate_operand" ""))
20908               (use (label_ref:DI (match_operand 3 "" "")))])]
20909   "TARGET_64BIT"
20910   "")
20911
20912 (define_insn "*sse_prologue_save_insn"
20913   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20914                           (match_operand:DI 4 "const_int_operand" "n")))
20915         (unspec:BLK [(reg:DI 21)
20916                      (reg:DI 22)
20917                      (reg:DI 23)
20918                      (reg:DI 24)
20919                      (reg:DI 25)
20920                      (reg:DI 26)
20921                      (reg:DI 27)
20922                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20923    (use (match_operand:DI 1 "register_operand" "r"))
20924    (use (match_operand:DI 2 "const_int_operand" "i"))
20925    (use (label_ref:DI (match_operand 3 "" "X")))]
20926   "TARGET_64BIT
20927    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20928    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20929   "*
20930 {
20931   int i;
20932   operands[0] = gen_rtx_MEM (Pmode,
20933                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20934   output_asm_insn (\"jmp\\t%A1\", operands);
20935   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20936     {
20937       operands[4] = adjust_address (operands[0], DImode, i*16);
20938       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20939       PUT_MODE (operands[4], TImode);
20940       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20941         output_asm_insn (\"rex\", operands);
20942       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20943     }
20944   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20945                              CODE_LABEL_NUMBER (operands[3]));
20946   return \"\";
20947 }
20948   "
20949   [(set_attr "type" "other")
20950    (set_attr "length_immediate" "0")
20951    (set_attr "length_address" "0")
20952    (set_attr "length" "135")
20953    (set_attr "memory" "store")
20954    (set_attr "modrm" "0")
20955    (set_attr "mode" "DI")])
20956
20957 (define_expand "prefetch"
20958   [(prefetch (match_operand 0 "address_operand" "")
20959              (match_operand:SI 1 "const_int_operand" "")
20960              (match_operand:SI 2 "const_int_operand" ""))]
20961   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20962 {
20963   int rw = INTVAL (operands[1]);
20964   int locality = INTVAL (operands[2]);
20965
20966   gcc_assert (rw == 0 || rw == 1);
20967   gcc_assert (locality >= 0 && locality <= 3);
20968   gcc_assert (GET_MODE (operands[0]) == Pmode
20969               || GET_MODE (operands[0]) == VOIDmode);
20970
20971   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20972      supported by SSE counterpart or the SSE prefetch is not available
20973      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20974      of locality.  */
20975   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20976     operands[2] = GEN_INT (3);
20977   else
20978     operands[1] = const0_rtx;
20979 })
20980
20981 (define_insn "*prefetch_sse"
20982   [(prefetch (match_operand:SI 0 "address_operand" "p")
20983              (const_int 0)
20984              (match_operand:SI 1 "const_int_operand" ""))]
20985   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20986 {
20987   static const char * const patterns[4] = {
20988    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20989   };
20990
20991   int locality = INTVAL (operands[1]);
20992   gcc_assert (locality >= 0 && locality <= 3);
20993
20994   return patterns[locality];
20995 }
20996   [(set_attr "type" "sse")
20997    (set_attr "memory" "none")])
20998
20999 (define_insn "*prefetch_sse_rex"
21000   [(prefetch (match_operand:DI 0 "address_operand" "p")
21001              (const_int 0)
21002              (match_operand:SI 1 "const_int_operand" ""))]
21003   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21004 {
21005   static const char * const patterns[4] = {
21006    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21007   };
21008
21009   int locality = INTVAL (operands[1]);
21010   gcc_assert (locality >= 0 && locality <= 3);
21011
21012   return patterns[locality];
21013 }
21014   [(set_attr "type" "sse")
21015    (set_attr "memory" "none")])
21016
21017 (define_insn "*prefetch_3dnow"
21018   [(prefetch (match_operand:SI 0 "address_operand" "p")
21019              (match_operand:SI 1 "const_int_operand" "n")
21020              (const_int 3))]
21021   "TARGET_3DNOW && !TARGET_64BIT"
21022 {
21023   if (INTVAL (operands[1]) == 0)
21024     return "prefetch\t%a0";
21025   else
21026     return "prefetchw\t%a0";
21027 }
21028   [(set_attr "type" "mmx")
21029    (set_attr "memory" "none")])
21030
21031 (define_insn "*prefetch_3dnow_rex"
21032   [(prefetch (match_operand:DI 0 "address_operand" "p")
21033              (match_operand:SI 1 "const_int_operand" "n")
21034              (const_int 3))]
21035   "TARGET_3DNOW && TARGET_64BIT"
21036 {
21037   if (INTVAL (operands[1]) == 0)
21038     return "prefetch\t%a0";
21039   else
21040     return "prefetchw\t%a0";
21041 }
21042   [(set_attr "type" "mmx")
21043    (set_attr "memory" "none")])
21044
21045 (define_expand "stack_protect_set"
21046   [(match_operand 0 "memory_operand" "")
21047    (match_operand 1 "memory_operand" "")]
21048   ""
21049 {
21050 #ifdef TARGET_THREAD_SSP_OFFSET
21051   if (TARGET_64BIT)
21052     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21053                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21054   else
21055     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21056                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21057 #else
21058   if (TARGET_64BIT)
21059     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21060   else
21061     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21062 #endif
21063   DONE;
21064 })
21065
21066 (define_insn "stack_protect_set_si"
21067   [(set (match_operand:SI 0 "memory_operand" "=m")
21068         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21069    (set (match_scratch:SI 2 "=&r") (const_int 0))
21070    (clobber (reg:CC FLAGS_REG))]
21071   ""
21072   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21073   [(set_attr "type" "multi")])
21074
21075 (define_insn "stack_protect_set_di"
21076   [(set (match_operand:DI 0 "memory_operand" "=m")
21077         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21078    (set (match_scratch:DI 2 "=&r") (const_int 0))
21079    (clobber (reg:CC FLAGS_REG))]
21080   "TARGET_64BIT"
21081   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21082   [(set_attr "type" "multi")])
21083
21084 (define_insn "stack_tls_protect_set_si"
21085   [(set (match_operand:SI 0 "memory_operand" "=m")
21086         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21087    (set (match_scratch:SI 2 "=&r") (const_int 0))
21088    (clobber (reg:CC FLAGS_REG))]
21089   ""
21090   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21091   [(set_attr "type" "multi")])
21092
21093 (define_insn "stack_tls_protect_set_di"
21094   [(set (match_operand:DI 0 "memory_operand" "=m")
21095         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21096    (set (match_scratch:DI 2 "=&r") (const_int 0))
21097    (clobber (reg:CC FLAGS_REG))]
21098   "TARGET_64BIT"
21099   {
21100      /* The kernel uses a different segment register for performance reasons; a
21101         system call would not have to trash the userspace segment register,
21102         which would be expensive */
21103      if (ix86_cmodel != CM_KERNEL)
21104         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21105      else
21106         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21107   }
21108   [(set_attr "type" "multi")])
21109
21110 (define_expand "stack_protect_test"
21111   [(match_operand 0 "memory_operand" "")
21112    (match_operand 1 "memory_operand" "")
21113    (match_operand 2 "" "")]
21114   ""
21115 {
21116   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21117   ix86_compare_op0 = operands[0];
21118   ix86_compare_op1 = operands[1];
21119   ix86_compare_emitted = flags;
21120
21121 #ifdef TARGET_THREAD_SSP_OFFSET
21122   if (TARGET_64BIT)
21123     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21124                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21125   else
21126     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21127                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21128 #else
21129   if (TARGET_64BIT)
21130     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21131   else
21132     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21133 #endif
21134   emit_jump_insn (gen_beq (operands[2]));
21135   DONE;
21136 })
21137
21138 (define_insn "stack_protect_test_si"
21139   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21140         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21141                      (match_operand:SI 2 "memory_operand" "m")]
21142                     UNSPEC_SP_TEST))
21143    (clobber (match_scratch:SI 3 "=&r"))]
21144   ""
21145   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21146   [(set_attr "type" "multi")])
21147
21148 (define_insn "stack_protect_test_di"
21149   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21150         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21151                      (match_operand:DI 2 "memory_operand" "m")]
21152                     UNSPEC_SP_TEST))
21153    (clobber (match_scratch:DI 3 "=&r"))]
21154   "TARGET_64BIT"
21155   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21156   [(set_attr "type" "multi")])
21157
21158 (define_insn "stack_tls_protect_test_si"
21159   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21160         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21161                      (match_operand:SI 2 "const_int_operand" "i")]
21162                     UNSPEC_SP_TLS_TEST))
21163    (clobber (match_scratch:SI 3 "=r"))]
21164   ""
21165   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21166   [(set_attr "type" "multi")])
21167
21168 (define_insn "stack_tls_protect_test_di"
21169   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21170         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21171                      (match_operand:DI 2 "const_int_operand" "i")]
21172                     UNSPEC_SP_TLS_TEST))
21173    (clobber (match_scratch:DI 3 "=r"))]
21174   "TARGET_64BIT"
21175   {
21176      /* The kernel uses a different segment register for performance reasons; a
21177         system call would not have to trash the userspace segment register,
21178         which would be expensive */
21179      if (ix86_cmodel != CM_KERNEL)
21180         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21181      else
21182         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21183   }
21184   [(set_attr "type" "multi")])
21185
21186 (include "mmx.md")
21187 (include "sse.md")
21188 (include "sync.md")