OSDN Git Service

7dae8e1e0b75d7acf6ebd9aa97011a727b39613e
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.  */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; The special asm out single letter directives following a '%' are:
31 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
32 ;;     operands[1].
33 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
34 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
35 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
36 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
37 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
38 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
39 ;; 'J' Print the appropriate jump operand.
40 ;;
41 ;; 'b' Print the QImode name of the register for the indicated operand.
42 ;;     %b0 would print %al if operands[0] is reg 0.
43 ;; 'w' Likewise, print the HImode name of the register.
44 ;; 'k' Likewise, print the SImode name of the register.
45 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
46 ;; 'y' Print "st(0)" instead of "st" as a register.
47
48 ;; UNSPEC usage:
49
50 (define_constants
51   [; Relocation specifiers
52    (UNSPEC_GOT                  0)
53    (UNSPEC_GOTOFF               1)
54    (UNSPEC_GOTPCREL             2)
55    (UNSPEC_GOTTPOFF             3)
56    (UNSPEC_TPOFF                4)
57    (UNSPEC_NTPOFF               5)
58    (UNSPEC_DTPOFF               6)
59    (UNSPEC_GOTNTPOFF            7)
60    (UNSPEC_INDNTPOFF            8)
61
62    ; Prologue support
63    (UNSPEC_STACK_ALLOC          11)
64    (UNSPEC_SET_GOT              12)
65    (UNSPEC_SSE_PROLOGUE_SAVE    13)
66    (UNSPEC_REG_SAVE             14)
67    (UNSPEC_DEF_CFA              15)
68
69    ; TLS support
70    (UNSPEC_TP                   16)
71    (UNSPEC_TLS_GD               17)
72    (UNSPEC_TLS_LD_BASE          18)
73    (UNSPEC_TLSDESC              19)
74
75    ; Other random patterns
76    (UNSPEC_SCAS                 20)
77    (UNSPEC_FNSTSW               21)
78    (UNSPEC_SAHF                 22)
79    (UNSPEC_FSTCW                23)
80    (UNSPEC_ADD_CARRY            24)
81    (UNSPEC_FLDCW                25)
82    (UNSPEC_REP                  26)
83    (UNSPEC_EH_RETURN            27)
84    (UNSPEC_LD_MPIC              28)     ; load_macho_picbase
85    (UNSPEC_TRUNC_NOOP           29)
86
87    ; For SSE/MMX support:
88    (UNSPEC_FIX_NOTRUNC          30)
89    (UNSPEC_MASKMOV              31)
90    (UNSPEC_MOVMSK               32)
91    (UNSPEC_MOVNT                33)
92    (UNSPEC_MOVU                 34)
93    (UNSPEC_RCP                  35)
94    (UNSPEC_RSQRT                36)
95    (UNSPEC_SFENCE               37)
96    (UNSPEC_NOP                  38)     ; prevents combiner cleverness
97    (UNSPEC_PFRCP                39)
98    (UNSPEC_PFRCPIT1             40)
99    (UNSPEC_PFRCPIT2             41)
100    (UNSPEC_PFRSQRT              42)
101    (UNSPEC_PFRSQIT1             43)
102    (UNSPEC_MFENCE               44)
103    (UNSPEC_LFENCE               45)
104    (UNSPEC_PSADBW               46)
105    (UNSPEC_LDDQU                47)
106
107    ; Generic math support
108    (UNSPEC_COPYSIGN             50)
109    (UNSPEC_IEEE_MIN             51)     ; not commutative
110    (UNSPEC_IEEE_MAX             52)     ; not commutative
111
112    ; x87 Floating point
113    (UNSPEC_SIN                  60)
114    (UNSPEC_COS                  61)
115    (UNSPEC_FPATAN               62)
116    (UNSPEC_FYL2X                63)
117    (UNSPEC_FYL2XP1              64)
118    (UNSPEC_FRNDINT              65)
119    (UNSPEC_FIST                 66)
120    (UNSPEC_F2XM1                67)
121    (UNSPEC_TAN                  68)
122    (UNSPEC_FXAM                 69)
123
124    ; x87 Rounding
125    (UNSPEC_FRNDINT_FLOOR        70)
126    (UNSPEC_FRNDINT_CEIL         71)
127    (UNSPEC_FRNDINT_TRUNC        72)
128    (UNSPEC_FRNDINT_MASK_PM      73)
129    (UNSPEC_FIST_FLOOR           74)
130    (UNSPEC_FIST_CEIL            75)
131
132    ; x87 Double output FP
133    (UNSPEC_SINCOS_COS           80)
134    (UNSPEC_SINCOS_SIN           81)
135    (UNSPEC_XTRACT_FRACT         84)
136    (UNSPEC_XTRACT_EXP           85)
137    (UNSPEC_FSCALE_FRACT         86)
138    (UNSPEC_FSCALE_EXP           87)
139    (UNSPEC_FPREM_F              88)
140    (UNSPEC_FPREM_U              89)
141    (UNSPEC_FPREM1_F             90)
142    (UNSPEC_FPREM1_U             91)
143
144    ; SSP patterns
145    (UNSPEC_SP_SET               100)
146    (UNSPEC_SP_TEST              101)
147    (UNSPEC_SP_TLS_SET           102)
148    (UNSPEC_SP_TLS_TEST          103)
149
150    ; SSSE3
151    (UNSPEC_PSHUFB               120)
152    (UNSPEC_PSIGN                121)
153    (UNSPEC_PALIGNR              122)
154
155    ; For SSE4A support
156    (UNSPEC_EXTRQI               130)
157    (UNSPEC_EXTRQ                131)   
158    (UNSPEC_INSERTQI             132)
159    (UNSPEC_INSERTQ              133)
160   ])
161
162 (define_constants
163   [(UNSPECV_BLOCKAGE            0)
164    (UNSPECV_STACK_PROBE         1)
165    (UNSPECV_EMMS                2)
166    (UNSPECV_LDMXCSR             3)
167    (UNSPECV_STMXCSR             4)
168    (UNSPECV_FEMMS               5)
169    (UNSPECV_CLFLUSH             6)
170    (UNSPECV_ALIGN               7)
171    (UNSPECV_MONITOR             8)
172    (UNSPECV_MWAIT               9)
173    (UNSPECV_CMPXCHG_1           10)
174    (UNSPECV_CMPXCHG_2           11)
175    (UNSPECV_XCHG                12)
176    (UNSPECV_LOCK                13)
177   ])
178
179 ;; Registers by name.
180 (define_constants
181   [(BP_REG                       6)
182    (SP_REG                       7)
183    (FLAGS_REG                   17)
184    (FPSR_REG                    18)
185    (FPCR_REG                    19)
186    (R10_REG                     39)
187    (R11_REG                     40)
188   ])
189
190 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
191 ;; from i386.c.
192
193 ;; In C guard expressions, put expressions which may be compile-time
194 ;; constants first.  This allows for better optimization.  For
195 ;; example, write "TARGET_64BIT && reload_completed", not
196 ;; "reload_completed && TARGET_64BIT".
197
198 \f
199 ;; Processor type.  This attribute must exactly match the processor_type
200 ;; enumeration in i386.h.
201 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
202                     nocona,core2,generic32,generic64,amdfam10"
203   (const (symbol_ref "ix86_tune")))
204
205 ;; A basic instruction type.  Refinements due to arguments to be
206 ;; provided in other attributes.
207 (define_attr "type"
208   "other,multi,
209    alu,alu1,negnot,imov,imovx,lea,
210    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
211    icmp,test,ibr,setcc,icmov,
212    push,pop,call,callv,leave,
213    str,bitmanip,
214    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
215    sselog,sselog1,sseiadd,sseishft,sseimul,
216    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins,
217    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
218   (const_string "other"))
219
220 ;; Main data type used by the insn
221 (define_attr "mode"
222   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
223   (const_string "unknown"))
224
225 ;; The CPU unit operations uses.
226 (define_attr "unit" "integer,i387,sse,mmx,unknown"
227   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
228            (const_string "i387")
229          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
230                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins")
231            (const_string "sse")
232          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
233            (const_string "mmx")
234          (eq_attr "type" "other")
235            (const_string "unknown")]
236          (const_string "integer")))
237
238 ;; The (bounding maximum) length of an instruction immediate.
239 (define_attr "length_immediate" ""
240   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
241                           bitmanip")
242            (const_int 0)
243          (eq_attr "unit" "i387,sse,mmx")
244            (const_int 0)
245          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
246                           imul,icmp,push,pop")
247            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
248          (eq_attr "type" "imov,test")
249            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
250          (eq_attr "type" "call")
251            (if_then_else (match_operand 0 "constant_call_address_operand" "")
252              (const_int 4)
253              (const_int 0))
254          (eq_attr "type" "callv")
255            (if_then_else (match_operand 1 "constant_call_address_operand" "")
256              (const_int 4)
257              (const_int 0))
258          ;; We don't know the size before shorten_branches.  Expect
259          ;; the instruction to fit for better scheduling.
260          (eq_attr "type" "ibr")
261            (const_int 1)
262          ]
263          (symbol_ref "/* Update immediate_length and other attributes! */
264                       gcc_unreachable (),1")))
265
266 ;; The (bounding maximum) length of an instruction address.
267 (define_attr "length_address" ""
268   (cond [(eq_attr "type" "str,other,multi,fxch")
269            (const_int 0)
270          (and (eq_attr "type" "call")
271               (match_operand 0 "constant_call_address_operand" ""))
272              (const_int 0)
273          (and (eq_attr "type" "callv")
274               (match_operand 1 "constant_call_address_operand" ""))
275              (const_int 0)
276          ]
277          (symbol_ref "ix86_attr_length_address_default (insn)")))
278
279 ;; Set when length prefix is used.
280 (define_attr "prefix_data16" ""
281   (if_then_else (ior (eq_attr "mode" "HI")
282                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
283     (const_int 1)
284     (const_int 0)))
285
286 ;; Set when string REP prefix is used.
287 (define_attr "prefix_rep" ""
288   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
289     (const_int 1)
290     (const_int 0)))
291
292 ;; Set when 0f opcode prefix is used.
293 (define_attr "prefix_0f" ""
294   (if_then_else
295     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
296          (eq_attr "unit" "sse,mmx"))
297     (const_int 1)
298     (const_int 0)))
299
300 ;; Set when REX opcode prefix is used.
301 (define_attr "prefix_rex" ""
302   (cond [(and (eq_attr "mode" "DI")
303               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
304            (const_int 1)
305          (and (eq_attr "mode" "QI")
306               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
307                   (const_int 0)))
308            (const_int 1)
309          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
310              (const_int 0))
311            (const_int 1)
312         ]
313         (const_int 0)))
314
315 ;; Set when modrm byte is used.
316 (define_attr "modrm" ""
317   (cond [(eq_attr "type" "str,leave")
318            (const_int 0)
319          (eq_attr "unit" "i387")
320            (const_int 0)
321          (and (eq_attr "type" "incdec")
322               (ior (match_operand:SI 1 "register_operand" "")
323                    (match_operand:HI 1 "register_operand" "")))
324            (const_int 0)
325          (and (eq_attr "type" "push")
326               (not (match_operand 1 "memory_operand" "")))
327            (const_int 0)
328          (and (eq_attr "type" "pop")
329               (not (match_operand 0 "memory_operand" "")))
330            (const_int 0)
331          (and (eq_attr "type" "imov")
332               (ior (and (match_operand 0 "register_operand" "")
333                         (match_operand 1 "immediate_operand" ""))
334                    (ior (and (match_operand 0 "ax_reg_operand" "")
335                              (match_operand 1 "memory_displacement_only_operand" ""))
336                         (and (match_operand 0 "memory_displacement_only_operand" "")
337                              (match_operand 1 "ax_reg_operand" "")))))
338            (const_int 0)
339          (and (eq_attr "type" "call")
340               (match_operand 0 "constant_call_address_operand" ""))
341              (const_int 0)
342          (and (eq_attr "type" "callv")
343               (match_operand 1 "constant_call_address_operand" ""))
344              (const_int 0)
345          ]
346          (const_int 1)))
347
348 ;; The (bounding maximum) length of an instruction in bytes.
349 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
350 ;; Later we may want to split them and compute proper length as for
351 ;; other insns.
352 (define_attr "length" ""
353   (cond [(eq_attr "type" "other,multi,fistp,frndint")
354            (const_int 16)
355          (eq_attr "type" "fcmp")
356            (const_int 4)
357          (eq_attr "unit" "i387")
358            (plus (const_int 2)
359                  (plus (attr "prefix_data16")
360                        (attr "length_address")))]
361          (plus (plus (attr "modrm")
362                      (plus (attr "prefix_0f")
363                            (plus (attr "prefix_rex")
364                                  (const_int 1))))
365                (plus (attr "prefix_rep")
366                      (plus (attr "prefix_data16")
367                            (plus (attr "length_immediate")
368                                  (attr "length_address")))))))
369
370 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
371 ;; `store' if there is a simple memory reference therein, or `unknown'
372 ;; if the instruction is complex.
373
374 (define_attr "memory" "none,load,store,both,unknown"
375   (cond [(eq_attr "type" "other,multi,str")
376            (const_string "unknown")
377          (eq_attr "type" "lea,fcmov,fpspc")
378            (const_string "none")
379          (eq_attr "type" "fistp,leave")
380            (const_string "both")
381          (eq_attr "type" "frndint")
382            (const_string "load")
383          (eq_attr "type" "push")
384            (if_then_else (match_operand 1 "memory_operand" "")
385              (const_string "both")
386              (const_string "store"))
387          (eq_attr "type" "pop")
388            (if_then_else (match_operand 0 "memory_operand" "")
389              (const_string "both")
390              (const_string "load"))
391          (eq_attr "type" "setcc")
392            (if_then_else (match_operand 0 "memory_operand" "")
393              (const_string "store")
394              (const_string "none"))
395          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
396            (if_then_else (ior (match_operand 0 "memory_operand" "")
397                               (match_operand 1 "memory_operand" ""))
398              (const_string "load")
399              (const_string "none"))
400          (eq_attr "type" "ibr")
401            (if_then_else (match_operand 0 "memory_operand" "")
402              (const_string "load")
403              (const_string "none"))
404          (eq_attr "type" "call")
405            (if_then_else (match_operand 0 "constant_call_address_operand" "")
406              (const_string "none")
407              (const_string "load"))
408          (eq_attr "type" "callv")
409            (if_then_else (match_operand 1 "constant_call_address_operand" "")
410              (const_string "none")
411              (const_string "load"))
412          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
413               (match_operand 1 "memory_operand" ""))
414            (const_string "both")
415          (and (match_operand 0 "memory_operand" "")
416               (match_operand 1 "memory_operand" ""))
417            (const_string "both")
418          (match_operand 0 "memory_operand" "")
419            (const_string "store")
420          (match_operand 1 "memory_operand" "")
421            (const_string "load")
422          (and (eq_attr "type"
423                  "!alu1,negnot,ishift1,
424                    imov,imovx,icmp,test,bitmanip,
425                    fmov,fcmp,fsgn,
426                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
427                    mmx,mmxmov,mmxcmp,mmxcvt")
428               (match_operand 2 "memory_operand" ""))
429            (const_string "load")
430          (and (eq_attr "type" "icmov")
431               (match_operand 3 "memory_operand" ""))
432            (const_string "load")
433         ]
434         (const_string "none")))
435
436 ;; Indicates if an instruction has both an immediate and a displacement.
437
438 (define_attr "imm_disp" "false,true,unknown"
439   (cond [(eq_attr "type" "other,multi")
440            (const_string "unknown")
441          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
442               (and (match_operand 0 "memory_displacement_operand" "")
443                    (match_operand 1 "immediate_operand" "")))
444            (const_string "true")
445          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
446               (and (match_operand 0 "memory_displacement_operand" "")
447                    (match_operand 2 "immediate_operand" "")))
448            (const_string "true")
449         ]
450         (const_string "false")))
451
452 ;; Indicates if an FP operation has an integer source.
453
454 (define_attr "fp_int_src" "false,true"
455   (const_string "false"))
456
457 ;; Defines rounding mode of an FP operation.
458
459 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
460   (const_string "any"))
461
462 ;; Describe a user's asm statement.
463 (define_asm_attributes
464   [(set_attr "length" "128")
465    (set_attr "type" "multi")])
466
467 ;; All x87 floating point modes
468 (define_mode_macro X87MODEF [SF DF XF])
469
470 ;; x87 SFmode and DFMode floating point modes
471 (define_mode_macro X87MODEF12 [SF DF])
472
473 ;; All integer modes handled by x87 fisttp operator.
474 (define_mode_macro X87MODEI [HI SI DI])
475
476 ;; All integer modes handled by integer x87 operators.
477 (define_mode_macro X87MODEI12 [HI SI])
478
479 ;; All SSE floating point modes
480 (define_mode_macro SSEMODEF [SF DF])
481
482 ;; All integer modes handled by SSE cvtts?2si* operators.
483 (define_mode_macro SSEMODEI24 [SI DI])
484
485 ;; SSE asm suffix for floating point modes
486 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
487
488 ;; SSE vector mode corresponding to a scalar mode
489 (define_mode_attr ssevecmode
490   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
491 \f
492 ;; Scheduling descriptions
493
494 (include "pentium.md")
495 (include "ppro.md")
496 (include "k6.md")
497 (include "athlon.md")
498 (include "geode.md")
499
500 \f
501 ;; Operand and operator predicates and constraints
502
503 (include "predicates.md")
504 (include "constraints.md")
505
506 \f
507 ;; Compare instructions.
508
509 ;; All compare insns have expanders that save the operands away without
510 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
511 ;; after the cmp) will actually emit the cmpM.
512
513 (define_expand "cmpti"
514   [(set (reg:CC FLAGS_REG)
515         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
516                     (match_operand:TI 1 "x86_64_general_operand" "")))]
517   "TARGET_64BIT"
518 {
519   if (MEM_P (operands[0]) && MEM_P (operands[1]))
520     operands[0] = force_reg (TImode, operands[0]);
521   ix86_compare_op0 = operands[0];
522   ix86_compare_op1 = operands[1];
523   DONE;
524 })
525
526 (define_expand "cmpdi"
527   [(set (reg:CC FLAGS_REG)
528         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
529                     (match_operand:DI 1 "x86_64_general_operand" "")))]
530   ""
531 {
532   if (MEM_P (operands[0]) && MEM_P (operands[1]))
533     operands[0] = force_reg (DImode, operands[0]);
534   ix86_compare_op0 = operands[0];
535   ix86_compare_op1 = operands[1];
536   DONE;
537 })
538
539 (define_expand "cmpsi"
540   [(set (reg:CC FLAGS_REG)
541         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
542                     (match_operand:SI 1 "general_operand" "")))]
543   ""
544 {
545   if (MEM_P (operands[0]) && MEM_P (operands[1]))
546     operands[0] = force_reg (SImode, operands[0]);
547   ix86_compare_op0 = operands[0];
548   ix86_compare_op1 = operands[1];
549   DONE;
550 })
551
552 (define_expand "cmphi"
553   [(set (reg:CC FLAGS_REG)
554         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
555                     (match_operand:HI 1 "general_operand" "")))]
556   ""
557 {
558   if (MEM_P (operands[0]) && MEM_P (operands[1]))
559     operands[0] = force_reg (HImode, operands[0]);
560   ix86_compare_op0 = operands[0];
561   ix86_compare_op1 = operands[1];
562   DONE;
563 })
564
565 (define_expand "cmpqi"
566   [(set (reg:CC FLAGS_REG)
567         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
568                     (match_operand:QI 1 "general_operand" "")))]
569   "TARGET_QIMODE_MATH"
570 {
571   if (MEM_P (operands[0]) && MEM_P (operands[1]))
572     operands[0] = force_reg (QImode, operands[0]);
573   ix86_compare_op0 = operands[0];
574   ix86_compare_op1 = operands[1];
575   DONE;
576 })
577
578 (define_insn "cmpdi_ccno_1_rex64"
579   [(set (reg FLAGS_REG)
580         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
581                  (match_operand:DI 1 "const0_operand" "n,n")))]
582   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
583   "@
584    test{q}\t%0, %0
585    cmp{q}\t{%1, %0|%0, %1}"
586   [(set_attr "type" "test,icmp")
587    (set_attr "length_immediate" "0,1")
588    (set_attr "mode" "DI")])
589
590 (define_insn "*cmpdi_minus_1_rex64"
591   [(set (reg FLAGS_REG)
592         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
593                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
594                  (const_int 0)))]
595   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
596   "cmp{q}\t{%1, %0|%0, %1}"
597   [(set_attr "type" "icmp")
598    (set_attr "mode" "DI")])
599
600 (define_expand "cmpdi_1_rex64"
601   [(set (reg:CC FLAGS_REG)
602         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
603                     (match_operand:DI 1 "general_operand" "")))]
604   "TARGET_64BIT"
605   "")
606
607 (define_insn "cmpdi_1_insn_rex64"
608   [(set (reg FLAGS_REG)
609         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
610                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
611   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
612   "cmp{q}\t{%1, %0|%0, %1}"
613   [(set_attr "type" "icmp")
614    (set_attr "mode" "DI")])
615
616
617 (define_insn "*cmpsi_ccno_1"
618   [(set (reg FLAGS_REG)
619         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
620                  (match_operand:SI 1 "const0_operand" "n,n")))]
621   "ix86_match_ccmode (insn, CCNOmode)"
622   "@
623    test{l}\t%0, %0
624    cmp{l}\t{%1, %0|%0, %1}"
625   [(set_attr "type" "test,icmp")
626    (set_attr "length_immediate" "0,1")
627    (set_attr "mode" "SI")])
628
629 (define_insn "*cmpsi_minus_1"
630   [(set (reg FLAGS_REG)
631         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
632                            (match_operand:SI 1 "general_operand" "ri,mr"))
633                  (const_int 0)))]
634   "ix86_match_ccmode (insn, CCGOCmode)"
635   "cmp{l}\t{%1, %0|%0, %1}"
636   [(set_attr "type" "icmp")
637    (set_attr "mode" "SI")])
638
639 (define_expand "cmpsi_1"
640   [(set (reg:CC FLAGS_REG)
641         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
642                     (match_operand:SI 1 "general_operand" "ri,mr")))]
643   ""
644   "")
645
646 (define_insn "*cmpsi_1_insn"
647   [(set (reg FLAGS_REG)
648         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
649                  (match_operand:SI 1 "general_operand" "ri,mr")))]
650   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
651     && ix86_match_ccmode (insn, CCmode)"
652   "cmp{l}\t{%1, %0|%0, %1}"
653   [(set_attr "type" "icmp")
654    (set_attr "mode" "SI")])
655
656 (define_insn "*cmphi_ccno_1"
657   [(set (reg FLAGS_REG)
658         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
659                  (match_operand:HI 1 "const0_operand" "n,n")))]
660   "ix86_match_ccmode (insn, CCNOmode)"
661   "@
662    test{w}\t%0, %0
663    cmp{w}\t{%1, %0|%0, %1}"
664   [(set_attr "type" "test,icmp")
665    (set_attr "length_immediate" "0,1")
666    (set_attr "mode" "HI")])
667
668 (define_insn "*cmphi_minus_1"
669   [(set (reg FLAGS_REG)
670         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
671                            (match_operand:HI 1 "general_operand" "ri,mr"))
672                  (const_int 0)))]
673   "ix86_match_ccmode (insn, CCGOCmode)"
674   "cmp{w}\t{%1, %0|%0, %1}"
675   [(set_attr "type" "icmp")
676    (set_attr "mode" "HI")])
677
678 (define_insn "*cmphi_1"
679   [(set (reg FLAGS_REG)
680         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
681                  (match_operand:HI 1 "general_operand" "ri,mr")))]
682   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
683    && ix86_match_ccmode (insn, CCmode)"
684   "cmp{w}\t{%1, %0|%0, %1}"
685   [(set_attr "type" "icmp")
686    (set_attr "mode" "HI")])
687
688 (define_insn "*cmpqi_ccno_1"
689   [(set (reg FLAGS_REG)
690         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
691                  (match_operand:QI 1 "const0_operand" "n,n")))]
692   "ix86_match_ccmode (insn, CCNOmode)"
693   "@
694    test{b}\t%0, %0
695    cmp{b}\t{$0, %0|%0, 0}"
696   [(set_attr "type" "test,icmp")
697    (set_attr "length_immediate" "0,1")
698    (set_attr "mode" "QI")])
699
700 (define_insn "*cmpqi_1"
701   [(set (reg FLAGS_REG)
702         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
703                  (match_operand:QI 1 "general_operand" "qi,mq")))]
704   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
705     && ix86_match_ccmode (insn, CCmode)"
706   "cmp{b}\t{%1, %0|%0, %1}"
707   [(set_attr "type" "icmp")
708    (set_attr "mode" "QI")])
709
710 (define_insn "*cmpqi_minus_1"
711   [(set (reg FLAGS_REG)
712         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
713                            (match_operand:QI 1 "general_operand" "qi,mq"))
714                  (const_int 0)))]
715   "ix86_match_ccmode (insn, CCGOCmode)"
716   "cmp{b}\t{%1, %0|%0, %1}"
717   [(set_attr "type" "icmp")
718    (set_attr "mode" "QI")])
719
720 (define_insn "*cmpqi_ext_1"
721   [(set (reg FLAGS_REG)
722         (compare
723           (match_operand:QI 0 "general_operand" "Qm")
724           (subreg:QI
725             (zero_extract:SI
726               (match_operand 1 "ext_register_operand" "Q")
727               (const_int 8)
728               (const_int 8)) 0)))]
729   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
730   "cmp{b}\t{%h1, %0|%0, %h1}"
731   [(set_attr "type" "icmp")
732    (set_attr "mode" "QI")])
733
734 (define_insn "*cmpqi_ext_1_rex64"
735   [(set (reg FLAGS_REG)
736         (compare
737           (match_operand:QI 0 "register_operand" "Q")
738           (subreg:QI
739             (zero_extract:SI
740               (match_operand 1 "ext_register_operand" "Q")
741               (const_int 8)
742               (const_int 8)) 0)))]
743   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
744   "cmp{b}\t{%h1, %0|%0, %h1}"
745   [(set_attr "type" "icmp")
746    (set_attr "mode" "QI")])
747
748 (define_insn "*cmpqi_ext_2"
749   [(set (reg FLAGS_REG)
750         (compare
751           (subreg:QI
752             (zero_extract:SI
753               (match_operand 0 "ext_register_operand" "Q")
754               (const_int 8)
755               (const_int 8)) 0)
756           (match_operand:QI 1 "const0_operand" "n")))]
757   "ix86_match_ccmode (insn, CCNOmode)"
758   "test{b}\t%h0, %h0"
759   [(set_attr "type" "test")
760    (set_attr "length_immediate" "0")
761    (set_attr "mode" "QI")])
762
763 (define_expand "cmpqi_ext_3"
764   [(set (reg:CC FLAGS_REG)
765         (compare:CC
766           (subreg:QI
767             (zero_extract:SI
768               (match_operand 0 "ext_register_operand" "")
769               (const_int 8)
770               (const_int 8)) 0)
771           (match_operand:QI 1 "general_operand" "")))]
772   ""
773   "")
774
775 (define_insn "cmpqi_ext_3_insn"
776   [(set (reg FLAGS_REG)
777         (compare
778           (subreg:QI
779             (zero_extract:SI
780               (match_operand 0 "ext_register_operand" "Q")
781               (const_int 8)
782               (const_int 8)) 0)
783           (match_operand:QI 1 "general_operand" "Qmn")))]
784   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
785   "cmp{b}\t{%1, %h0|%h0, %1}"
786   [(set_attr "type" "icmp")
787    (set_attr "mode" "QI")])
788
789 (define_insn "cmpqi_ext_3_insn_rex64"
790   [(set (reg FLAGS_REG)
791         (compare
792           (subreg:QI
793             (zero_extract:SI
794               (match_operand 0 "ext_register_operand" "Q")
795               (const_int 8)
796               (const_int 8)) 0)
797           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
798   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
799   "cmp{b}\t{%1, %h0|%h0, %1}"
800   [(set_attr "type" "icmp")
801    (set_attr "mode" "QI")])
802
803 (define_insn "*cmpqi_ext_4"
804   [(set (reg FLAGS_REG)
805         (compare
806           (subreg:QI
807             (zero_extract:SI
808               (match_operand 0 "ext_register_operand" "Q")
809               (const_int 8)
810               (const_int 8)) 0)
811           (subreg:QI
812             (zero_extract:SI
813               (match_operand 1 "ext_register_operand" "Q")
814               (const_int 8)
815               (const_int 8)) 0)))]
816   "ix86_match_ccmode (insn, CCmode)"
817   "cmp{b}\t{%h1, %h0|%h0, %h1}"
818   [(set_attr "type" "icmp")
819    (set_attr "mode" "QI")])
820
821 ;; These implement float point compares.
822 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
823 ;; which would allow mix and match FP modes on the compares.  Which is what
824 ;; the old patterns did, but with many more of them.
825
826 (define_expand "cmpxf"
827   [(set (reg:CC FLAGS_REG)
828         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
829                     (match_operand:XF 1 "nonmemory_operand" "")))]
830   "TARGET_80387"
831 {
832   ix86_compare_op0 = operands[0];
833   ix86_compare_op1 = operands[1];
834   DONE;
835 })
836
837 (define_expand "cmpdf"
838   [(set (reg:CC FLAGS_REG)
839         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
840                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
841   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
842 {
843   ix86_compare_op0 = operands[0];
844   ix86_compare_op1 = operands[1];
845   DONE;
846 })
847
848 (define_expand "cmpsf"
849   [(set (reg:CC FLAGS_REG)
850         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
851                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
852   "TARGET_80387 || TARGET_SSE_MATH"
853 {
854   ix86_compare_op0 = operands[0];
855   ix86_compare_op1 = operands[1];
856   DONE;
857 })
858
859 ;; FP compares, step 1:
860 ;; Set the FP condition codes.
861 ;;
862 ;; CCFPmode     compare with exceptions
863 ;; CCFPUmode    compare with no exceptions
864
865 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
866 ;; used to manage the reg stack popping would not be preserved.
867
868 (define_insn "*cmpfp_0"
869   [(set (match_operand:HI 0 "register_operand" "=a")
870         (unspec:HI
871           [(compare:CCFP
872              (match_operand 1 "register_operand" "f")
873              (match_operand 2 "const0_operand" "X"))]
874         UNSPEC_FNSTSW))]
875   "TARGET_80387
876    && FLOAT_MODE_P (GET_MODE (operands[1]))
877    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
878   "* return output_fp_compare (insn, operands, 0, 0);"
879   [(set_attr "type" "multi")
880    (set_attr "unit" "i387")
881    (set (attr "mode")
882      (cond [(match_operand:SF 1 "" "")
883               (const_string "SF")
884             (match_operand:DF 1 "" "")
885               (const_string "DF")
886            ]
887            (const_string "XF")))])
888
889 (define_insn "*cmpfp_sf"
890   [(set (match_operand:HI 0 "register_operand" "=a")
891         (unspec:HI
892           [(compare:CCFP
893              (match_operand:SF 1 "register_operand" "f")
894              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
895           UNSPEC_FNSTSW))]
896   "TARGET_80387"
897   "* return output_fp_compare (insn, operands, 0, 0);"
898   [(set_attr "type" "multi")
899    (set_attr "unit" "i387")
900    (set_attr "mode" "SF")])
901
902 (define_insn "*cmpfp_df"
903   [(set (match_operand:HI 0 "register_operand" "=a")
904         (unspec:HI
905           [(compare:CCFP
906              (match_operand:DF 1 "register_operand" "f")
907              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
908           UNSPEC_FNSTSW))]
909   "TARGET_80387"
910   "* return output_fp_compare (insn, operands, 0, 0);"
911   [(set_attr "type" "multi")
912    (set_attr "unit" "i387")
913    (set_attr "mode" "DF")])
914
915 (define_insn "*cmpfp_xf"
916   [(set (match_operand:HI 0 "register_operand" "=a")
917         (unspec:HI
918           [(compare:CCFP
919              (match_operand:XF 1 "register_operand" "f")
920              (match_operand:XF 2 "register_operand" "f"))]
921           UNSPEC_FNSTSW))]
922   "TARGET_80387"
923   "* return output_fp_compare (insn, operands, 0, 0);"
924   [(set_attr "type" "multi")
925    (set_attr "unit" "i387")
926    (set_attr "mode" "XF")])
927
928 (define_insn "*cmpfp_u"
929   [(set (match_operand:HI 0 "register_operand" "=a")
930         (unspec:HI
931           [(compare:CCFPU
932              (match_operand 1 "register_operand" "f")
933              (match_operand 2 "register_operand" "f"))]
934           UNSPEC_FNSTSW))]
935   "TARGET_80387
936    && FLOAT_MODE_P (GET_MODE (operands[1]))
937    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
938   "* return output_fp_compare (insn, operands, 0, 1);"
939   [(set_attr "type" "multi")
940    (set_attr "unit" "i387")
941    (set (attr "mode")
942      (cond [(match_operand:SF 1 "" "")
943               (const_string "SF")
944             (match_operand:DF 1 "" "")
945               (const_string "DF")
946            ]
947            (const_string "XF")))])
948
949 (define_insn "*cmpfp_<mode>"
950   [(set (match_operand:HI 0 "register_operand" "=a")
951         (unspec:HI
952           [(compare:CCFP
953              (match_operand 1 "register_operand" "f")
954              (match_operator 3 "float_operator"
955                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
956           UNSPEC_FNSTSW))]
957   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
958    && FLOAT_MODE_P (GET_MODE (operands[1]))
959    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
960   "* return output_fp_compare (insn, operands, 0, 0);"
961   [(set_attr "type" "multi")
962    (set_attr "unit" "i387")
963    (set_attr "fp_int_src" "true")
964    (set_attr "mode" "<MODE>")])
965
966 ;; FP compares, step 2
967 ;; Move the fpsw to ax.
968
969 (define_insn "x86_fnstsw_1"
970   [(set (match_operand:HI 0 "register_operand" "=a")
971         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
972   "TARGET_80387"
973   "fnstsw\t%0"
974   [(set_attr "length" "2")
975    (set_attr "mode" "SI")
976    (set_attr "unit" "i387")])
977
978 ;; FP compares, step 3
979 ;; Get ax into flags, general case.
980
981 (define_insn "x86_sahf_1"
982   [(set (reg:CC FLAGS_REG)
983         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
984   "!TARGET_64BIT"
985   "sahf"
986   [(set_attr "length" "1")
987    (set_attr "athlon_decode" "vector")
988    (set_attr "amdfam10_decode" "direct")
989    (set_attr "mode" "SI")])
990
991 ;; Pentium Pro can do steps 1 through 3 in one go.
992 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes) 
993 (define_insn "*cmpfp_i_mixed"
994   [(set (reg:CCFP FLAGS_REG)
995         (compare:CCFP (match_operand 0 "register_operand" "f,x")
996                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
997   "TARGET_MIX_SSE_I387
998    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
999    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1000   "* return output_fp_compare (insn, operands, 1, 0);"
1001   [(set_attr "type" "fcmp,ssecomi")
1002    (set (attr "mode")
1003      (if_then_else (match_operand:SF 1 "" "")
1004         (const_string "SF")
1005         (const_string "DF")))
1006    (set_attr "athlon_decode" "vector")
1007    (set_attr "amdfam10_decode" "direct")])
1008
1009 (define_insn "*cmpfp_i_sse"
1010   [(set (reg:CCFP FLAGS_REG)
1011         (compare:CCFP (match_operand 0 "register_operand" "x")
1012                       (match_operand 1 "nonimmediate_operand" "xm")))]
1013   "TARGET_SSE_MATH
1014    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1015    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1016   "* return output_fp_compare (insn, operands, 1, 0);"
1017   [(set_attr "type" "ssecomi")
1018    (set (attr "mode")
1019      (if_then_else (match_operand:SF 1 "" "")
1020         (const_string "SF")
1021         (const_string "DF")))
1022    (set_attr "athlon_decode" "vector")
1023    (set_attr "amdfam10_decode" "direct")])
1024
1025 (define_insn "*cmpfp_i_i387"
1026   [(set (reg:CCFP FLAGS_REG)
1027         (compare:CCFP (match_operand 0 "register_operand" "f")
1028                       (match_operand 1 "register_operand" "f")))]
1029   "TARGET_80387 && TARGET_CMOVE
1030    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1031    && FLOAT_MODE_P (GET_MODE (operands[0]))
1032    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1033   "* return output_fp_compare (insn, operands, 1, 0);"
1034   [(set_attr "type" "fcmp")
1035    (set (attr "mode")
1036      (cond [(match_operand:SF 1 "" "")
1037               (const_string "SF")
1038             (match_operand:DF 1 "" "")
1039               (const_string "DF")
1040            ]
1041            (const_string "XF")))
1042    (set_attr "athlon_decode" "vector")
1043    (set_attr "amdfam10_decode" "direct")])
1044
1045 (define_insn "*cmpfp_iu_mixed"
1046   [(set (reg:CCFPU FLAGS_REG)
1047         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1048                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1049   "TARGET_MIX_SSE_I387
1050    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1051    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1052   "* return output_fp_compare (insn, operands, 1, 1);"
1053   [(set_attr "type" "fcmp,ssecomi")
1054    (set (attr "mode")
1055      (if_then_else (match_operand:SF 1 "" "")
1056         (const_string "SF")
1057         (const_string "DF")))
1058    (set_attr "athlon_decode" "vector")
1059    (set_attr "amdfam10_decode" "direct")])
1060
1061 (define_insn "*cmpfp_iu_sse"
1062   [(set (reg:CCFPU FLAGS_REG)
1063         (compare:CCFPU (match_operand 0 "register_operand" "x")
1064                        (match_operand 1 "nonimmediate_operand" "xm")))]
1065   "TARGET_SSE_MATH
1066    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1067    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1068   "* return output_fp_compare (insn, operands, 1, 1);"
1069   [(set_attr "type" "ssecomi")
1070    (set (attr "mode")
1071      (if_then_else (match_operand:SF 1 "" "")
1072         (const_string "SF")
1073         (const_string "DF")))
1074    (set_attr "athlon_decode" "vector")
1075    (set_attr "amdfam10_decode" "direct")])
1076
1077 (define_insn "*cmpfp_iu_387"
1078   [(set (reg:CCFPU FLAGS_REG)
1079         (compare:CCFPU (match_operand 0 "register_operand" "f")
1080                        (match_operand 1 "register_operand" "f")))]
1081   "TARGET_80387 && TARGET_CMOVE
1082    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1083    && FLOAT_MODE_P (GET_MODE (operands[0]))
1084    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1085   "* return output_fp_compare (insn, operands, 1, 1);"
1086   [(set_attr "type" "fcmp")
1087    (set (attr "mode")
1088      (cond [(match_operand:SF 1 "" "")
1089               (const_string "SF")
1090             (match_operand:DF 1 "" "")
1091               (const_string "DF")
1092            ]
1093            (const_string "XF")))
1094    (set_attr "athlon_decode" "vector")
1095    (set_attr "amdfam10_decode" "direct")])
1096 \f
1097 ;; Move instructions.
1098
1099 ;; General case of fullword move.
1100
1101 (define_expand "movsi"
1102   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1103         (match_operand:SI 1 "general_operand" ""))]
1104   ""
1105   "ix86_expand_move (SImode, operands); DONE;")
1106
1107 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1108 ;; general_operand.
1109 ;;
1110 ;; %%% We don't use a post-inc memory reference because x86 is not a
1111 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1112 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1113 ;; targets without our curiosities, and it is just as easy to represent
1114 ;; this differently.
1115
1116 (define_insn "*pushsi2"
1117   [(set (match_operand:SI 0 "push_operand" "=<")
1118         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1119   "!TARGET_64BIT"
1120   "push{l}\t%1"
1121   [(set_attr "type" "push")
1122    (set_attr "mode" "SI")])
1123
1124 ;; For 64BIT abi we always round up to 8 bytes.
1125 (define_insn "*pushsi2_rex64"
1126   [(set (match_operand:SI 0 "push_operand" "=X")
1127         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1128   "TARGET_64BIT"
1129   "push{q}\t%q1"
1130   [(set_attr "type" "push")
1131    (set_attr "mode" "SI")])
1132
1133 (define_insn "*pushsi2_prologue"
1134   [(set (match_operand:SI 0 "push_operand" "=<")
1135         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1136    (clobber (mem:BLK (scratch)))]
1137   "!TARGET_64BIT"
1138   "push{l}\t%1"
1139   [(set_attr "type" "push")
1140    (set_attr "mode" "SI")])
1141
1142 (define_insn "*popsi1_epilogue"
1143   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1144         (mem:SI (reg:SI SP_REG)))
1145    (set (reg:SI SP_REG)
1146         (plus:SI (reg:SI SP_REG) (const_int 4)))
1147    (clobber (mem:BLK (scratch)))]
1148   "!TARGET_64BIT"
1149   "pop{l}\t%0"
1150   [(set_attr "type" "pop")
1151    (set_attr "mode" "SI")])
1152
1153 (define_insn "popsi1"
1154   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1155         (mem:SI (reg:SI SP_REG)))
1156    (set (reg:SI SP_REG)
1157         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1158   "!TARGET_64BIT"
1159   "pop{l}\t%0"
1160   [(set_attr "type" "pop")
1161    (set_attr "mode" "SI")])
1162
1163 (define_insn "*movsi_xor"
1164   [(set (match_operand:SI 0 "register_operand" "=r")
1165         (match_operand:SI 1 "const0_operand" "i"))
1166    (clobber (reg:CC FLAGS_REG))]
1167   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1168   "xor{l}\t%0, %0"
1169   [(set_attr "type" "alu1")
1170    (set_attr "mode" "SI")
1171    (set_attr "length_immediate" "0")])
1172
1173 (define_insn "*movsi_or"
1174   [(set (match_operand:SI 0 "register_operand" "=r")
1175         (match_operand:SI 1 "immediate_operand" "i"))
1176    (clobber (reg:CC FLAGS_REG))]
1177   "reload_completed
1178    && operands[1] == constm1_rtx
1179    && (TARGET_PENTIUM || optimize_size)"
1180 {
1181   operands[1] = constm1_rtx;
1182   return "or{l}\t{%1, %0|%0, %1}";
1183 }
1184   [(set_attr "type" "alu1")
1185    (set_attr "mode" "SI")
1186    (set_attr "length_immediate" "1")])
1187
1188 (define_insn "*movsi_1"
1189   [(set (match_operand:SI 0 "nonimmediate_operand"
1190                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1191         (match_operand:SI 1 "general_operand"
1192                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1193   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1194 {
1195   switch (get_attr_type (insn))
1196     {
1197     case TYPE_SSELOG1:
1198       if (get_attr_mode (insn) == MODE_TI)
1199         return "pxor\t%0, %0";
1200       return "xorps\t%0, %0";
1201
1202     case TYPE_SSEMOV:
1203       switch (get_attr_mode (insn))
1204         {
1205         case MODE_TI:
1206           return "movdqa\t{%1, %0|%0, %1}";
1207         case MODE_V4SF:
1208           return "movaps\t{%1, %0|%0, %1}";
1209         case MODE_SI:
1210           return "movd\t{%1, %0|%0, %1}";
1211         case MODE_SF:
1212           return "movss\t{%1, %0|%0, %1}";
1213         default:
1214           gcc_unreachable ();
1215         }
1216
1217     case TYPE_MMXADD:
1218       return "pxor\t%0, %0";
1219
1220     case TYPE_MMXMOV:
1221       if (get_attr_mode (insn) == MODE_DI)
1222         return "movq\t{%1, %0|%0, %1}";
1223       return "movd\t{%1, %0|%0, %1}";
1224
1225     case TYPE_LEA:
1226       return "lea{l}\t{%1, %0|%0, %1}";
1227
1228     default:
1229       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1230       return "mov{l}\t{%1, %0|%0, %1}";
1231     }
1232 }
1233   [(set (attr "type")
1234      (cond [(eq_attr "alternative" "2")
1235               (const_string "mmxadd")
1236             (eq_attr "alternative" "3,4,5")
1237               (const_string "mmxmov")
1238             (eq_attr "alternative" "6")
1239               (const_string "sselog1")
1240             (eq_attr "alternative" "7,8,9,10,11")
1241               (const_string "ssemov")
1242             (match_operand:DI 1 "pic_32bit_operand" "")
1243               (const_string "lea")
1244            ]
1245            (const_string "imov")))
1246    (set (attr "mode")
1247      (cond [(eq_attr "alternative" "2,3")
1248               (const_string "DI")
1249             (eq_attr "alternative" "6,7")
1250               (if_then_else
1251                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1252                 (const_string "V4SF")
1253                 (const_string "TI"))
1254             (and (eq_attr "alternative" "8,9,10,11")
1255                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1256               (const_string "SF")
1257            ]
1258            (const_string "SI")))])
1259
1260 ;; Stores and loads of ax to arbitrary constant address.
1261 ;; We fake an second form of instruction to force reload to load address
1262 ;; into register when rax is not available
1263 (define_insn "*movabssi_1_rex64"
1264   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1265         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1266   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1267   "@
1268    movabs{l}\t{%1, %P0|%P0, %1}
1269    mov{l}\t{%1, %a0|%a0, %1}"
1270   [(set_attr "type" "imov")
1271    (set_attr "modrm" "0,*")
1272    (set_attr "length_address" "8,0")
1273    (set_attr "length_immediate" "0,*")
1274    (set_attr "memory" "store")
1275    (set_attr "mode" "SI")])
1276
1277 (define_insn "*movabssi_2_rex64"
1278   [(set (match_operand:SI 0 "register_operand" "=a,r")
1279         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1280   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1281   "@
1282    movabs{l}\t{%P1, %0|%0, %P1}
1283    mov{l}\t{%a1, %0|%0, %a1}"
1284   [(set_attr "type" "imov")
1285    (set_attr "modrm" "0,*")
1286    (set_attr "length_address" "8,0")
1287    (set_attr "length_immediate" "0")
1288    (set_attr "memory" "load")
1289    (set_attr "mode" "SI")])
1290
1291 (define_insn "*swapsi"
1292   [(set (match_operand:SI 0 "register_operand" "+r")
1293         (match_operand:SI 1 "register_operand" "+r"))
1294    (set (match_dup 1)
1295         (match_dup 0))]
1296   ""
1297   "xchg{l}\t%1, %0"
1298   [(set_attr "type" "imov")
1299    (set_attr "mode" "SI")
1300    (set_attr "pent_pair" "np")
1301    (set_attr "athlon_decode" "vector")
1302    (set_attr "amdfam10_decode" "double")])   
1303
1304 (define_expand "movhi"
1305   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1306         (match_operand:HI 1 "general_operand" ""))]
1307   ""
1308   "ix86_expand_move (HImode, operands); DONE;")
1309
1310 (define_insn "*pushhi2"
1311   [(set (match_operand:HI 0 "push_operand" "=X")
1312         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1313   "!TARGET_64BIT"
1314   "push{l}\t%k1"
1315   [(set_attr "type" "push")
1316    (set_attr "mode" "SI")])
1317
1318 ;; For 64BIT abi we always round up to 8 bytes.
1319 (define_insn "*pushhi2_rex64"
1320   [(set (match_operand:HI 0 "push_operand" "=X")
1321         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1322   "TARGET_64BIT"
1323   "push{q}\t%q1"
1324   [(set_attr "type" "push")
1325    (set_attr "mode" "DI")])
1326
1327 (define_insn "*movhi_1"
1328   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1329         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1330   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1331 {
1332   switch (get_attr_type (insn))
1333     {
1334     case TYPE_IMOVX:
1335       /* movzwl is faster than movw on p2 due to partial word stalls,
1336          though not as fast as an aligned movl.  */
1337       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1338     default:
1339       if (get_attr_mode (insn) == MODE_SI)
1340         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1341       else
1342         return "mov{w}\t{%1, %0|%0, %1}";
1343     }
1344 }
1345   [(set (attr "type")
1346      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1347               (const_string "imov")
1348             (and (eq_attr "alternative" "0")
1349                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1350                           (const_int 0))
1351                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1352                           (const_int 0))))
1353               (const_string "imov")
1354             (and (eq_attr "alternative" "1,2")
1355                  (match_operand:HI 1 "aligned_operand" ""))
1356               (const_string "imov")
1357             (and (ne (symbol_ref "TARGET_MOVX")
1358                      (const_int 0))
1359                  (eq_attr "alternative" "0,2"))
1360               (const_string "imovx")
1361            ]
1362            (const_string "imov")))
1363     (set (attr "mode")
1364       (cond [(eq_attr "type" "imovx")
1365                (const_string "SI")
1366              (and (eq_attr "alternative" "1,2")
1367                   (match_operand:HI 1 "aligned_operand" ""))
1368                (const_string "SI")
1369              (and (eq_attr "alternative" "0")
1370                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1371                            (const_int 0))
1372                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1373                            (const_int 0))))
1374                (const_string "SI")
1375             ]
1376             (const_string "HI")))])
1377
1378 ;; Stores and loads of ax to arbitrary constant address.
1379 ;; We fake an second form of instruction to force reload to load address
1380 ;; into register when rax is not available
1381 (define_insn "*movabshi_1_rex64"
1382   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1383         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1384   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1385   "@
1386    movabs{w}\t{%1, %P0|%P0, %1}
1387    mov{w}\t{%1, %a0|%a0, %1}"
1388   [(set_attr "type" "imov")
1389    (set_attr "modrm" "0,*")
1390    (set_attr "length_address" "8,0")
1391    (set_attr "length_immediate" "0,*")
1392    (set_attr "memory" "store")
1393    (set_attr "mode" "HI")])
1394
1395 (define_insn "*movabshi_2_rex64"
1396   [(set (match_operand:HI 0 "register_operand" "=a,r")
1397         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1398   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1399   "@
1400    movabs{w}\t{%P1, %0|%0, %P1}
1401    mov{w}\t{%a1, %0|%0, %a1}"
1402   [(set_attr "type" "imov")
1403    (set_attr "modrm" "0,*")
1404    (set_attr "length_address" "8,0")
1405    (set_attr "length_immediate" "0")
1406    (set_attr "memory" "load")
1407    (set_attr "mode" "HI")])
1408
1409 (define_insn "*swaphi_1"
1410   [(set (match_operand:HI 0 "register_operand" "+r")
1411         (match_operand:HI 1 "register_operand" "+r"))
1412    (set (match_dup 1)
1413         (match_dup 0))]
1414   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1415   "xchg{l}\t%k1, %k0"
1416   [(set_attr "type" "imov")
1417    (set_attr "mode" "SI")
1418    (set_attr "pent_pair" "np")
1419    (set_attr "athlon_decode" "vector")
1420    (set_attr "amdfam10_decode" "double")])   
1421
1422 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1423 (define_insn "*swaphi_2"
1424   [(set (match_operand:HI 0 "register_operand" "+r")
1425         (match_operand:HI 1 "register_operand" "+r"))
1426    (set (match_dup 1)
1427         (match_dup 0))]
1428   "TARGET_PARTIAL_REG_STALL"
1429   "xchg{w}\t%1, %0"
1430   [(set_attr "type" "imov")
1431    (set_attr "mode" "HI")
1432    (set_attr "pent_pair" "np")
1433    (set_attr "athlon_decode" "vector")])
1434
1435 (define_expand "movstricthi"
1436   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1437         (match_operand:HI 1 "general_operand" ""))]
1438   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1439 {
1440   /* Don't generate memory->memory moves, go through a register */
1441   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1442     operands[1] = force_reg (HImode, operands[1]);
1443 })
1444
1445 (define_insn "*movstricthi_1"
1446   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1447         (match_operand:HI 1 "general_operand" "rn,m"))]
1448   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1449    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1450   "mov{w}\t{%1, %0|%0, %1}"
1451   [(set_attr "type" "imov")
1452    (set_attr "mode" "HI")])
1453
1454 (define_insn "*movstricthi_xor"
1455   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1456         (match_operand:HI 1 "const0_operand" "i"))
1457    (clobber (reg:CC FLAGS_REG))]
1458   "reload_completed
1459    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1460   "xor{w}\t%0, %0"
1461   [(set_attr "type" "alu1")
1462    (set_attr "mode" "HI")
1463    (set_attr "length_immediate" "0")])
1464
1465 (define_expand "movqi"
1466   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1467         (match_operand:QI 1 "general_operand" ""))]
1468   ""
1469   "ix86_expand_move (QImode, operands); DONE;")
1470
1471 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1472 ;; "push a byte".  But actually we use pushl, which has the effect
1473 ;; of rounding the amount pushed up to a word.
1474
1475 (define_insn "*pushqi2"
1476   [(set (match_operand:QI 0 "push_operand" "=X")
1477         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1478   "!TARGET_64BIT"
1479   "push{l}\t%k1"
1480   [(set_attr "type" "push")
1481    (set_attr "mode" "SI")])
1482
1483 ;; For 64BIT abi we always round up to 8 bytes.
1484 (define_insn "*pushqi2_rex64"
1485   [(set (match_operand:QI 0 "push_operand" "=X")
1486         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1487   "TARGET_64BIT"
1488   "push{q}\t%q1"
1489   [(set_attr "type" "push")
1490    (set_attr "mode" "DI")])
1491
1492 ;; Situation is quite tricky about when to choose full sized (SImode) move
1493 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1494 ;; partial register dependency machines (such as AMD Athlon), where QImode
1495 ;; moves issue extra dependency and for partial register stalls machines
1496 ;; that don't use QImode patterns (and QImode move cause stall on the next
1497 ;; instruction).
1498 ;;
1499 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1500 ;; register stall machines with, where we use QImode instructions, since
1501 ;; partial register stall can be caused there.  Then we use movzx.
1502 (define_insn "*movqi_1"
1503   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1504         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1505   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1506 {
1507   switch (get_attr_type (insn))
1508     {
1509     case TYPE_IMOVX:
1510       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1511       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1512     default:
1513       if (get_attr_mode (insn) == MODE_SI)
1514         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1515       else
1516         return "mov{b}\t{%1, %0|%0, %1}";
1517     }
1518 }
1519   [(set (attr "type")
1520      (cond [(and (eq_attr "alternative" "5")
1521                  (not (match_operand:QI 1 "aligned_operand" "")))
1522               (const_string "imovx")
1523             (ne (symbol_ref "optimize_size") (const_int 0))
1524               (const_string "imov")
1525             (and (eq_attr "alternative" "3")
1526                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1527                           (const_int 0))
1528                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1529                           (const_int 0))))
1530               (const_string "imov")
1531             (eq_attr "alternative" "3,5")
1532               (const_string "imovx")
1533             (and (ne (symbol_ref "TARGET_MOVX")
1534                      (const_int 0))
1535                  (eq_attr "alternative" "2"))
1536               (const_string "imovx")
1537            ]
1538            (const_string "imov")))
1539    (set (attr "mode")
1540       (cond [(eq_attr "alternative" "3,4,5")
1541                (const_string "SI")
1542              (eq_attr "alternative" "6")
1543                (const_string "QI")
1544              (eq_attr "type" "imovx")
1545                (const_string "SI")
1546              (and (eq_attr "type" "imov")
1547                   (and (eq_attr "alternative" "0,1")
1548                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1549                                 (const_int 0))
1550                             (and (eq (symbol_ref "optimize_size")
1551                                      (const_int 0))
1552                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1553                                      (const_int 0))))))
1554                (const_string "SI")
1555              ;; Avoid partial register stalls when not using QImode arithmetic
1556              (and (eq_attr "type" "imov")
1557                   (and (eq_attr "alternative" "0,1")
1558                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1559                                 (const_int 0))
1560                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1561                                 (const_int 0)))))
1562                (const_string "SI")
1563            ]
1564            (const_string "QI")))])
1565
1566 (define_expand "reload_outqi"
1567   [(parallel [(match_operand:QI 0 "" "=m")
1568               (match_operand:QI 1 "register_operand" "r")
1569               (match_operand:QI 2 "register_operand" "=&q")])]
1570   ""
1571 {
1572   rtx op0, op1, op2;
1573   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1574
1575   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1576   if (! q_regs_operand (op1, QImode))
1577     {
1578       emit_insn (gen_movqi (op2, op1));
1579       op1 = op2;
1580     }
1581   emit_insn (gen_movqi (op0, op1));
1582   DONE;
1583 })
1584
1585 (define_insn "*swapqi_1"
1586   [(set (match_operand:QI 0 "register_operand" "+r")
1587         (match_operand:QI 1 "register_operand" "+r"))
1588    (set (match_dup 1)
1589         (match_dup 0))]
1590   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1591   "xchg{l}\t%k1, %k0"
1592   [(set_attr "type" "imov")
1593    (set_attr "mode" "SI")
1594    (set_attr "pent_pair" "np")
1595    (set_attr "athlon_decode" "vector")
1596    (set_attr "amdfam10_decode" "vector")])   
1597
1598 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1599 (define_insn "*swapqi_2"
1600   [(set (match_operand:QI 0 "register_operand" "+q")
1601         (match_operand:QI 1 "register_operand" "+q"))
1602    (set (match_dup 1)
1603         (match_dup 0))]
1604   "TARGET_PARTIAL_REG_STALL"
1605   "xchg{b}\t%1, %0"
1606   [(set_attr "type" "imov")
1607    (set_attr "mode" "QI")
1608    (set_attr "pent_pair" "np")
1609    (set_attr "athlon_decode" "vector")])
1610
1611 (define_expand "movstrictqi"
1612   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1613         (match_operand:QI 1 "general_operand" ""))]
1614   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1615 {
1616   /* Don't generate memory->memory moves, go through a register.  */
1617   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1618     operands[1] = force_reg (QImode, operands[1]);
1619 })
1620
1621 (define_insn "*movstrictqi_1"
1622   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1623         (match_operand:QI 1 "general_operand" "*qn,m"))]
1624   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1625    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1626   "mov{b}\t{%1, %0|%0, %1}"
1627   [(set_attr "type" "imov")
1628    (set_attr "mode" "QI")])
1629
1630 (define_insn "*movstrictqi_xor"
1631   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1632         (match_operand:QI 1 "const0_operand" "i"))
1633    (clobber (reg:CC FLAGS_REG))]
1634   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1635   "xor{b}\t%0, %0"
1636   [(set_attr "type" "alu1")
1637    (set_attr "mode" "QI")
1638    (set_attr "length_immediate" "0")])
1639
1640 (define_insn "*movsi_extv_1"
1641   [(set (match_operand:SI 0 "register_operand" "=R")
1642         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1643                          (const_int 8)
1644                          (const_int 8)))]
1645   ""
1646   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1647   [(set_attr "type" "imovx")
1648    (set_attr "mode" "SI")])
1649
1650 (define_insn "*movhi_extv_1"
1651   [(set (match_operand:HI 0 "register_operand" "=R")
1652         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1653                          (const_int 8)
1654                          (const_int 8)))]
1655   ""
1656   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1657   [(set_attr "type" "imovx")
1658    (set_attr "mode" "SI")])
1659
1660 (define_insn "*movqi_extv_1"
1661   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1662         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1663                          (const_int 8)
1664                          (const_int 8)))]
1665   "!TARGET_64BIT"
1666 {
1667   switch (get_attr_type (insn))
1668     {
1669     case TYPE_IMOVX:
1670       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1671     default:
1672       return "mov{b}\t{%h1, %0|%0, %h1}";
1673     }
1674 }
1675   [(set (attr "type")
1676      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1677                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1678                              (ne (symbol_ref "TARGET_MOVX")
1679                                  (const_int 0))))
1680         (const_string "imovx")
1681         (const_string "imov")))
1682    (set (attr "mode")
1683      (if_then_else (eq_attr "type" "imovx")
1684         (const_string "SI")
1685         (const_string "QI")))])
1686
1687 (define_insn "*movqi_extv_1_rex64"
1688   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1689         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1690                          (const_int 8)
1691                          (const_int 8)))]
1692   "TARGET_64BIT"
1693 {
1694   switch (get_attr_type (insn))
1695     {
1696     case TYPE_IMOVX:
1697       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1698     default:
1699       return "mov{b}\t{%h1, %0|%0, %h1}";
1700     }
1701 }
1702   [(set (attr "type")
1703      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1704                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1705                              (ne (symbol_ref "TARGET_MOVX")
1706                                  (const_int 0))))
1707         (const_string "imovx")
1708         (const_string "imov")))
1709    (set (attr "mode")
1710      (if_then_else (eq_attr "type" "imovx")
1711         (const_string "SI")
1712         (const_string "QI")))])
1713
1714 ;; Stores and loads of ax to arbitrary constant address.
1715 ;; We fake an second form of instruction to force reload to load address
1716 ;; into register when rax is not available
1717 (define_insn "*movabsqi_1_rex64"
1718   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1719         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1720   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1721   "@
1722    movabs{b}\t{%1, %P0|%P0, %1}
1723    mov{b}\t{%1, %a0|%a0, %1}"
1724   [(set_attr "type" "imov")
1725    (set_attr "modrm" "0,*")
1726    (set_attr "length_address" "8,0")
1727    (set_attr "length_immediate" "0,*")
1728    (set_attr "memory" "store")
1729    (set_attr "mode" "QI")])
1730
1731 (define_insn "*movabsqi_2_rex64"
1732   [(set (match_operand:QI 0 "register_operand" "=a,r")
1733         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1734   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1735   "@
1736    movabs{b}\t{%P1, %0|%0, %P1}
1737    mov{b}\t{%a1, %0|%0, %a1}"
1738   [(set_attr "type" "imov")
1739    (set_attr "modrm" "0,*")
1740    (set_attr "length_address" "8,0")
1741    (set_attr "length_immediate" "0")
1742    (set_attr "memory" "load")
1743    (set_attr "mode" "QI")])
1744
1745 (define_insn "*movdi_extzv_1"
1746   [(set (match_operand:DI 0 "register_operand" "=R")
1747         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1748                          (const_int 8)
1749                          (const_int 8)))]
1750   "TARGET_64BIT"
1751   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1752   [(set_attr "type" "imovx")
1753    (set_attr "mode" "DI")])
1754
1755 (define_insn "*movsi_extzv_1"
1756   [(set (match_operand:SI 0 "register_operand" "=R")
1757         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1758                          (const_int 8)
1759                          (const_int 8)))]
1760   ""
1761   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1762   [(set_attr "type" "imovx")
1763    (set_attr "mode" "SI")])
1764
1765 (define_insn "*movqi_extzv_2"
1766   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1767         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1768                                     (const_int 8)
1769                                     (const_int 8)) 0))]
1770   "!TARGET_64BIT"
1771 {
1772   switch (get_attr_type (insn))
1773     {
1774     case TYPE_IMOVX:
1775       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1776     default:
1777       return "mov{b}\t{%h1, %0|%0, %h1}";
1778     }
1779 }
1780   [(set (attr "type")
1781      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1782                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1783                              (ne (symbol_ref "TARGET_MOVX")
1784                                  (const_int 0))))
1785         (const_string "imovx")
1786         (const_string "imov")))
1787    (set (attr "mode")
1788      (if_then_else (eq_attr "type" "imovx")
1789         (const_string "SI")
1790         (const_string "QI")))])
1791
1792 (define_insn "*movqi_extzv_2_rex64"
1793   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1794         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1795                                     (const_int 8)
1796                                     (const_int 8)) 0))]
1797   "TARGET_64BIT"
1798 {
1799   switch (get_attr_type (insn))
1800     {
1801     case TYPE_IMOVX:
1802       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1803     default:
1804       return "mov{b}\t{%h1, %0|%0, %h1}";
1805     }
1806 }
1807   [(set (attr "type")
1808      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1809                         (ne (symbol_ref "TARGET_MOVX")
1810                             (const_int 0)))
1811         (const_string "imovx")
1812         (const_string "imov")))
1813    (set (attr "mode")
1814      (if_then_else (eq_attr "type" "imovx")
1815         (const_string "SI")
1816         (const_string "QI")))])
1817
1818 (define_insn "movsi_insv_1"
1819   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1820                          (const_int 8)
1821                          (const_int 8))
1822         (match_operand:SI 1 "general_operand" "Qmn"))]
1823   "!TARGET_64BIT"
1824   "mov{b}\t{%b1, %h0|%h0, %b1}"
1825   [(set_attr "type" "imov")
1826    (set_attr "mode" "QI")])
1827
1828 (define_insn "*movsi_insv_1_rex64"
1829   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1830                          (const_int 8)
1831                          (const_int 8))
1832         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1833   "TARGET_64BIT"
1834   "mov{b}\t{%b1, %h0|%h0, %b1}"
1835   [(set_attr "type" "imov")
1836    (set_attr "mode" "QI")])
1837
1838 (define_insn "movdi_insv_1_rex64"
1839   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1840                          (const_int 8)
1841                          (const_int 8))
1842         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1843   "TARGET_64BIT"
1844   "mov{b}\t{%b1, %h0|%h0, %b1}"
1845   [(set_attr "type" "imov")
1846    (set_attr "mode" "QI")])
1847
1848 (define_insn "*movqi_insv_2"
1849   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1850                          (const_int 8)
1851                          (const_int 8))
1852         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1853                      (const_int 8)))]
1854   ""
1855   "mov{b}\t{%h1, %h0|%h0, %h1}"
1856   [(set_attr "type" "imov")
1857    (set_attr "mode" "QI")])
1858
1859 (define_expand "movdi"
1860   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1861         (match_operand:DI 1 "general_operand" ""))]
1862   ""
1863   "ix86_expand_move (DImode, operands); DONE;")
1864
1865 (define_insn "*pushdi"
1866   [(set (match_operand:DI 0 "push_operand" "=<")
1867         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1868   "!TARGET_64BIT"
1869   "#")
1870
1871 (define_insn "*pushdi2_rex64"
1872   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1873         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1874   "TARGET_64BIT"
1875   "@
1876    push{q}\t%1
1877    #"
1878   [(set_attr "type" "push,multi")
1879    (set_attr "mode" "DI")])
1880
1881 ;; Convert impossible pushes of immediate to existing instructions.
1882 ;; First try to get scratch register and go through it.  In case this
1883 ;; fails, push sign extended lower part first and then overwrite
1884 ;; upper part by 32bit move.
1885 (define_peephole2
1886   [(match_scratch:DI 2 "r")
1887    (set (match_operand:DI 0 "push_operand" "")
1888         (match_operand:DI 1 "immediate_operand" ""))]
1889   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1890    && !x86_64_immediate_operand (operands[1], DImode)"
1891   [(set (match_dup 2) (match_dup 1))
1892    (set (match_dup 0) (match_dup 2))]
1893   "")
1894
1895 ;; We need to define this as both peepholer and splitter for case
1896 ;; peephole2 pass is not run.
1897 ;; "&& 1" is needed to keep it from matching the previous pattern.
1898 (define_peephole2
1899   [(set (match_operand:DI 0 "push_operand" "")
1900         (match_operand:DI 1 "immediate_operand" ""))]
1901   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1902    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1903   [(set (match_dup 0) (match_dup 1))
1904    (set (match_dup 2) (match_dup 3))]
1905   "split_di (operands + 1, 1, operands + 2, operands + 3);
1906    operands[1] = gen_lowpart (DImode, operands[2]);
1907    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1908                                                     GEN_INT (4)));
1909   ")
1910
1911 (define_split
1912   [(set (match_operand:DI 0 "push_operand" "")
1913         (match_operand:DI 1 "immediate_operand" ""))]
1914   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1915                     ? flow2_completed : reload_completed)
1916    && !symbolic_operand (operands[1], DImode)
1917    && !x86_64_immediate_operand (operands[1], DImode)"
1918   [(set (match_dup 0) (match_dup 1))
1919    (set (match_dup 2) (match_dup 3))]
1920   "split_di (operands + 1, 1, operands + 2, operands + 3);
1921    operands[1] = gen_lowpart (DImode, operands[2]);
1922    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1923                                                     GEN_INT (4)));
1924   ")
1925
1926 (define_insn "*pushdi2_prologue_rex64"
1927   [(set (match_operand:DI 0 "push_operand" "=<")
1928         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1929    (clobber (mem:BLK (scratch)))]
1930   "TARGET_64BIT"
1931   "push{q}\t%1"
1932   [(set_attr "type" "push")
1933    (set_attr "mode" "DI")])
1934
1935 (define_insn "*popdi1_epilogue_rex64"
1936   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1937         (mem:DI (reg:DI SP_REG)))
1938    (set (reg:DI SP_REG)
1939         (plus:DI (reg:DI SP_REG) (const_int 8)))
1940    (clobber (mem:BLK (scratch)))]
1941   "TARGET_64BIT"
1942   "pop{q}\t%0"
1943   [(set_attr "type" "pop")
1944    (set_attr "mode" "DI")])
1945
1946 (define_insn "popdi1"
1947   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1948         (mem:DI (reg:DI SP_REG)))
1949    (set (reg:DI SP_REG)
1950         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1951   "TARGET_64BIT"
1952   "pop{q}\t%0"
1953   [(set_attr "type" "pop")
1954    (set_attr "mode" "DI")])
1955
1956 (define_insn "*movdi_xor_rex64"
1957   [(set (match_operand:DI 0 "register_operand" "=r")
1958         (match_operand:DI 1 "const0_operand" "i"))
1959    (clobber (reg:CC FLAGS_REG))]
1960   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1961    && reload_completed"
1962   "xor{l}\t%k0, %k0";
1963   [(set_attr "type" "alu1")
1964    (set_attr "mode" "SI")
1965    (set_attr "length_immediate" "0")])
1966
1967 (define_insn "*movdi_or_rex64"
1968   [(set (match_operand:DI 0 "register_operand" "=r")
1969         (match_operand:DI 1 "const_int_operand" "i"))
1970    (clobber (reg:CC FLAGS_REG))]
1971   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1972    && reload_completed
1973    && operands[1] == constm1_rtx"
1974 {
1975   operands[1] = constm1_rtx;
1976   return "or{q}\t{%1, %0|%0, %1}";
1977 }
1978   [(set_attr "type" "alu1")
1979    (set_attr "mode" "DI")
1980    (set_attr "length_immediate" "1")])
1981
1982 (define_insn "*movdi_2"
1983   [(set (match_operand:DI 0 "nonimmediate_operand"
1984                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
1985         (match_operand:DI 1 "general_operand"
1986                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
1987   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1988   "@
1989    #
1990    #
1991    pxor\t%0, %0
1992    movq\t{%1, %0|%0, %1}
1993    movq\t{%1, %0|%0, %1}
1994    pxor\t%0, %0
1995    movq\t{%1, %0|%0, %1}
1996    movdqa\t{%1, %0|%0, %1}
1997    movq\t{%1, %0|%0, %1}
1998    xorps\t%0, %0
1999    movlps\t{%1, %0|%0, %1}
2000    movaps\t{%1, %0|%0, %1}
2001    movlps\t{%1, %0|%0, %1}"
2002   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2003    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2004
2005 (define_split
2006   [(set (match_operand:DI 0 "push_operand" "")
2007         (match_operand:DI 1 "general_operand" ""))]
2008   "!TARGET_64BIT && reload_completed
2009    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2010   [(const_int 0)]
2011   "ix86_split_long_move (operands); DONE;")
2012
2013 ;; %%% This multiword shite has got to go.
2014 (define_split
2015   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2016         (match_operand:DI 1 "general_operand" ""))]
2017   "!TARGET_64BIT && reload_completed
2018    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2019    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2020   [(const_int 0)]
2021   "ix86_split_long_move (operands); DONE;")
2022
2023 (define_insn "*movdi_1_rex64"
2024   [(set (match_operand:DI 0 "nonimmediate_operand"
2025           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2026         (match_operand:DI 1 "general_operand"
2027           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2028   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2029 {
2030   switch (get_attr_type (insn))
2031     {
2032     case TYPE_SSECVT:
2033       if (SSE_REG_P (operands[0]))
2034         return "movq2dq\t{%1, %0|%0, %1}";
2035       else
2036         return "movdq2q\t{%1, %0|%0, %1}";
2037
2038     case TYPE_SSEMOV:
2039       if (get_attr_mode (insn) == MODE_TI)
2040         return "movdqa\t{%1, %0|%0, %1}";
2041       /* FALLTHRU */
2042
2043     case TYPE_MMXMOV:
2044       /* Moves from and into integer register is done using movd
2045          opcode with REX prefix.  */
2046       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2047         return "movd\t{%1, %0|%0, %1}";
2048       return "movq\t{%1, %0|%0, %1}";
2049
2050     case TYPE_SSELOG1:
2051     case TYPE_MMXADD:
2052       return "pxor\t%0, %0";
2053
2054     case TYPE_MULTI:
2055       return "#";
2056
2057     case TYPE_LEA:
2058       return "lea{q}\t{%a1, %0|%0, %a1}";
2059
2060     default:
2061       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2062       if (get_attr_mode (insn) == MODE_SI)
2063         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2064       else if (which_alternative == 2)
2065         return "movabs{q}\t{%1, %0|%0, %1}";
2066       else
2067         return "mov{q}\t{%1, %0|%0, %1}";
2068     }
2069 }
2070   [(set (attr "type")
2071      (cond [(eq_attr "alternative" "5")
2072               (const_string "mmxadd")
2073             (eq_attr "alternative" "6,7,8,9,10")
2074               (const_string "mmxmov")
2075             (eq_attr "alternative" "11")
2076               (const_string "sselog1")
2077             (eq_attr "alternative" "12,13,14,15,16")
2078               (const_string "ssemov")
2079             (eq_attr "alternative" "17,18")
2080               (const_string "ssecvt")
2081             (eq_attr "alternative" "4")
2082               (const_string "multi")
2083             (match_operand:DI 1 "pic_32bit_operand" "")
2084               (const_string "lea")
2085            ]
2086            (const_string "imov")))
2087    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2088    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2089    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2090
2091 ;; Stores and loads of ax to arbitrary constant address.
2092 ;; We fake an second form of instruction to force reload to load address
2093 ;; into register when rax is not available
2094 (define_insn "*movabsdi_1_rex64"
2095   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2096         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2097   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2098   "@
2099    movabs{q}\t{%1, %P0|%P0, %1}
2100    mov{q}\t{%1, %a0|%a0, %1}"
2101   [(set_attr "type" "imov")
2102    (set_attr "modrm" "0,*")
2103    (set_attr "length_address" "8,0")
2104    (set_attr "length_immediate" "0,*")
2105    (set_attr "memory" "store")
2106    (set_attr "mode" "DI")])
2107
2108 (define_insn "*movabsdi_2_rex64"
2109   [(set (match_operand:DI 0 "register_operand" "=a,r")
2110         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2111   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2112   "@
2113    movabs{q}\t{%P1, %0|%0, %P1}
2114    mov{q}\t{%a1, %0|%0, %a1}"
2115   [(set_attr "type" "imov")
2116    (set_attr "modrm" "0,*")
2117    (set_attr "length_address" "8,0")
2118    (set_attr "length_immediate" "0")
2119    (set_attr "memory" "load")
2120    (set_attr "mode" "DI")])
2121
2122 ;; Convert impossible stores of immediate to existing instructions.
2123 ;; First try to get scratch register and go through it.  In case this
2124 ;; fails, move by 32bit parts.
2125 (define_peephole2
2126   [(match_scratch:DI 2 "r")
2127    (set (match_operand:DI 0 "memory_operand" "")
2128         (match_operand:DI 1 "immediate_operand" ""))]
2129   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2130    && !x86_64_immediate_operand (operands[1], DImode)"
2131   [(set (match_dup 2) (match_dup 1))
2132    (set (match_dup 0) (match_dup 2))]
2133   "")
2134
2135 ;; We need to define this as both peepholer and splitter for case
2136 ;; peephole2 pass is not run.
2137 ;; "&& 1" is needed to keep it from matching the previous pattern.
2138 (define_peephole2
2139   [(set (match_operand:DI 0 "memory_operand" "")
2140         (match_operand:DI 1 "immediate_operand" ""))]
2141   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2142    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2143   [(set (match_dup 2) (match_dup 3))
2144    (set (match_dup 4) (match_dup 5))]
2145   "split_di (operands, 2, operands + 2, operands + 4);")
2146
2147 (define_split
2148   [(set (match_operand:DI 0 "memory_operand" "")
2149         (match_operand:DI 1 "immediate_operand" ""))]
2150   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2151                     ? flow2_completed : reload_completed)
2152    && !symbolic_operand (operands[1], DImode)
2153    && !x86_64_immediate_operand (operands[1], DImode)"
2154   [(set (match_dup 2) (match_dup 3))
2155    (set (match_dup 4) (match_dup 5))]
2156   "split_di (operands, 2, operands + 2, operands + 4);")
2157
2158 (define_insn "*swapdi_rex64"
2159   [(set (match_operand:DI 0 "register_operand" "+r")
2160         (match_operand:DI 1 "register_operand" "+r"))
2161    (set (match_dup 1)
2162         (match_dup 0))]
2163   "TARGET_64BIT"
2164   "xchg{q}\t%1, %0"
2165   [(set_attr "type" "imov")
2166    (set_attr "mode" "DI")
2167    (set_attr "pent_pair" "np")
2168    (set_attr "athlon_decode" "vector")
2169    (set_attr "amdfam10_decode" "double")])   
2170
2171 (define_expand "movti"
2172   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2173         (match_operand:TI 1 "nonimmediate_operand" ""))]
2174   "TARGET_SSE || TARGET_64BIT"
2175 {
2176   if (TARGET_64BIT)
2177     ix86_expand_move (TImode, operands);
2178   else
2179     ix86_expand_vector_move (TImode, operands);
2180   DONE;
2181 })
2182
2183 (define_insn "*movti_internal"
2184   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2185         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2186   "TARGET_SSE && !TARGET_64BIT
2187    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2188 {
2189   switch (which_alternative)
2190     {
2191     case 0:
2192       if (get_attr_mode (insn) == MODE_V4SF)
2193         return "xorps\t%0, %0";
2194       else
2195         return "pxor\t%0, %0";
2196     case 1:
2197     case 2:
2198       if (get_attr_mode (insn) == MODE_V4SF)
2199         return "movaps\t{%1, %0|%0, %1}";
2200       else
2201         return "movdqa\t{%1, %0|%0, %1}";
2202     default:
2203       gcc_unreachable ();
2204     }
2205 }
2206   [(set_attr "type" "sselog1,ssemov,ssemov")
2207    (set (attr "mode")
2208         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2209                     (ne (symbol_ref "optimize_size") (const_int 0)))
2210                  (const_string "V4SF")
2211                (and (eq_attr "alternative" "2")
2212                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2213                         (const_int 0)))
2214                  (const_string "V4SF")]
2215               (const_string "TI")))])
2216
2217 (define_insn "*movti_rex64"
2218   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2219         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2220   "TARGET_64BIT
2221    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2222 {
2223   switch (which_alternative)
2224     {
2225     case 0:
2226     case 1:
2227       return "#";
2228     case 2:
2229       if (get_attr_mode (insn) == MODE_V4SF)
2230         return "xorps\t%0, %0";
2231       else
2232         return "pxor\t%0, %0";
2233     case 3:
2234     case 4:
2235       if (get_attr_mode (insn) == MODE_V4SF)
2236         return "movaps\t{%1, %0|%0, %1}";
2237       else
2238         return "movdqa\t{%1, %0|%0, %1}";
2239     default:
2240       gcc_unreachable ();
2241     }
2242 }
2243   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2244    (set (attr "mode")
2245         (cond [(eq_attr "alternative" "2,3")
2246                  (if_then_else
2247                    (ne (symbol_ref "optimize_size")
2248                        (const_int 0))
2249                    (const_string "V4SF")
2250                    (const_string "TI"))
2251                (eq_attr "alternative" "4")
2252                  (if_then_else
2253                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2254                             (const_int 0))
2255                         (ne (symbol_ref "optimize_size")
2256                             (const_int 0)))
2257                    (const_string "V4SF")
2258                    (const_string "TI"))]
2259                (const_string "DI")))])
2260
2261 (define_split
2262   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2263         (match_operand:TI 1 "general_operand" ""))]
2264   "reload_completed && !SSE_REG_P (operands[0])
2265    && !SSE_REG_P (operands[1])"
2266   [(const_int 0)]
2267   "ix86_split_long_move (operands); DONE;")
2268
2269 (define_expand "movsf"
2270   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2271         (match_operand:SF 1 "general_operand" ""))]
2272   ""
2273   "ix86_expand_move (SFmode, operands); DONE;")
2274
2275 (define_insn "*pushsf"
2276   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2277         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2278   "!TARGET_64BIT"
2279 {
2280   /* Anything else should be already split before reg-stack.  */
2281   gcc_assert (which_alternative == 1);
2282   return "push{l}\t%1";
2283 }
2284   [(set_attr "type" "multi,push,multi")
2285    (set_attr "unit" "i387,*,*")
2286    (set_attr "mode" "SF,SI,SF")])
2287
2288 (define_insn "*pushsf_rex64"
2289   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2290         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2291   "TARGET_64BIT"
2292 {
2293   /* Anything else should be already split before reg-stack.  */
2294   gcc_assert (which_alternative == 1);
2295   return "push{q}\t%q1";
2296 }
2297   [(set_attr "type" "multi,push,multi")
2298    (set_attr "unit" "i387,*,*")
2299    (set_attr "mode" "SF,DI,SF")])
2300
2301 (define_split
2302   [(set (match_operand:SF 0 "push_operand" "")
2303         (match_operand:SF 1 "memory_operand" ""))]
2304   "reload_completed
2305    && MEM_P (operands[1])
2306    && constant_pool_reference_p (operands[1])"
2307   [(set (match_dup 0)
2308         (match_dup 1))]
2309   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2310
2311
2312 ;; %%% Kill this when call knows how to work this out.
2313 (define_split
2314   [(set (match_operand:SF 0 "push_operand" "")
2315         (match_operand:SF 1 "any_fp_register_operand" ""))]
2316   "!TARGET_64BIT"
2317   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2318    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2319
2320 (define_split
2321   [(set (match_operand:SF 0 "push_operand" "")
2322         (match_operand:SF 1 "any_fp_register_operand" ""))]
2323   "TARGET_64BIT"
2324   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2325    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2326
2327 (define_insn "*movsf_1"
2328   [(set (match_operand:SF 0 "nonimmediate_operand"
2329           "=f,m,f,r  ,m ,x,x,x ,m,*y,m ,*y,Yi,r ,*Ym,r  ")
2330         (match_operand:SF 1 "general_operand"
2331           "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y,r ,Yi,r  ,*Ym"))]
2332   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2333    && (reload_in_progress || reload_completed
2334        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2335        || (!TARGET_SSE_MATH && optimize_size
2336            && standard_80387_constant_p (operands[1]))
2337        || GET_CODE (operands[1]) != CONST_DOUBLE
2338        || memory_operand (operands[0], SFmode))"
2339 {
2340   switch (which_alternative)
2341     {
2342     case 0:
2343       return output_387_reg_move (insn, operands);
2344
2345     case 1:
2346       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2347         return "fstp%z0\t%y0";
2348       else
2349         return "fst%z0\t%y0";
2350
2351     case 2:
2352       return standard_80387_constant_opcode (operands[1]);
2353
2354     case 3:
2355     case 4:
2356       return "mov{l}\t{%1, %0|%0, %1}";
2357     case 5:
2358       if (get_attr_mode (insn) == MODE_TI)
2359         return "pxor\t%0, %0";
2360       else
2361         return "xorps\t%0, %0";
2362     case 6:
2363       if (get_attr_mode (insn) == MODE_V4SF)
2364         return "movaps\t{%1, %0|%0, %1}";
2365       else
2366         return "movss\t{%1, %0|%0, %1}";
2367     case 7: case 8:
2368       return "movss\t{%1, %0|%0, %1}";
2369
2370     case 9: case 10:
2371     case 12: case 13: case 14: case 15:
2372       return "movd\t{%1, %0|%0, %1}";
2373
2374     case 11:
2375       return "movq\t{%1, %0|%0, %1}";
2376
2377     default:
2378       gcc_unreachable ();
2379     }
2380 }
2381   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2382    (set (attr "mode")
2383         (cond [(eq_attr "alternative" "3,4,9,10")
2384                  (const_string "SI")
2385                (eq_attr "alternative" "5")
2386                  (if_then_else
2387                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2388                                  (const_int 0))
2389                              (ne (symbol_ref "TARGET_SSE2")
2390                                  (const_int 0)))
2391                         (eq (symbol_ref "optimize_size")
2392                             (const_int 0)))
2393                    (const_string "TI")
2394                    (const_string "V4SF"))
2395                /* For architectures resolving dependencies on
2396                   whole SSE registers use APS move to break dependency
2397                   chains, otherwise use short move to avoid extra work.
2398
2399                   Do the same for architectures resolving dependencies on
2400                   the parts.  While in DF mode it is better to always handle
2401                   just register parts, the SF mode is different due to lack
2402                   of instructions to load just part of the register.  It is
2403                   better to maintain the whole registers in single format
2404                   to avoid problems on using packed logical operations.  */
2405                (eq_attr "alternative" "6")
2406                  (if_then_else
2407                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2408                             (const_int 0))
2409                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2410                             (const_int 0)))
2411                    (const_string "V4SF")
2412                    (const_string "SF"))
2413                (eq_attr "alternative" "11")
2414                  (const_string "DI")]
2415                (const_string "SF")))])
2416
2417 (define_insn "*swapsf"
2418   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2419         (match_operand:SF 1 "fp_register_operand" "+f"))
2420    (set (match_dup 1)
2421         (match_dup 0))]
2422   "reload_completed || TARGET_80387"
2423 {
2424   if (STACK_TOP_P (operands[0]))
2425     return "fxch\t%1";
2426   else
2427     return "fxch\t%0";
2428 }
2429   [(set_attr "type" "fxch")
2430    (set_attr "mode" "SF")])
2431
2432 (define_expand "movdf"
2433   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2434         (match_operand:DF 1 "general_operand" ""))]
2435   ""
2436   "ix86_expand_move (DFmode, operands); DONE;")
2437
2438 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2439 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2440 ;; On the average, pushdf using integers can be still shorter.  Allow this
2441 ;; pattern for optimize_size too.
2442
2443 (define_insn "*pushdf_nointeger"
2444   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2445         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2446   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2447 {
2448   /* This insn should be already split before reg-stack.  */
2449   gcc_unreachable ();
2450 }
2451   [(set_attr "type" "multi")
2452    (set_attr "unit" "i387,*,*,*")
2453    (set_attr "mode" "DF,SI,SI,DF")])
2454
2455 (define_insn "*pushdf_integer"
2456   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2457         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2458   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2459 {
2460   /* This insn should be already split before reg-stack.  */
2461   gcc_unreachable ();
2462 }
2463   [(set_attr "type" "multi")
2464    (set_attr "unit" "i387,*,*")
2465    (set_attr "mode" "DF,SI,DF")])
2466
2467 ;; %%% Kill this when call knows how to work this out.
2468 (define_split
2469   [(set (match_operand:DF 0 "push_operand" "")
2470         (match_operand:DF 1 "any_fp_register_operand" ""))]
2471   "!TARGET_64BIT && reload_completed"
2472   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2473    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2474   "")
2475
2476 (define_split
2477   [(set (match_operand:DF 0 "push_operand" "")
2478         (match_operand:DF 1 "any_fp_register_operand" ""))]
2479   "TARGET_64BIT && reload_completed"
2480   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2481    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2482   "")
2483
2484 (define_split
2485   [(set (match_operand:DF 0 "push_operand" "")
2486         (match_operand:DF 1 "general_operand" ""))]
2487   "reload_completed"
2488   [(const_int 0)]
2489   "ix86_split_long_move (operands); DONE;")
2490
2491 ;; Moving is usually shorter when only FP registers are used. This separate
2492 ;; movdf pattern avoids the use of integer registers for FP operations
2493 ;; when optimizing for size.
2494
2495 (define_insn "*movdf_nointeger"
2496   [(set (match_operand:DF 0 "nonimmediate_operand"
2497                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
2498         (match_operand:DF 1 "general_operand"
2499                         "fm,f,G,*roF,F*r,C   ,Y2*x,mY2*x,Y2*x"))]
2500   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2501    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2502    && (reload_in_progress || reload_completed
2503        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2504        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2505            && standard_80387_constant_p (operands[1]))
2506        || GET_CODE (operands[1]) != CONST_DOUBLE
2507        || memory_operand (operands[0], DFmode))"
2508 {
2509   switch (which_alternative)
2510     {
2511     case 0:
2512       return output_387_reg_move (insn, operands);
2513
2514     case 1:
2515       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2516         return "fstp%z0\t%y0";
2517       else
2518         return "fst%z0\t%y0";
2519
2520     case 2:
2521       return standard_80387_constant_opcode (operands[1]);
2522
2523     case 3:
2524     case 4:
2525       return "#";
2526     case 5:
2527       switch (get_attr_mode (insn))
2528         {
2529         case MODE_V4SF:
2530           return "xorps\t%0, %0";
2531         case MODE_V2DF:
2532           return "xorpd\t%0, %0";
2533         case MODE_TI:
2534           return "pxor\t%0, %0";
2535         default:
2536           gcc_unreachable ();
2537         }
2538     case 6:
2539     case 7:
2540     case 8:
2541       switch (get_attr_mode (insn))
2542         {
2543         case MODE_V4SF:
2544           return "movaps\t{%1, %0|%0, %1}";
2545         case MODE_V2DF:
2546           return "movapd\t{%1, %0|%0, %1}";
2547         case MODE_TI:
2548           return "movdqa\t{%1, %0|%0, %1}";
2549         case MODE_DI:
2550           return "movq\t{%1, %0|%0, %1}";
2551         case MODE_DF:
2552           return "movsd\t{%1, %0|%0, %1}";
2553         case MODE_V1DF:
2554           return "movlpd\t{%1, %0|%0, %1}";
2555         case MODE_V2SF:
2556           return "movlps\t{%1, %0|%0, %1}";
2557         default:
2558           gcc_unreachable ();
2559         }
2560
2561     default:
2562       gcc_unreachable ();
2563     }
2564 }
2565   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2566    (set (attr "mode")
2567         (cond [(eq_attr "alternative" "0,1,2")
2568                  (const_string "DF")
2569                (eq_attr "alternative" "3,4")
2570                  (const_string "SI")
2571
2572                /* For SSE1, we have many fewer alternatives.  */
2573                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2574                  (cond [(eq_attr "alternative" "5,6")
2575                           (const_string "V4SF")
2576                        ]
2577                    (const_string "V2SF"))
2578
2579                /* xorps is one byte shorter.  */
2580                (eq_attr "alternative" "5")
2581                  (cond [(ne (symbol_ref "optimize_size")
2582                             (const_int 0))
2583                           (const_string "V4SF")
2584                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2585                             (const_int 0))
2586                           (const_string "TI")
2587                        ]
2588                        (const_string "V2DF"))
2589
2590                /* For architectures resolving dependencies on
2591                   whole SSE registers use APD move to break dependency
2592                   chains, otherwise use short move to avoid extra work.
2593
2594                   movaps encodes one byte shorter.  */
2595                (eq_attr "alternative" "6")
2596                  (cond
2597                    [(ne (symbol_ref "optimize_size")
2598                         (const_int 0))
2599                       (const_string "V4SF")
2600                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2601                         (const_int 0))
2602                       (const_string "V2DF")
2603                    ]
2604                    (const_string "DF"))
2605                /* For architectures resolving dependencies on register
2606                   parts we may avoid extra work to zero out upper part
2607                   of register.  */
2608                (eq_attr "alternative" "7")
2609                  (if_then_else
2610                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2611                        (const_int 0))
2612                    (const_string "V1DF")
2613                    (const_string "DF"))
2614               ]
2615               (const_string "DF")))])
2616
2617 (define_insn "*movdf_integer_rex64"
2618   [(set (match_operand:DF 0 "nonimmediate_operand"
2619                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2620         (match_operand:DF 1 "general_operand"
2621                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2622   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2623    && (reload_in_progress || reload_completed
2624        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2625        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2626            && standard_80387_constant_p (operands[1]))
2627        || GET_CODE (operands[1]) != CONST_DOUBLE
2628        || memory_operand (operands[0], DFmode))"
2629 {
2630   switch (which_alternative)
2631     {
2632     case 0:
2633       return output_387_reg_move (insn, operands);
2634
2635     case 1:
2636       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2637         return "fstp%z0\t%y0";
2638       else
2639         return "fst%z0\t%y0";
2640
2641     case 2:
2642       return standard_80387_constant_opcode (operands[1]);
2643
2644     case 3:
2645     case 4:
2646       return "#";
2647
2648     case 5:
2649       switch (get_attr_mode (insn))
2650         {
2651         case MODE_V4SF:
2652           return "xorps\t%0, %0";
2653         case MODE_V2DF:
2654           return "xorpd\t%0, %0";
2655         case MODE_TI:
2656           return "pxor\t%0, %0";
2657         default:
2658           gcc_unreachable ();
2659         }
2660     case 6:
2661     case 7:
2662     case 8:
2663       switch (get_attr_mode (insn))
2664         {
2665         case MODE_V4SF:
2666           return "movaps\t{%1, %0|%0, %1}";
2667         case MODE_V2DF:
2668           return "movapd\t{%1, %0|%0, %1}";
2669         case MODE_TI:
2670           return "movdqa\t{%1, %0|%0, %1}";
2671         case MODE_DI:
2672           return "movq\t{%1, %0|%0, %1}";
2673         case MODE_DF:
2674           return "movsd\t{%1, %0|%0, %1}";
2675         case MODE_V1DF:
2676           return "movlpd\t{%1, %0|%0, %1}";
2677         case MODE_V2SF:
2678           return "movlps\t{%1, %0|%0, %1}";
2679         default:
2680           gcc_unreachable ();
2681         }
2682
2683     case 9:
2684     case 10:
2685       return "movd\t{%1, %0|%0, %1}";
2686
2687     default:
2688       gcc_unreachable();
2689     }
2690 }
2691   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2692    (set (attr "mode")
2693         (cond [(eq_attr "alternative" "0,1,2")
2694                  (const_string "DF")
2695                (eq_attr "alternative" "3,4,9,10")
2696                  (const_string "DI")
2697
2698                /* For SSE1, we have many fewer alternatives.  */
2699                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2700                  (cond [(eq_attr "alternative" "5,6")
2701                           (const_string "V4SF")
2702                        ]
2703                    (const_string "V2SF"))
2704
2705                /* xorps is one byte shorter.  */
2706                (eq_attr "alternative" "5")
2707                  (cond [(ne (symbol_ref "optimize_size")
2708                             (const_int 0))
2709                           (const_string "V4SF")
2710                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2711                             (const_int 0))
2712                           (const_string "TI")
2713                        ]
2714                        (const_string "V2DF"))
2715
2716                /* For architectures resolving dependencies on
2717                   whole SSE registers use APD move to break dependency
2718                   chains, otherwise use short move to avoid extra work.
2719
2720                   movaps encodes one byte shorter.  */
2721                (eq_attr "alternative" "6")
2722                  (cond
2723                    [(ne (symbol_ref "optimize_size")
2724                         (const_int 0))
2725                       (const_string "V4SF")
2726                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2727                         (const_int 0))
2728                       (const_string "V2DF")
2729                    ]
2730                    (const_string "DF"))
2731                /* For architectures resolving dependencies on register
2732                   parts we may avoid extra work to zero out upper part
2733                   of register.  */
2734                (eq_attr "alternative" "7")
2735                  (if_then_else
2736                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2737                        (const_int 0))
2738                    (const_string "V1DF")
2739                    (const_string "DF"))
2740               ]
2741               (const_string "DF")))])
2742
2743 (define_insn "*movdf_integer"
2744   [(set (match_operand:DF 0 "nonimmediate_operand"
2745                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
2746         (match_operand:DF 1 "general_operand"
2747                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
2748   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2749    && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2750    && (reload_in_progress || reload_completed
2751        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2752        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2753            && standard_80387_constant_p (operands[1]))
2754        || GET_CODE (operands[1]) != CONST_DOUBLE
2755        || memory_operand (operands[0], DFmode))"
2756 {
2757   switch (which_alternative)
2758     {
2759     case 0:
2760       return output_387_reg_move (insn, operands);
2761
2762     case 1:
2763       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2764         return "fstp%z0\t%y0";
2765       else
2766         return "fst%z0\t%y0";
2767
2768     case 2:
2769       return standard_80387_constant_opcode (operands[1]);
2770
2771     case 3:
2772     case 4:
2773       return "#";
2774
2775     case 5:
2776       switch (get_attr_mode (insn))
2777         {
2778         case MODE_V4SF:
2779           return "xorps\t%0, %0";
2780         case MODE_V2DF:
2781           return "xorpd\t%0, %0";
2782         case MODE_TI:
2783           return "pxor\t%0, %0";
2784         default:
2785           gcc_unreachable ();
2786         }
2787     case 6:
2788     case 7:
2789     case 8:
2790       switch (get_attr_mode (insn))
2791         {
2792         case MODE_V4SF:
2793           return "movaps\t{%1, %0|%0, %1}";
2794         case MODE_V2DF:
2795           return "movapd\t{%1, %0|%0, %1}";
2796         case MODE_TI:
2797           return "movdqa\t{%1, %0|%0, %1}";
2798         case MODE_DI:
2799           return "movq\t{%1, %0|%0, %1}";
2800         case MODE_DF:
2801           return "movsd\t{%1, %0|%0, %1}";
2802         case MODE_V1DF:
2803           return "movlpd\t{%1, %0|%0, %1}";
2804         case MODE_V2SF:
2805           return "movlps\t{%1, %0|%0, %1}";
2806         default:
2807           gcc_unreachable ();
2808         }
2809
2810     default:
2811       gcc_unreachable();
2812     }
2813 }
2814   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2815    (set (attr "mode")
2816         (cond [(eq_attr "alternative" "0,1,2")
2817                  (const_string "DF")
2818                (eq_attr "alternative" "3,4")
2819                  (const_string "SI")
2820
2821                /* For SSE1, we have many fewer alternatives.  */
2822                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2823                  (cond [(eq_attr "alternative" "5,6")
2824                           (const_string "V4SF")
2825                        ]
2826                    (const_string "V2SF"))
2827
2828                /* xorps is one byte shorter.  */
2829                (eq_attr "alternative" "5")
2830                  (cond [(ne (symbol_ref "optimize_size")
2831                             (const_int 0))
2832                           (const_string "V4SF")
2833                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2834                             (const_int 0))
2835                           (const_string "TI")
2836                        ]
2837                        (const_string "V2DF"))
2838
2839                /* For architectures resolving dependencies on
2840                   whole SSE registers use APD move to break dependency
2841                   chains, otherwise use short move to avoid extra work.
2842
2843                   movaps encodes one byte shorter.  */
2844                (eq_attr "alternative" "6")
2845                  (cond
2846                    [(ne (symbol_ref "optimize_size")
2847                         (const_int 0))
2848                       (const_string "V4SF")
2849                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2850                         (const_int 0))
2851                       (const_string "V2DF")
2852                    ]
2853                    (const_string "DF"))
2854                /* For architectures resolving dependencies on register
2855                   parts we may avoid extra work to zero out upper part
2856                   of register.  */
2857                (eq_attr "alternative" "7")
2858                  (if_then_else
2859                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2860                        (const_int 0))
2861                    (const_string "V1DF")
2862                    (const_string "DF"))
2863               ]
2864               (const_string "DF")))])
2865
2866 (define_split
2867   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2868         (match_operand:DF 1 "general_operand" ""))]
2869   "reload_completed
2870    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2871    && ! (ANY_FP_REG_P (operands[0]) ||
2872          (GET_CODE (operands[0]) == SUBREG
2873           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2874    && ! (ANY_FP_REG_P (operands[1]) ||
2875          (GET_CODE (operands[1]) == SUBREG
2876           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2877   [(const_int 0)]
2878   "ix86_split_long_move (operands); DONE;")
2879
2880 (define_insn "*swapdf"
2881   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2882         (match_operand:DF 1 "fp_register_operand" "+f"))
2883    (set (match_dup 1)
2884         (match_dup 0))]
2885   "reload_completed || TARGET_80387"
2886 {
2887   if (STACK_TOP_P (operands[0]))
2888     return "fxch\t%1";
2889   else
2890     return "fxch\t%0";
2891 }
2892   [(set_attr "type" "fxch")
2893    (set_attr "mode" "DF")])
2894
2895 (define_expand "movxf"
2896   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2897         (match_operand:XF 1 "general_operand" ""))]
2898   ""
2899   "ix86_expand_move (XFmode, operands); DONE;")
2900
2901 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2902 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2903 ;; Pushing using integer instructions is longer except for constants
2904 ;; and direct memory references.
2905 ;; (assuming that any given constant is pushed only once, but this ought to be
2906 ;;  handled elsewhere).
2907
2908 (define_insn "*pushxf_nointeger"
2909   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2910         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2911   "optimize_size"
2912 {
2913   /* This insn should be already split before reg-stack.  */
2914   gcc_unreachable ();
2915 }
2916   [(set_attr "type" "multi")
2917    (set_attr "unit" "i387,*,*")
2918    (set_attr "mode" "XF,SI,SI")])
2919
2920 (define_insn "*pushxf_integer"
2921   [(set (match_operand:XF 0 "push_operand" "=<,<")
2922         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2923   "!optimize_size"
2924 {
2925   /* This insn should be already split before reg-stack.  */
2926   gcc_unreachable ();
2927 }
2928   [(set_attr "type" "multi")
2929    (set_attr "unit" "i387,*")
2930    (set_attr "mode" "XF,SI")])
2931
2932 (define_split
2933   [(set (match_operand 0 "push_operand" "")
2934         (match_operand 1 "general_operand" ""))]
2935   "reload_completed
2936    && (GET_MODE (operands[0]) == XFmode
2937        || GET_MODE (operands[0]) == DFmode)
2938    && !ANY_FP_REG_P (operands[1])"
2939   [(const_int 0)]
2940   "ix86_split_long_move (operands); DONE;")
2941
2942 (define_split
2943   [(set (match_operand:XF 0 "push_operand" "")
2944         (match_operand:XF 1 "any_fp_register_operand" ""))]
2945   "!TARGET_64BIT"
2946   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2947    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2948   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2949
2950 (define_split
2951   [(set (match_operand:XF 0 "push_operand" "")
2952         (match_operand:XF 1 "any_fp_register_operand" ""))]
2953   "TARGET_64BIT"
2954   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2955    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2956   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2957
2958 ;; Do not use integer registers when optimizing for size
2959 (define_insn "*movxf_nointeger"
2960   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2961         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2962   "optimize_size
2963    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2964    && (reload_in_progress || reload_completed
2965        || (optimize_size && standard_80387_constant_p (operands[1]))
2966        || GET_CODE (operands[1]) != CONST_DOUBLE
2967        || memory_operand (operands[0], XFmode))"
2968 {
2969   switch (which_alternative)
2970     {
2971     case 0:
2972       return output_387_reg_move (insn, operands);
2973
2974     case 1:
2975       /* There is no non-popping store to memory for XFmode.  So if
2976          we need one, follow the store with a load.  */
2977       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2978         return "fstp%z0\t%y0\;fld%z0\t%y0";
2979       else
2980         return "fstp%z0\t%y0";
2981
2982     case 2:
2983       return standard_80387_constant_opcode (operands[1]);
2984
2985     case 3: case 4:
2986       return "#";
2987     default:
2988       gcc_unreachable ();
2989     }
2990 }
2991   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2992    (set_attr "mode" "XF,XF,XF,SI,SI")])
2993
2994 (define_insn "*movxf_integer"
2995   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2996         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2997   "!optimize_size
2998    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2999    && (reload_in_progress || reload_completed
3000        || (optimize_size && standard_80387_constant_p (operands[1]))
3001        || GET_CODE (operands[1]) != CONST_DOUBLE
3002        || memory_operand (operands[0], XFmode))"
3003 {
3004   switch (which_alternative)
3005     {
3006     case 0:
3007       return output_387_reg_move (insn, operands);
3008
3009     case 1:
3010       /* There is no non-popping store to memory for XFmode.  So if
3011          we need one, follow the store with a load.  */
3012       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3013         return "fstp%z0\t%y0\;fld%z0\t%y0";
3014       else
3015         return "fstp%z0\t%y0";
3016
3017     case 2:
3018       return standard_80387_constant_opcode (operands[1]);
3019
3020     case 3: case 4:
3021       return "#";
3022
3023     default:
3024       gcc_unreachable ();
3025     }
3026 }
3027   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3028    (set_attr "mode" "XF,XF,XF,SI,SI")])
3029
3030 (define_split
3031   [(set (match_operand 0 "nonimmediate_operand" "")
3032         (match_operand 1 "general_operand" ""))]
3033   "reload_completed
3034    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3035    && GET_MODE (operands[0]) == XFmode
3036    && ! (ANY_FP_REG_P (operands[0]) ||
3037          (GET_CODE (operands[0]) == SUBREG
3038           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3039    && ! (ANY_FP_REG_P (operands[1]) ||
3040          (GET_CODE (operands[1]) == SUBREG
3041           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3042   [(const_int 0)]
3043   "ix86_split_long_move (operands); DONE;")
3044
3045 (define_split
3046   [(set (match_operand 0 "register_operand" "")
3047         (match_operand 1 "memory_operand" ""))]
3048   "reload_completed
3049    && MEM_P (operands[1])
3050    && (GET_MODE (operands[0]) == XFmode
3051        || GET_MODE (operands[0]) == SFmode
3052        || GET_MODE (operands[0]) == DFmode)
3053    && constant_pool_reference_p (operands[1])"
3054   [(set (match_dup 0) (match_dup 1))]
3055 {
3056   rtx c = avoid_constant_pool_reference (operands[1]);
3057   rtx r = operands[0];
3058
3059   if (GET_CODE (r) == SUBREG)
3060     r = SUBREG_REG (r);
3061
3062   if (SSE_REG_P (r))
3063     {
3064       if (!standard_sse_constant_p (c))
3065         FAIL;
3066     }
3067   else if (FP_REG_P (r))
3068     {
3069       if (!standard_80387_constant_p (c))
3070         FAIL;
3071     }
3072   else if (MMX_REG_P (r))
3073     FAIL;
3074
3075   operands[1] = c;
3076 })
3077
3078 (define_split
3079   [(set (match_operand 0 "register_operand" "")
3080         (float_extend (match_operand 1 "memory_operand" "")))]
3081   "reload_completed
3082    && MEM_P (operands[1])
3083    && (GET_MODE (operands[0]) == XFmode
3084        || GET_MODE (operands[0]) == SFmode
3085        || GET_MODE (operands[0]) == DFmode)
3086    && constant_pool_reference_p (operands[1])"
3087   [(set (match_dup 0) (match_dup 1))]
3088 {
3089   rtx c = avoid_constant_pool_reference (SET_SRC (PATTERN (curr_insn)));
3090   rtx r = operands[0];
3091
3092   if (GET_CODE (r) == SUBREG)
3093     r = SUBREG_REG (r);
3094
3095   if (SSE_REG_P (r))
3096     {
3097       if (!standard_sse_constant_p (c))
3098         FAIL;
3099     }
3100   else if (FP_REG_P (r))
3101     {
3102       if (!standard_80387_constant_p (c))
3103         FAIL;
3104     }
3105   else if (MMX_REG_P (r))
3106     FAIL;
3107
3108   operands[1] = c;
3109 })
3110
3111 (define_insn "swapxf"
3112   [(set (match_operand:XF 0 "register_operand" "+f")
3113         (match_operand:XF 1 "register_operand" "+f"))
3114    (set (match_dup 1)
3115         (match_dup 0))]
3116   "TARGET_80387"
3117 {
3118   if (STACK_TOP_P (operands[0]))
3119     return "fxch\t%1";
3120   else
3121     return "fxch\t%0";
3122 }
3123   [(set_attr "type" "fxch")
3124    (set_attr "mode" "XF")])
3125
3126 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3127 (define_split
3128   [(set (match_operand:X87MODEF 0 "register_operand" "")
3129         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3130   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3131    && (standard_80387_constant_p (operands[1]) == 8
3132        || standard_80387_constant_p (operands[1]) == 9)"
3133   [(set (match_dup 0)(match_dup 1))
3134    (set (match_dup 0)
3135         (neg:X87MODEF (match_dup 0)))]
3136 {
3137   REAL_VALUE_TYPE r;
3138
3139   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3140   if (real_isnegzero (&r))
3141     operands[1] = CONST0_RTX (<MODE>mode);
3142   else
3143     operands[1] = CONST1_RTX (<MODE>mode);
3144 })
3145
3146 (define_expand "movtf"
3147   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3148         (match_operand:TF 1 "nonimmediate_operand" ""))]
3149   "TARGET_64BIT"
3150 {
3151   ix86_expand_move (TFmode, operands);
3152   DONE;
3153 })
3154
3155 (define_insn "*movtf_internal"
3156   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3157         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3158   "TARGET_64BIT
3159    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3160 {
3161   switch (which_alternative)
3162     {
3163     case 0:
3164     case 1:
3165       return "#";
3166     case 2:
3167       if (get_attr_mode (insn) == MODE_V4SF)
3168         return "xorps\t%0, %0";
3169       else
3170         return "pxor\t%0, %0";
3171     case 3:
3172     case 4:
3173       if (get_attr_mode (insn) == MODE_V4SF)
3174         return "movaps\t{%1, %0|%0, %1}";
3175       else
3176         return "movdqa\t{%1, %0|%0, %1}";
3177     default:
3178       gcc_unreachable ();
3179     }
3180 }
3181   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3182    (set (attr "mode")
3183         (cond [(eq_attr "alternative" "2,3")
3184                  (if_then_else
3185                    (ne (symbol_ref "optimize_size")
3186                        (const_int 0))
3187                    (const_string "V4SF")
3188                    (const_string "TI"))
3189                (eq_attr "alternative" "4")
3190                  (if_then_else
3191                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3192                             (const_int 0))
3193                         (ne (symbol_ref "optimize_size")
3194                             (const_int 0)))
3195                    (const_string "V4SF")
3196                    (const_string "TI"))]
3197                (const_string "DI")))])
3198
3199 (define_split
3200   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3201         (match_operand:TF 1 "general_operand" ""))]
3202   "reload_completed && !SSE_REG_P (operands[0])
3203    && !SSE_REG_P (operands[1])"
3204   [(const_int 0)]
3205   "ix86_split_long_move (operands); DONE;")
3206 \f
3207 ;; Zero extension instructions
3208
3209 (define_expand "zero_extendhisi2"
3210   [(set (match_operand:SI 0 "register_operand" "")
3211      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3212   ""
3213 {
3214   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3215     {
3216       operands[1] = force_reg (HImode, operands[1]);
3217       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3218       DONE;
3219     }
3220 })
3221
3222 (define_insn "zero_extendhisi2_and"
3223   [(set (match_operand:SI 0 "register_operand" "=r")
3224      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3225    (clobber (reg:CC FLAGS_REG))]
3226   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3227   "#"
3228   [(set_attr "type" "alu1")
3229    (set_attr "mode" "SI")])
3230
3231 (define_split
3232   [(set (match_operand:SI 0 "register_operand" "")
3233         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3234    (clobber (reg:CC FLAGS_REG))]
3235   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3236   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3237               (clobber (reg:CC FLAGS_REG))])]
3238   "")
3239
3240 (define_insn "*zero_extendhisi2_movzwl"
3241   [(set (match_operand:SI 0 "register_operand" "=r")
3242      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3243   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3244   "movz{wl|x}\t{%1, %0|%0, %1}"
3245   [(set_attr "type" "imovx")
3246    (set_attr "mode" "SI")])
3247
3248 (define_expand "zero_extendqihi2"
3249   [(parallel
3250     [(set (match_operand:HI 0 "register_operand" "")
3251        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3252      (clobber (reg:CC FLAGS_REG))])]
3253   ""
3254   "")
3255
3256 (define_insn "*zero_extendqihi2_and"
3257   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3258      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3259    (clobber (reg:CC FLAGS_REG))]
3260   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3261   "#"
3262   [(set_attr "type" "alu1")
3263    (set_attr "mode" "HI")])
3264
3265 (define_insn "*zero_extendqihi2_movzbw_and"
3266   [(set (match_operand:HI 0 "register_operand" "=r,r")
3267      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3268    (clobber (reg:CC FLAGS_REG))]
3269   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3270   "#"
3271   [(set_attr "type" "imovx,alu1")
3272    (set_attr "mode" "HI")])
3273
3274 ; zero extend to SImode here to avoid partial register stalls
3275 (define_insn "*zero_extendqihi2_movzbl"
3276   [(set (match_operand:HI 0 "register_operand" "=r")
3277      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3278   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3279   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3280   [(set_attr "type" "imovx")
3281    (set_attr "mode" "SI")])
3282
3283 ;; For the movzbw case strip only the clobber
3284 (define_split
3285   [(set (match_operand:HI 0 "register_operand" "")
3286         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3287    (clobber (reg:CC FLAGS_REG))]
3288   "reload_completed
3289    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3290    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3291   [(set (match_operand:HI 0 "register_operand" "")
3292         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3293
3294 ;; When source and destination does not overlap, clear destination
3295 ;; first and then do the movb
3296 (define_split
3297   [(set (match_operand:HI 0 "register_operand" "")
3298         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3299    (clobber (reg:CC FLAGS_REG))]
3300   "reload_completed
3301    && ANY_QI_REG_P (operands[0])
3302    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3303    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3304   [(set (match_dup 0) (const_int 0))
3305    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3306   "operands[2] = gen_lowpart (QImode, operands[0]);")
3307
3308 ;; Rest is handled by single and.
3309 (define_split
3310   [(set (match_operand:HI 0 "register_operand" "")
3311         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3312    (clobber (reg:CC FLAGS_REG))]
3313   "reload_completed
3314    && true_regnum (operands[0]) == true_regnum (operands[1])"
3315   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3316               (clobber (reg:CC FLAGS_REG))])]
3317   "")
3318
3319 (define_expand "zero_extendqisi2"
3320   [(parallel
3321     [(set (match_operand:SI 0 "register_operand" "")
3322        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3323      (clobber (reg:CC FLAGS_REG))])]
3324   ""
3325   "")
3326
3327 (define_insn "*zero_extendqisi2_and"
3328   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3329      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3330    (clobber (reg:CC FLAGS_REG))]
3331   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3332   "#"
3333   [(set_attr "type" "alu1")
3334    (set_attr "mode" "SI")])
3335
3336 (define_insn "*zero_extendqisi2_movzbw_and"
3337   [(set (match_operand:SI 0 "register_operand" "=r,r")
3338      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3339    (clobber (reg:CC FLAGS_REG))]
3340   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3341   "#"
3342   [(set_attr "type" "imovx,alu1")
3343    (set_attr "mode" "SI")])
3344
3345 (define_insn "*zero_extendqisi2_movzbw"
3346   [(set (match_operand:SI 0 "register_operand" "=r")
3347      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3348   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3349   "movz{bl|x}\t{%1, %0|%0, %1}"
3350   [(set_attr "type" "imovx")
3351    (set_attr "mode" "SI")])
3352
3353 ;; For the movzbl case strip only the clobber
3354 (define_split
3355   [(set (match_operand:SI 0 "register_operand" "")
3356         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3357    (clobber (reg:CC FLAGS_REG))]
3358   "reload_completed
3359    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3360    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3361   [(set (match_dup 0)
3362         (zero_extend:SI (match_dup 1)))])
3363
3364 ;; When source and destination does not overlap, clear destination
3365 ;; first and then do the movb
3366 (define_split
3367   [(set (match_operand:SI 0 "register_operand" "")
3368         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3369    (clobber (reg:CC FLAGS_REG))]
3370   "reload_completed
3371    && ANY_QI_REG_P (operands[0])
3372    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3373    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3374    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3375   [(set (match_dup 0) (const_int 0))
3376    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3377   "operands[2] = gen_lowpart (QImode, operands[0]);")
3378
3379 ;; Rest is handled by single and.
3380 (define_split
3381   [(set (match_operand:SI 0 "register_operand" "")
3382         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3383    (clobber (reg:CC FLAGS_REG))]
3384   "reload_completed
3385    && true_regnum (operands[0]) == true_regnum (operands[1])"
3386   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3387               (clobber (reg:CC FLAGS_REG))])]
3388   "")
3389
3390 ;; %%% Kill me once multi-word ops are sane.
3391 (define_expand "zero_extendsidi2"
3392   [(set (match_operand:DI 0 "register_operand" "=r")
3393      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3394   ""
3395 {
3396   if (!TARGET_64BIT)
3397     {
3398       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3399       DONE;
3400     }
3401 })
3402
3403 (define_insn "zero_extendsidi2_32"
3404   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,*y,?*Yi,*Y2")
3405         (zero_extend:DI
3406          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m ,r   ,m")))
3407    (clobber (reg:CC FLAGS_REG))]
3408   "!TARGET_64BIT"
3409   "@
3410    #
3411    #
3412    #
3413    movd\t{%1, %0|%0, %1}
3414    movd\t{%1, %0|%0, %1}
3415    movd\t{%1, %0|%0, %1}
3416    movd\t{%1, %0|%0, %1}"
3417   [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3418    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3419
3420 (define_insn "zero_extendsidi2_rex64"
3421   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,*y,?*Yi,*Y2")
3422      (zero_extend:DI
3423        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m ,r   ,m")))]
3424   "TARGET_64BIT"
3425   "@
3426    mov\t{%k1, %k0|%k0, %k1}
3427    #
3428    movd\t{%1, %0|%0, %1}
3429    movd\t{%1, %0|%0, %1}
3430    movd\t{%1, %0|%0, %1}
3431    movd\t{%1, %0|%0, %1}"
3432   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3433    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3434
3435 (define_split
3436   [(set (match_operand:DI 0 "memory_operand" "")
3437      (zero_extend:DI (match_dup 0)))]
3438   "TARGET_64BIT"
3439   [(set (match_dup 4) (const_int 0))]
3440   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3441
3442 (define_split
3443   [(set (match_operand:DI 0 "register_operand" "")
3444         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3445    (clobber (reg:CC FLAGS_REG))]
3446   "!TARGET_64BIT && reload_completed
3447    && true_regnum (operands[0]) == true_regnum (operands[1])"
3448   [(set (match_dup 4) (const_int 0))]
3449   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3450
3451 (define_split
3452   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3453         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3454    (clobber (reg:CC FLAGS_REG))]
3455   "!TARGET_64BIT && reload_completed
3456    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3457   [(set (match_dup 3) (match_dup 1))
3458    (set (match_dup 4) (const_int 0))]
3459   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3460
3461 (define_insn "zero_extendhidi2"
3462   [(set (match_operand:DI 0 "register_operand" "=r")
3463      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3464   "TARGET_64BIT"
3465   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3466   [(set_attr "type" "imovx")
3467    (set_attr "mode" "DI")])
3468
3469 (define_insn "zero_extendqidi2"
3470   [(set (match_operand:DI 0 "register_operand" "=r")
3471      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3472   "TARGET_64BIT"
3473   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3474   [(set_attr "type" "imovx")
3475    (set_attr "mode" "DI")])
3476 \f
3477 ;; Sign extension instructions
3478
3479 (define_expand "extendsidi2"
3480   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3481                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3482               (clobber (reg:CC FLAGS_REG))
3483               (clobber (match_scratch:SI 2 ""))])]
3484   ""
3485 {
3486   if (TARGET_64BIT)
3487     {
3488       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3489       DONE;
3490     }
3491 })
3492
3493 (define_insn "*extendsidi2_1"
3494   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3495         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3496    (clobber (reg:CC FLAGS_REG))
3497    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3498   "!TARGET_64BIT"
3499   "#")
3500
3501 (define_insn "extendsidi2_rex64"
3502   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3503         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3504   "TARGET_64BIT"
3505   "@
3506    {cltq|cdqe}
3507    movs{lq|x}\t{%1,%0|%0, %1}"
3508   [(set_attr "type" "imovx")
3509    (set_attr "mode" "DI")
3510    (set_attr "prefix_0f" "0")
3511    (set_attr "modrm" "0,1")])
3512
3513 (define_insn "extendhidi2"
3514   [(set (match_operand:DI 0 "register_operand" "=r")
3515         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3516   "TARGET_64BIT"
3517   "movs{wq|x}\t{%1,%0|%0, %1}"
3518   [(set_attr "type" "imovx")
3519    (set_attr "mode" "DI")])
3520
3521 (define_insn "extendqidi2"
3522   [(set (match_operand:DI 0 "register_operand" "=r")
3523         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3524   "TARGET_64BIT"
3525   "movs{bq|x}\t{%1,%0|%0, %1}"
3526    [(set_attr "type" "imovx")
3527     (set_attr "mode" "DI")])
3528
3529 ;; Extend to memory case when source register does die.
3530 (define_split
3531   [(set (match_operand:DI 0 "memory_operand" "")
3532         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3533    (clobber (reg:CC FLAGS_REG))
3534    (clobber (match_operand:SI 2 "register_operand" ""))]
3535   "(reload_completed
3536     && dead_or_set_p (insn, operands[1])
3537     && !reg_mentioned_p (operands[1], operands[0]))"
3538   [(set (match_dup 3) (match_dup 1))
3539    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3540               (clobber (reg:CC FLAGS_REG))])
3541    (set (match_dup 4) (match_dup 1))]
3542   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3543
3544 ;; Extend to memory case when source register does not die.
3545 (define_split
3546   [(set (match_operand:DI 0 "memory_operand" "")
3547         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3548    (clobber (reg:CC FLAGS_REG))
3549    (clobber (match_operand:SI 2 "register_operand" ""))]
3550   "reload_completed"
3551   [(const_int 0)]
3552 {
3553   split_di (&operands[0], 1, &operands[3], &operands[4]);
3554
3555   emit_move_insn (operands[3], operands[1]);
3556
3557   /* Generate a cltd if possible and doing so it profitable.  */
3558   if (true_regnum (operands[1]) == 0
3559       && true_regnum (operands[2]) == 1
3560       && (optimize_size || TARGET_USE_CLTD))
3561     {
3562       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3563     }
3564   else
3565     {
3566       emit_move_insn (operands[2], operands[1]);
3567       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3568     }
3569   emit_move_insn (operands[4], operands[2]);
3570   DONE;
3571 })
3572
3573 ;; Extend to register case.  Optimize case where source and destination
3574 ;; registers match and cases where we can use cltd.
3575 (define_split
3576   [(set (match_operand:DI 0 "register_operand" "")
3577         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3578    (clobber (reg:CC FLAGS_REG))
3579    (clobber (match_scratch:SI 2 ""))]
3580   "reload_completed"
3581   [(const_int 0)]
3582 {
3583   split_di (&operands[0], 1, &operands[3], &operands[4]);
3584
3585   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3586     emit_move_insn (operands[3], operands[1]);
3587
3588   /* Generate a cltd if possible and doing so it profitable.  */
3589   if (true_regnum (operands[3]) == 0
3590       && (optimize_size || TARGET_USE_CLTD))
3591     {
3592       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3593       DONE;
3594     }
3595
3596   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3597     emit_move_insn (operands[4], operands[1]);
3598
3599   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3600   DONE;
3601 })
3602
3603 (define_insn "extendhisi2"
3604   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3605         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3606   ""
3607 {
3608   switch (get_attr_prefix_0f (insn))
3609     {
3610     case 0:
3611       return "{cwtl|cwde}";
3612     default:
3613       return "movs{wl|x}\t{%1,%0|%0, %1}";
3614     }
3615 }
3616   [(set_attr "type" "imovx")
3617    (set_attr "mode" "SI")
3618    (set (attr "prefix_0f")
3619      ;; movsx is short decodable while cwtl is vector decoded.
3620      (if_then_else (and (eq_attr "cpu" "!k6")
3621                         (eq_attr "alternative" "0"))
3622         (const_string "0")
3623         (const_string "1")))
3624    (set (attr "modrm")
3625      (if_then_else (eq_attr "prefix_0f" "0")
3626         (const_string "0")
3627         (const_string "1")))])
3628
3629 (define_insn "*extendhisi2_zext"
3630   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3631         (zero_extend:DI
3632           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3633   "TARGET_64BIT"
3634 {
3635   switch (get_attr_prefix_0f (insn))
3636     {
3637     case 0:
3638       return "{cwtl|cwde}";
3639     default:
3640       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3641     }
3642 }
3643   [(set_attr "type" "imovx")
3644    (set_attr "mode" "SI")
3645    (set (attr "prefix_0f")
3646      ;; movsx is short decodable while cwtl is vector decoded.
3647      (if_then_else (and (eq_attr "cpu" "!k6")
3648                         (eq_attr "alternative" "0"))
3649         (const_string "0")
3650         (const_string "1")))
3651    (set (attr "modrm")
3652      (if_then_else (eq_attr "prefix_0f" "0")
3653         (const_string "0")
3654         (const_string "1")))])
3655
3656 (define_insn "extendqihi2"
3657   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3658         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3659   ""
3660 {
3661   switch (get_attr_prefix_0f (insn))
3662     {
3663     case 0:
3664       return "{cbtw|cbw}";
3665     default:
3666       return "movs{bw|x}\t{%1,%0|%0, %1}";
3667     }
3668 }
3669   [(set_attr "type" "imovx")
3670    (set_attr "mode" "HI")
3671    (set (attr "prefix_0f")
3672      ;; movsx is short decodable while cwtl is vector decoded.
3673      (if_then_else (and (eq_attr "cpu" "!k6")
3674                         (eq_attr "alternative" "0"))
3675         (const_string "0")
3676         (const_string "1")))
3677    (set (attr "modrm")
3678      (if_then_else (eq_attr "prefix_0f" "0")
3679         (const_string "0")
3680         (const_string "1")))])
3681
3682 (define_insn "extendqisi2"
3683   [(set (match_operand:SI 0 "register_operand" "=r")
3684         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3685   ""
3686   "movs{bl|x}\t{%1,%0|%0, %1}"
3687    [(set_attr "type" "imovx")
3688     (set_attr "mode" "SI")])
3689
3690 (define_insn "*extendqisi2_zext"
3691   [(set (match_operand:DI 0 "register_operand" "=r")
3692         (zero_extend:DI
3693           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3694   "TARGET_64BIT"
3695   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3696    [(set_attr "type" "imovx")
3697     (set_attr "mode" "SI")])
3698 \f
3699 ;; Conversions between float and double.
3700
3701 ;; These are all no-ops in the model used for the 80387.  So just
3702 ;; emit moves.
3703
3704 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3705 (define_insn "*dummy_extendsfdf2"
3706   [(set (match_operand:DF 0 "push_operand" "=<")
3707         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3708   "0"
3709   "#")
3710
3711 (define_split
3712   [(set (match_operand:DF 0 "push_operand" "")
3713         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3714   "!TARGET_64BIT"
3715   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3716    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3717
3718 (define_split
3719   [(set (match_operand:DF 0 "push_operand" "")
3720         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3721   "TARGET_64BIT"
3722   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3723    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3724
3725 (define_insn "*dummy_extendsfxf2"
3726   [(set (match_operand:XF 0 "push_operand" "=<")
3727         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3728   "0"
3729   "#")
3730
3731 (define_split
3732   [(set (match_operand:XF 0 "push_operand" "")
3733         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3734   ""
3735   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3736    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3737   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3738
3739 (define_split
3740   [(set (match_operand:XF 0 "push_operand" "")
3741         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3742   "TARGET_64BIT"
3743   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3744    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3745   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3746
3747 (define_split
3748   [(set (match_operand:XF 0 "push_operand" "")
3749         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3750   ""
3751   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3752    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3753   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3754
3755 (define_split
3756   [(set (match_operand:XF 0 "push_operand" "")
3757         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3758   "TARGET_64BIT"
3759   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3760    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3761   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3762
3763 (define_expand "extendsfdf2"
3764   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3765         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3766   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3767 {
3768   /* ??? Needed for compress_float_constant since all fp constants
3769      are LEGITIMATE_CONSTANT_P.  */
3770   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3771     {
3772       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3773           && standard_80387_constant_p (operands[1]) > 0)
3774         {
3775           operands[1] = simplify_const_unary_operation
3776             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3777           emit_move_insn_1 (operands[0], operands[1]);
3778           DONE;
3779         }
3780       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3781     }
3782 })
3783
3784 (define_insn "*extendsfdf2_mixed"
3785   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3786         (float_extend:DF
3787           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3788   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3789 {
3790   switch (which_alternative)
3791     {
3792     case 0:
3793       return output_387_reg_move (insn, operands);
3794
3795     case 1:
3796       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3797         return "fstp%z0\t%y0";
3798       else
3799         return "fst%z0\t%y0";
3800
3801     case 2:
3802       return "cvtss2sd\t{%1, %0|%0, %1}";
3803
3804     default:
3805       gcc_unreachable ();
3806     }
3807 }
3808   [(set_attr "type" "fmov,fmov,ssecvt")
3809    (set_attr "mode" "SF,XF,DF")])
3810
3811 (define_insn "*extendsfdf2_sse"
3812   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3813         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3814   "TARGET_SSE2 && TARGET_SSE_MATH"
3815   "cvtss2sd\t{%1, %0|%0, %1}"
3816   [(set_attr "type" "ssecvt")
3817    (set_attr "mode" "DF")])
3818
3819 (define_insn "*extendsfdf2_i387"
3820   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3821         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3822   "TARGET_80387"
3823 {
3824   switch (which_alternative)
3825     {
3826     case 0:
3827       return output_387_reg_move (insn, operands);
3828
3829     case 1:
3830       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3831         return "fstp%z0\t%y0";
3832       else
3833         return "fst%z0\t%y0";
3834
3835     default:
3836       gcc_unreachable ();
3837     }
3838 }
3839   [(set_attr "type" "fmov")
3840    (set_attr "mode" "SF,XF")])
3841
3842 (define_expand "extendsfxf2"
3843   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3844         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3845   "TARGET_80387"
3846 {
3847   /* ??? Needed for compress_float_constant since all fp constants
3848      are LEGITIMATE_CONSTANT_P.  */
3849   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3850     {
3851       if (standard_80387_constant_p (operands[1]) > 0)
3852         {
3853           operands[1] = simplify_const_unary_operation
3854             (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3855           emit_move_insn_1 (operands[0], operands[1]);
3856           DONE;
3857         }
3858       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3859     }
3860 })
3861
3862 (define_insn "*extendsfxf2_i387"
3863   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3864         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3865   "TARGET_80387"
3866 {
3867   switch (which_alternative)
3868     {
3869     case 0:
3870       return output_387_reg_move (insn, operands);
3871
3872     case 1:
3873       /* There is no non-popping store to memory for XFmode.  So if
3874          we need one, follow the store with a load.  */
3875       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3876         return "fstp%z0\t%y0";
3877       else
3878         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3879
3880     default:
3881       gcc_unreachable ();
3882     }
3883 }
3884   [(set_attr "type" "fmov")
3885    (set_attr "mode" "SF,XF")])
3886
3887 (define_expand "extenddfxf2"
3888   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3889         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3890   "TARGET_80387"
3891 {
3892   /* ??? Needed for compress_float_constant since all fp constants
3893      are LEGITIMATE_CONSTANT_P.  */
3894   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3895     {
3896       if (standard_80387_constant_p (operands[1]) > 0)
3897         {
3898           operands[1] = simplify_const_unary_operation
3899             (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3900           emit_move_insn_1 (operands[0], operands[1]);
3901           DONE;
3902         }
3903       operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3904     }
3905 })
3906
3907 (define_insn "*extenddfxf2_i387"
3908   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3909         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3910   "TARGET_80387"
3911 {
3912   switch (which_alternative)
3913     {
3914     case 0:
3915       return output_387_reg_move (insn, operands);
3916
3917     case 1:
3918       /* There is no non-popping store to memory for XFmode.  So if
3919          we need one, follow the store with a load.  */
3920       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3921         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3922       else
3923         return "fstp%z0\t%y0";
3924
3925     default:
3926       gcc_unreachable ();
3927     }
3928 }
3929   [(set_attr "type" "fmov")
3930    (set_attr "mode" "DF,XF")])
3931
3932 ;; %%% This seems bad bad news.
3933 ;; This cannot output into an f-reg because there is no way to be sure
3934 ;; of truncating in that case.  Otherwise this is just like a simple move
3935 ;; insn.  So we pretend we can output to a reg in order to get better
3936 ;; register preferencing, but we really use a stack slot.
3937
3938 ;; Conversion from DFmode to SFmode.
3939
3940 (define_expand "truncdfsf2"
3941   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3942         (float_truncate:SF
3943           (match_operand:DF 1 "nonimmediate_operand" "")))]
3944   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3945 {
3946   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3947     ;
3948   else if (flag_unsafe_math_optimizations)
3949     ;
3950   else
3951     {
3952       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3953       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3954       DONE;
3955     }
3956 })
3957
3958 (define_expand "truncdfsf2_with_temp"
3959   [(parallel [(set (match_operand:SF 0 "" "")
3960                    (float_truncate:SF (match_operand:DF 1 "" "")))
3961               (clobber (match_operand:SF 2 "" ""))])]
3962   "")
3963
3964 (define_insn "*truncdfsf_fast_mixed"
3965   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,x")
3966         (float_truncate:SF
3967           (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
3968   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3969 {
3970   switch (which_alternative)
3971     {
3972     case 0:
3973       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3974         return "fstp%z0\t%y0";
3975       else
3976         return "fst%z0\t%y0";
3977     case 1:
3978       return output_387_reg_move (insn, operands);
3979     case 2:
3980       return "cvtsd2ss\t{%1, %0|%0, %1}";
3981     default:
3982       gcc_unreachable ();
3983     }
3984 }
3985   [(set_attr "type" "fmov,fmov,ssecvt")
3986    (set_attr "mode" "SF")])
3987
3988 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3989 ;; because nothing we do here is unsafe.
3990 (define_insn "*truncdfsf_fast_sse"
3991   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
3992         (float_truncate:SF
3993           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
3994   "TARGET_SSE2 && TARGET_SSE_MATH"
3995   "cvtsd2ss\t{%1, %0|%0, %1}"
3996   [(set_attr "type" "ssecvt")
3997    (set_attr "mode" "SF")])
3998
3999 (define_insn "*truncdfsf_fast_i387"
4000   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4001         (float_truncate:SF
4002           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4003   "TARGET_80387 && flag_unsafe_math_optimizations"
4004   "* return output_387_reg_move (insn, operands);"
4005   [(set_attr "type" "fmov")
4006    (set_attr "mode" "SF")])
4007
4008 (define_insn "*truncdfsf_mixed"
4009   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y2")
4010         (float_truncate:SF
4011           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Y2m")))
4012    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
4013   "TARGET_MIX_SSE_I387"
4014 {
4015   switch (which_alternative)
4016     {
4017     case 0:
4018       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4019         return "fstp%z0\t%y0";
4020       else
4021         return "fst%z0\t%y0";
4022     case 1:
4023       return "#";
4024     case 2:
4025       return "cvtsd2ss\t{%1, %0|%0, %1}";
4026     default:
4027       gcc_unreachable ();
4028     }
4029 }
4030   [(set_attr "type" "fmov,multi,ssecvt")
4031    (set_attr "unit" "*,i387,*")
4032    (set_attr "mode" "SF")])
4033
4034 (define_insn "*truncdfsf_i387"
4035   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4036         (float_truncate:SF
4037           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4038    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4039   "TARGET_80387"
4040 {
4041   switch (which_alternative)
4042     {
4043     case 0:
4044       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4045         return "fstp%z0\t%y0";
4046       else
4047         return "fst%z0\t%y0";
4048     case 1:
4049       return "#";
4050     default:
4051       gcc_unreachable ();
4052     }
4053 }
4054   [(set_attr "type" "fmov,multi")
4055    (set_attr "unit" "*,i387")
4056    (set_attr "mode" "SF")])
4057
4058 (define_insn "*truncdfsf2_i387_1"
4059   [(set (match_operand:SF 0 "memory_operand" "=m")
4060         (float_truncate:SF
4061           (match_operand:DF 1 "register_operand" "f")))]
4062   "TARGET_80387
4063    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4064    && !TARGET_MIX_SSE_I387"
4065 {
4066   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4067     return "fstp%z0\t%y0";
4068   else
4069     return "fst%z0\t%y0";
4070 }
4071   [(set_attr "type" "fmov")
4072    (set_attr "mode" "SF")])
4073
4074 (define_split
4075   [(set (match_operand:SF 0 "register_operand" "")
4076         (float_truncate:SF
4077          (match_operand:DF 1 "fp_register_operand" "")))
4078    (clobber (match_operand 2 "" ""))]
4079   "reload_completed"
4080   [(set (match_dup 2) (match_dup 1))
4081    (set (match_dup 0) (match_dup 2))]
4082 {
4083   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4084 })
4085
4086 ;; Conversion from XFmode to SFmode.
4087
4088 (define_expand "truncxfsf2"
4089   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4090                    (float_truncate:SF
4091                     (match_operand:XF 1 "register_operand" "")))
4092               (clobber (match_dup 2))])]
4093   "TARGET_80387"
4094 {
4095   if (flag_unsafe_math_optimizations)
4096     {
4097       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
4098       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
4099       if (reg != operands[0])
4100         emit_move_insn (operands[0], reg);
4101       DONE;
4102     }
4103   else
4104     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
4105 })
4106
4107 (define_insn "*truncxfsf2_mixed"
4108   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
4109         (float_truncate:SF
4110          (match_operand:XF 1 "register_operand" "f,f,f,f")))
4111    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4112   "TARGET_80387"
4113 {
4114   gcc_assert (!which_alternative);
4115   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4116     return "fstp%z0\t%y0";
4117   else
4118     return "fst%z0\t%y0";
4119 }
4120   [(set_attr "type" "fmov,multi,multi,multi")
4121    (set_attr "unit" "*,i387,i387,i387")
4122    (set_attr "mode" "SF")])
4123
4124 (define_insn "truncxfsf2_i387_noop"
4125   [(set (match_operand:SF 0 "register_operand" "=f")
4126         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
4127   "TARGET_80387 && flag_unsafe_math_optimizations"
4128   "* return output_387_reg_move (insn, operands);"
4129   [(set_attr "type" "fmov")
4130    (set_attr "mode" "SF")])
4131
4132 (define_insn "*truncxfsf2_i387"
4133   [(set (match_operand:SF 0 "memory_operand" "=m")
4134         (float_truncate:SF
4135          (match_operand:XF 1 "register_operand" "f")))]
4136   "TARGET_80387"
4137 {
4138   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4139     return "fstp%z0\t%y0";
4140   else
4141     return "fst%z0\t%y0";
4142 }
4143   [(set_attr "type" "fmov")
4144    (set_attr "mode" "SF")])
4145
4146 (define_split
4147   [(set (match_operand:SF 0 "register_operand" "")
4148         (float_truncate:SF
4149          (match_operand:XF 1 "register_operand" "")))
4150    (clobber (match_operand:SF 2 "memory_operand" ""))]
4151   "TARGET_80387 && reload_completed"
4152   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4153    (set (match_dup 0) (match_dup 2))]
4154   "")
4155
4156 (define_split
4157   [(set (match_operand:SF 0 "memory_operand" "")
4158         (float_truncate:SF
4159          (match_operand:XF 1 "register_operand" "")))
4160    (clobber (match_operand:SF 2 "memory_operand" ""))]
4161   "TARGET_80387"
4162   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4163   "")
4164
4165 ;; Conversion from XFmode to DFmode.
4166
4167 (define_expand "truncxfdf2"
4168   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4169                    (float_truncate:DF
4170                     (match_operand:XF 1 "register_operand" "")))
4171               (clobber (match_dup 2))])]
4172   "TARGET_80387"
4173 {
4174   if (flag_unsafe_math_optimizations)
4175     {
4176       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
4177       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
4178       if (reg != operands[0])
4179         emit_move_insn (operands[0], reg);
4180       DONE;
4181     }
4182   else
4183     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
4184 })
4185
4186 (define_insn "*truncxfdf2_mixed"
4187   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y2*x")
4188         (float_truncate:DF
4189          (match_operand:XF 1 "register_operand" "f,f,f,f")))
4190    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4191   "TARGET_80387"
4192 {
4193   gcc_assert (!which_alternative);
4194   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4195     return "fstp%z0\t%y0";
4196   else
4197     return "fst%z0\t%y0";
4198 }
4199   [(set_attr "type" "fmov,multi,multi,multi")
4200    (set_attr "unit" "*,i387,i387,i387")
4201    (set_attr "mode" "DF")])
4202
4203 (define_insn "truncxfdf2_i387_noop"
4204   [(set (match_operand:DF 0 "register_operand" "=f")
4205         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4206   "TARGET_80387 && flag_unsafe_math_optimizations"
4207   "* return output_387_reg_move (insn, operands);"
4208   [(set_attr "type" "fmov")
4209    (set_attr "mode" "DF")])
4210
4211 (define_insn "*truncxfdf2_i387"
4212   [(set (match_operand:DF 0 "memory_operand" "=m")
4213         (float_truncate:DF
4214           (match_operand:XF 1 "register_operand" "f")))]
4215   "TARGET_80387"
4216 {
4217   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4218     return "fstp%z0\t%y0";
4219   else
4220     return "fst%z0\t%y0";
4221 }
4222   [(set_attr "type" "fmov")
4223    (set_attr "mode" "DF")])
4224
4225 (define_split
4226   [(set (match_operand:DF 0 "register_operand" "")
4227         (float_truncate:DF
4228          (match_operand:XF 1 "register_operand" "")))
4229    (clobber (match_operand:DF 2 "memory_operand" ""))]
4230   "TARGET_80387 && reload_completed"
4231   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4232    (set (match_dup 0) (match_dup 2))]
4233   "")
4234
4235 (define_split
4236   [(set (match_operand:DF 0 "memory_operand" "")
4237         (float_truncate:DF
4238          (match_operand:XF 1 "register_operand" "")))
4239    (clobber (match_operand:DF 2 "memory_operand" ""))]
4240   "TARGET_80387"
4241   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4242   "")
4243 \f
4244 ;; Signed conversion to DImode.
4245
4246 (define_expand "fix_truncxfdi2"
4247   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4248                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4249               (clobber (reg:CC FLAGS_REG))])]
4250   "TARGET_80387"
4251 {
4252   if (TARGET_FISTTP)
4253    {
4254      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4255      DONE;
4256    }
4257 })
4258
4259 (define_expand "fix_trunc<mode>di2"
4260   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4261                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4262               (clobber (reg:CC FLAGS_REG))])]
4263   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4264 {
4265   if (TARGET_FISTTP
4266       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4267    {
4268      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4269      DONE;
4270    }
4271   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4272    {
4273      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4274      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4275      if (out != operands[0])
4276         emit_move_insn (operands[0], out);
4277      DONE;
4278    }
4279 })
4280
4281 ;; Signed conversion to SImode.
4282
4283 (define_expand "fix_truncxfsi2"
4284   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4285                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4286               (clobber (reg:CC FLAGS_REG))])]
4287   "TARGET_80387"
4288 {
4289   if (TARGET_FISTTP)
4290    {
4291      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4292      DONE;
4293    }
4294 })
4295
4296 (define_expand "fix_trunc<mode>si2"
4297   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4298                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4299               (clobber (reg:CC FLAGS_REG))])]
4300   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4301 {
4302   if (TARGET_FISTTP
4303       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4304    {
4305      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4306      DONE;
4307    }
4308   if (SSE_FLOAT_MODE_P (<MODE>mode))
4309    {
4310      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4311      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4312      if (out != operands[0])
4313         emit_move_insn (operands[0], out);
4314      DONE;
4315    }
4316 })
4317
4318 ;; Signed conversion to HImode.
4319
4320 (define_expand "fix_trunc<mode>hi2"
4321   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4322                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4323               (clobber (reg:CC FLAGS_REG))])]
4324   "TARGET_80387
4325    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4326 {
4327   if (TARGET_FISTTP)
4328    {
4329      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4330      DONE;
4331    }
4332 })
4333
4334 ;; Unsigned conversion to SImode.
4335
4336 (define_expand "fixuns_trunc<mode>si2"
4337   [(parallel
4338     [(set (match_operand:SI 0 "register_operand" "")
4339           (unsigned_fix:SI
4340             (match_operand:SSEMODEF 1 "nonimmediate_operand" "")))
4341      (use (match_dup 2))
4342      (clobber (match_scratch:<ssevecmode> 3 ""))
4343      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4344   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4345 {
4346   enum machine_mode mode = <MODE>mode;
4347   enum machine_mode vecmode = <ssevecmode>mode;
4348   REAL_VALUE_TYPE TWO31r;
4349   rtx two31;
4350
4351   real_ldexp (&TWO31r, &dconst1, 31);
4352   two31 = const_double_from_real_value (TWO31r, mode);
4353   two31 = ix86_build_const_vector (mode, true, two31);
4354   operands[2] = force_reg (vecmode, two31);
4355 })
4356
4357 (define_insn_and_split "*fixuns_trunc<mode>_1"
4358   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4359         (unsigned_fix:SI
4360           (match_operand:SSEMODEF 3 "nonimmediate_operand" "xm,xm")))
4361    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4362    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4363    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4364   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4365   "#"
4366   "&& reload_completed"
4367   [(const_int 0)]
4368 {
4369   ix86_split_convert_uns_si_sse (operands);
4370   DONE;
4371 })
4372
4373 ;; Unsigned conversion to HImode.
4374 ;; Without these patterns, we'll try the unsigned SI conversion which
4375 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4376
4377 (define_expand "fixuns_truncsfhi2"
4378   [(set (match_dup 2)
4379         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "")))
4380    (set (match_operand:HI 0 "nonimmediate_operand" "")
4381         (subreg:HI (match_dup 2) 0))]
4382   "TARGET_SSE_MATH"
4383   "operands[2] = gen_reg_rtx (SImode);")
4384
4385 (define_expand "fixuns_truncdfhi2"
4386   [(set (match_dup 2)
4387         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "")))
4388    (set (match_operand:HI 0 "nonimmediate_operand" "")
4389         (subreg:HI (match_dup 2) 0))]
4390   "TARGET_SSE_MATH && TARGET_SSE2"
4391   "operands[2] = gen_reg_rtx (SImode);")
4392
4393 ;; When SSE is available, it is always faster to use it!
4394 (define_insn "fix_truncsfdi_sse"
4395   [(set (match_operand:DI 0 "register_operand" "=r,r")
4396         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4397   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4398   "cvttss2si{q}\t{%1, %0|%0, %1}"
4399   [(set_attr "type" "sseicvt")
4400    (set_attr "mode" "SF")
4401    (set_attr "athlon_decode" "double,vector")
4402    (set_attr "amdfam10_decode" "double,double")])
4403
4404 (define_insn "fix_truncdfdi_sse"
4405   [(set (match_operand:DI 0 "register_operand" "=r,r")
4406         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "x,xm")))]
4407   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4408   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4409   [(set_attr "type" "sseicvt")
4410    (set_attr "mode" "DF")
4411    (set_attr "athlon_decode" "double,vector")
4412    (set_attr "amdfam10_decode" "double,double")])
4413
4414 (define_insn "fix_truncsfsi_sse"
4415   [(set (match_operand:SI 0 "register_operand" "=r,r")
4416         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4417   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4418   "cvttss2si\t{%1, %0|%0, %1}"
4419   [(set_attr "type" "sseicvt")
4420    (set_attr "mode" "DF")
4421    (set_attr "athlon_decode" "double,vector")
4422    (set_attr "amdfam10_decode" "double,double")])
4423
4424 (define_insn "fix_truncdfsi_sse"
4425   [(set (match_operand:SI 0 "register_operand" "=r,r")
4426         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "x,xm")))]
4427   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4428   "cvttsd2si\t{%1, %0|%0, %1}"
4429   [(set_attr "type" "sseicvt")
4430    (set_attr "mode" "DF")
4431    (set_attr "athlon_decode" "double,vector")
4432    (set_attr "amdfam10_decode" "double,double")])
4433
4434 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4435 (define_peephole2
4436   [(set (match_operand:DF 0 "register_operand" "")
4437         (match_operand:DF 1 "memory_operand" ""))
4438    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4439         (fix:SSEMODEI24 (match_dup 0)))]
4440   "!TARGET_K8
4441    && peep2_reg_dead_p (2, operands[0])"
4442   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4443   "")
4444
4445 (define_peephole2
4446   [(set (match_operand:SF 0 "register_operand" "")
4447         (match_operand:SF 1 "memory_operand" ""))
4448    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4449         (fix:SSEMODEI24 (match_dup 0)))]
4450   "!TARGET_K8
4451    && peep2_reg_dead_p (2, operands[0])"
4452   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4453   "")
4454
4455 ;; Avoid vector decoded forms of the instruction.
4456 (define_peephole2
4457   [(match_scratch:DF 2 "Y")
4458    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4459         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4460   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4461   [(set (match_dup 2) (match_dup 1))
4462    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4463   "")
4464
4465 (define_peephole2
4466   [(match_scratch:SF 2 "x")
4467    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4468         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4469   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4470   [(set (match_dup 2) (match_dup 1))
4471    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4472   "")
4473
4474 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4475   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4476         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4477   "TARGET_FISTTP
4478    && FLOAT_MODE_P (GET_MODE (operands[1]))
4479    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4480          && (TARGET_64BIT || <MODE>mode != DImode))
4481         && TARGET_SSE_MATH)
4482    && !(reload_completed || reload_in_progress)"
4483   "#"
4484   "&& 1"
4485   [(const_int 0)]
4486 {
4487   if (memory_operand (operands[0], VOIDmode))
4488     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4489   else
4490     {
4491       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4492       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4493                                                             operands[1],
4494                                                             operands[2]));
4495     }
4496   DONE;
4497 }
4498   [(set_attr "type" "fisttp")
4499    (set_attr "mode" "<MODE>")])
4500
4501 (define_insn "fix_trunc<mode>_i387_fisttp"
4502   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4503         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4504    (clobber (match_scratch:XF 2 "=&1f"))]
4505   "TARGET_FISTTP
4506    && FLOAT_MODE_P (GET_MODE (operands[1]))
4507    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4508          && (TARGET_64BIT || <MODE>mode != DImode))
4509         && TARGET_SSE_MATH)"
4510   "* return output_fix_trunc (insn, operands, 1);"
4511   [(set_attr "type" "fisttp")
4512    (set_attr "mode" "<MODE>")])
4513
4514 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4515   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4516         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4517    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4518    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4519   "TARGET_FISTTP
4520    && FLOAT_MODE_P (GET_MODE (operands[1]))
4521    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4522         && (TARGET_64BIT || <MODE>mode != DImode))
4523         && TARGET_SSE_MATH)"
4524   "#"
4525   [(set_attr "type" "fisttp")
4526    (set_attr "mode" "<MODE>")])
4527
4528 (define_split
4529   [(set (match_operand:X87MODEI 0 "register_operand" "")
4530         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4531    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4532    (clobber (match_scratch 3 ""))]
4533   "reload_completed"
4534   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4535               (clobber (match_dup 3))])
4536    (set (match_dup 0) (match_dup 2))]
4537   "")
4538
4539 (define_split
4540   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4541         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4542    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4543    (clobber (match_scratch 3 ""))]
4544   "reload_completed"
4545   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4546               (clobber (match_dup 3))])]
4547   "")
4548
4549 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4550 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4551 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4552 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4553 ;; function in i386.c.
4554 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4555   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4556         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4557    (clobber (reg:CC FLAGS_REG))]
4558   "TARGET_80387 && !TARGET_FISTTP
4559    && FLOAT_MODE_P (GET_MODE (operands[1]))
4560    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4561          && (TARGET_64BIT || <MODE>mode != DImode))
4562    && !(reload_completed || reload_in_progress)"
4563   "#"
4564   "&& 1"
4565   [(const_int 0)]
4566 {
4567   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4568
4569   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4570   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4571   if (memory_operand (operands[0], VOIDmode))
4572     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4573                                          operands[2], operands[3]));
4574   else
4575     {
4576       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4577       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4578                                                      operands[2], operands[3],
4579                                                      operands[4]));
4580     }
4581   DONE;
4582 }
4583   [(set_attr "type" "fistp")
4584    (set_attr "i387_cw" "trunc")
4585    (set_attr "mode" "<MODE>")])
4586
4587 (define_insn "fix_truncdi_i387"
4588   [(set (match_operand:DI 0 "memory_operand" "=m")
4589         (fix:DI (match_operand 1 "register_operand" "f")))
4590    (use (match_operand:HI 2 "memory_operand" "m"))
4591    (use (match_operand:HI 3 "memory_operand" "m"))
4592    (clobber (match_scratch:XF 4 "=&1f"))]
4593   "TARGET_80387 && !TARGET_FISTTP
4594    && FLOAT_MODE_P (GET_MODE (operands[1]))
4595    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4596   "* return output_fix_trunc (insn, operands, 0);"
4597   [(set_attr "type" "fistp")
4598    (set_attr "i387_cw" "trunc")
4599    (set_attr "mode" "DI")])
4600
4601 (define_insn "fix_truncdi_i387_with_temp"
4602   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4603         (fix:DI (match_operand 1 "register_operand" "f,f")))
4604    (use (match_operand:HI 2 "memory_operand" "m,m"))
4605    (use (match_operand:HI 3 "memory_operand" "m,m"))
4606    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4607    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4608   "TARGET_80387 && !TARGET_FISTTP
4609    && FLOAT_MODE_P (GET_MODE (operands[1]))
4610    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4611   "#"
4612   [(set_attr "type" "fistp")
4613    (set_attr "i387_cw" "trunc")
4614    (set_attr "mode" "DI")])
4615
4616 (define_split
4617   [(set (match_operand:DI 0 "register_operand" "")
4618         (fix:DI (match_operand 1 "register_operand" "")))
4619    (use (match_operand:HI 2 "memory_operand" ""))
4620    (use (match_operand:HI 3 "memory_operand" ""))
4621    (clobber (match_operand:DI 4 "memory_operand" ""))
4622    (clobber (match_scratch 5 ""))]
4623   "reload_completed"
4624   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4625               (use (match_dup 2))
4626               (use (match_dup 3))
4627               (clobber (match_dup 5))])
4628    (set (match_dup 0) (match_dup 4))]
4629   "")
4630
4631 (define_split
4632   [(set (match_operand:DI 0 "memory_operand" "")
4633         (fix:DI (match_operand 1 "register_operand" "")))
4634    (use (match_operand:HI 2 "memory_operand" ""))
4635    (use (match_operand:HI 3 "memory_operand" ""))
4636    (clobber (match_operand:DI 4 "memory_operand" ""))
4637    (clobber (match_scratch 5 ""))]
4638   "reload_completed"
4639   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4640               (use (match_dup 2))
4641               (use (match_dup 3))
4642               (clobber (match_dup 5))])]
4643   "")
4644
4645 (define_insn "fix_trunc<mode>_i387"
4646   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4647         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4648    (use (match_operand:HI 2 "memory_operand" "m"))
4649    (use (match_operand:HI 3 "memory_operand" "m"))]
4650   "TARGET_80387 && !TARGET_FISTTP
4651    && FLOAT_MODE_P (GET_MODE (operands[1]))
4652    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4653   "* return output_fix_trunc (insn, operands, 0);"
4654   [(set_attr "type" "fistp")
4655    (set_attr "i387_cw" "trunc")
4656    (set_attr "mode" "<MODE>")])
4657
4658 (define_insn "fix_trunc<mode>_i387_with_temp"
4659   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4660         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4661    (use (match_operand:HI 2 "memory_operand" "m,m"))
4662    (use (match_operand:HI 3 "memory_operand" "m,m"))
4663    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4664   "TARGET_80387 && !TARGET_FISTTP
4665    && FLOAT_MODE_P (GET_MODE (operands[1]))
4666    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4667   "#"
4668   [(set_attr "type" "fistp")
4669    (set_attr "i387_cw" "trunc")
4670    (set_attr "mode" "<MODE>")])
4671
4672 (define_split
4673   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4674         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4675    (use (match_operand:HI 2 "memory_operand" ""))
4676    (use (match_operand:HI 3 "memory_operand" ""))
4677    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4678   "reload_completed"
4679   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4680               (use (match_dup 2))
4681               (use (match_dup 3))])
4682    (set (match_dup 0) (match_dup 4))]
4683   "")
4684
4685 (define_split
4686   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4687         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4688    (use (match_operand:HI 2 "memory_operand" ""))
4689    (use (match_operand:HI 3 "memory_operand" ""))
4690    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4691   "reload_completed"
4692   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4693               (use (match_dup 2))
4694               (use (match_dup 3))])]
4695   "")
4696
4697 (define_insn "x86_fnstcw_1"
4698   [(set (match_operand:HI 0 "memory_operand" "=m")
4699         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4700   "TARGET_80387"
4701   "fnstcw\t%0"
4702   [(set_attr "length" "2")
4703    (set_attr "mode" "HI")
4704    (set_attr "unit" "i387")])
4705
4706 (define_insn "x86_fldcw_1"
4707   [(set (reg:HI FPCR_REG)
4708         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4709   "TARGET_80387"
4710   "fldcw\t%0"
4711   [(set_attr "length" "2")
4712    (set_attr "mode" "HI")
4713    (set_attr "unit" "i387")
4714    (set_attr "athlon_decode" "vector")
4715    (set_attr "amdfam10_decode" "vector")])   
4716 \f
4717 ;; Conversion between fixed point and floating point.
4718
4719 ;; Even though we only accept memory inputs, the backend _really_
4720 ;; wants to be able to do this between registers.
4721
4722 (define_expand "floathisf2"
4723   [(set (match_operand:SF 0 "register_operand" "")
4724         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4725   "TARGET_80387 || TARGET_SSE_MATH"
4726 {
4727   if (TARGET_SSE_MATH)
4728     {
4729       emit_insn (gen_floatsisf2 (operands[0],
4730                                  convert_to_mode (SImode, operands[1], 0)));
4731       DONE;
4732     }
4733 })
4734
4735 (define_insn "*floathisf2_i387"
4736   [(set (match_operand:SF 0 "register_operand" "=f,f")
4737         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4738   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4739   "@
4740    fild%z1\t%1
4741    #"
4742   [(set_attr "type" "fmov,multi")
4743    (set_attr "mode" "SF")
4744    (set_attr "unit" "*,i387")
4745    (set_attr "fp_int_src" "true")])
4746
4747 (define_expand "floatsisf2"
4748   [(set (match_operand:SF 0 "register_operand" "")
4749         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4750   "TARGET_80387 || TARGET_SSE_MATH"
4751   "")
4752
4753 (define_insn "*floatsisf2_mixed"
4754   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4755         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4756   "TARGET_MIX_SSE_I387"
4757   "@
4758    fild%z1\t%1
4759    #
4760    cvtsi2ss\t{%1, %0|%0, %1}
4761    cvtsi2ss\t{%1, %0|%0, %1}"
4762   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4763    (set_attr "mode" "SF")
4764    (set_attr "unit" "*,i387,*,*")
4765    (set_attr "athlon_decode" "*,*,vector,double")
4766    (set_attr "amdfam10_decode" "*,*,vector,double")
4767    (set_attr "fp_int_src" "true")])
4768
4769 (define_insn "*floatsisf2_sse"
4770   [(set (match_operand:SF 0 "register_operand" "=x,x")
4771         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4772   "TARGET_SSE_MATH"
4773   "cvtsi2ss\t{%1, %0|%0, %1}"
4774   [(set_attr "type" "sseicvt")
4775    (set_attr "mode" "SF")
4776    (set_attr "athlon_decode" "vector,double")
4777    (set_attr "amdfam10_decode" "vector,double")
4778    (set_attr "fp_int_src" "true")])
4779
4780 (define_insn "*floatsisf2_i387"
4781   [(set (match_operand:SF 0 "register_operand" "=f,f")
4782         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4783   "TARGET_80387"
4784   "@
4785    fild%z1\t%1
4786    #"
4787   [(set_attr "type" "fmov,multi")
4788    (set_attr "mode" "SF")
4789    (set_attr "unit" "*,i387")
4790    (set_attr "fp_int_src" "true")])
4791
4792 (define_expand "floatdisf2"
4793   [(set (match_operand:SF 0 "register_operand" "")
4794         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4795   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4796   "")
4797
4798 (define_insn "*floatdisf2_mixed"
4799   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4800         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4801   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4802   "@
4803    fild%z1\t%1
4804    #
4805    cvtsi2ss{q}\t{%1, %0|%0, %1}
4806    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4807   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4808    (set_attr "mode" "SF")
4809    (set_attr "unit" "*,i387,*,*")
4810    (set_attr "athlon_decode" "*,*,vector,double")
4811    (set_attr "amdfam10_decode" "*,*,vector,double")
4812    (set_attr "fp_int_src" "true")])
4813
4814 (define_insn "*floatdisf2_sse"
4815   [(set (match_operand:SF 0 "register_operand" "=x,x")
4816         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4817   "TARGET_64BIT && TARGET_SSE_MATH"
4818   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4819   [(set_attr "type" "sseicvt")
4820    (set_attr "mode" "SF")
4821    (set_attr "athlon_decode" "vector,double")
4822    (set_attr "amdfam10_decode" "vector,double")
4823    (set_attr "fp_int_src" "true")])
4824
4825 (define_insn "*floatdisf2_i387"
4826   [(set (match_operand:SF 0 "register_operand" "=f,f")
4827         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4828   "TARGET_80387"
4829   "@
4830    fild%z1\t%1
4831    #"
4832   [(set_attr "type" "fmov,multi")
4833    (set_attr "mode" "SF")
4834    (set_attr "unit" "*,i387")
4835    (set_attr "fp_int_src" "true")])
4836
4837 (define_expand "floathidf2"
4838   [(set (match_operand:DF 0 "register_operand" "")
4839         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4840   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4841 {
4842   if (TARGET_SSE2 && TARGET_SSE_MATH)
4843     {
4844       emit_insn (gen_floatsidf2 (operands[0],
4845                                  convert_to_mode (SImode, operands[1], 0)));
4846       DONE;
4847     }
4848 })
4849
4850 (define_insn "*floathidf2_i387"
4851   [(set (match_operand:DF 0 "register_operand" "=f,f")
4852         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4853   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4854   "@
4855    fild%z1\t%1
4856    #"
4857   [(set_attr "type" "fmov,multi")
4858    (set_attr "mode" "DF")
4859    (set_attr "unit" "*,i387")
4860    (set_attr "fp_int_src" "true")])
4861
4862 (define_expand "floatsidf2"
4863   [(set (match_operand:DF 0 "register_operand" "")
4864         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4865   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4866   "")
4867
4868 (define_insn "*floatsidf2_mixed"
4869   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4870         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4871   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4872   "@
4873    fild%z1\t%1
4874    #
4875    cvtsi2sd\t{%1, %0|%0, %1}
4876    cvtsi2sd\t{%1, %0|%0, %1}"
4877   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4878    (set_attr "mode" "DF")
4879    (set_attr "unit" "*,i387,*,*")
4880    (set_attr "athlon_decode" "*,*,double,direct")
4881    (set_attr "amdfam10_decode" "*,*,vector,double")
4882    (set_attr "fp_int_src" "true")])
4883
4884 (define_insn "*floatsidf2_sse"
4885   [(set (match_operand:DF 0 "register_operand" "=x,x")
4886         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4887   "TARGET_SSE2 && TARGET_SSE_MATH"
4888   "cvtsi2sd\t{%1, %0|%0, %1}"
4889   [(set_attr "type" "sseicvt")
4890    (set_attr "mode" "DF")
4891    (set_attr "athlon_decode" "double,direct")
4892    (set_attr "amdfam10_decode" "vector,double")
4893    (set_attr "fp_int_src" "true")])
4894
4895 (define_insn "*floatsidf2_i387"
4896   [(set (match_operand:DF 0 "register_operand" "=f,f")
4897         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4898   "TARGET_80387"
4899   "@
4900    fild%z1\t%1
4901    #"
4902   [(set_attr "type" "fmov,multi")
4903    (set_attr "mode" "DF")
4904    (set_attr "unit" "*,i387")
4905    (set_attr "fp_int_src" "true")])
4906
4907 (define_expand "floatdidf2"
4908   [(set (match_operand:DF 0 "register_operand" "")
4909         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4910   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4911 {
4912   if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
4913     {
4914       ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
4915       DONE;
4916     }
4917 })
4918
4919 (define_insn "*floatdidf2_mixed"
4920   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4921         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4922   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4923   "@
4924    fild%z1\t%1
4925    #
4926    cvtsi2sd{q}\t{%1, %0|%0, %1}
4927    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4928   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4929    (set_attr "mode" "DF")
4930    (set_attr "unit" "*,i387,*,*")
4931    (set_attr "athlon_decode" "*,*,double,direct")
4932    (set_attr "amdfam10_decode" "*,*,vector,double")
4933    (set_attr "fp_int_src" "true")])
4934
4935 (define_insn "*floatdidf2_sse"
4936   [(set (match_operand:DF 0 "register_operand" "=x,x")
4937         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4938   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4939   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4940   [(set_attr "type" "sseicvt")
4941    (set_attr "mode" "DF")
4942    (set_attr "athlon_decode" "double,direct")
4943    (set_attr "amdfam10_decode" "vector,double")
4944    (set_attr "fp_int_src" "true")])
4945
4946 (define_insn "*floatdidf2_i387"
4947   [(set (match_operand:DF 0 "register_operand" "=f,f")
4948         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4949   "TARGET_80387"
4950   "@
4951    fild%z1\t%1
4952    #"
4953   [(set_attr "type" "fmov,multi")
4954    (set_attr "mode" "DF")
4955    (set_attr "unit" "*,i387")
4956    (set_attr "fp_int_src" "true")])
4957
4958 (define_insn "floathixf2"
4959   [(set (match_operand:XF 0 "register_operand" "=f,f")
4960         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4961   "TARGET_80387"
4962   "@
4963    fild%z1\t%1
4964    #"
4965   [(set_attr "type" "fmov,multi")
4966    (set_attr "mode" "XF")
4967    (set_attr "unit" "*,i387")
4968    (set_attr "fp_int_src" "true")])
4969
4970 (define_insn "floatsixf2"
4971   [(set (match_operand:XF 0 "register_operand" "=f,f")
4972         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4973   "TARGET_80387"
4974   "@
4975    fild%z1\t%1
4976    #"
4977   [(set_attr "type" "fmov,multi")
4978    (set_attr "mode" "XF")
4979    (set_attr "unit" "*,i387")
4980    (set_attr "fp_int_src" "true")])
4981
4982 (define_insn "floatdixf2"
4983   [(set (match_operand:XF 0 "register_operand" "=f,f")
4984         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4985   "TARGET_80387"
4986   "@
4987    fild%z1\t%1
4988    #"
4989   [(set_attr "type" "fmov,multi")
4990    (set_attr "mode" "XF")
4991    (set_attr "unit" "*,i387")
4992    (set_attr "fp_int_src" "true")])
4993
4994 ;; %%% Kill these when reload knows how to do it.
4995 (define_split
4996   [(set (match_operand 0 "fp_register_operand" "")
4997         (float (match_operand 1 "register_operand" "")))]
4998   "reload_completed
4999    && TARGET_80387
5000    && FLOAT_MODE_P (GET_MODE (operands[0]))"
5001   [(const_int 0)]
5002 {
5003   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5004   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5005   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5006   ix86_free_from_memory (GET_MODE (operands[1]));
5007   DONE;
5008 })
5009
5010 (define_expand "floatunssisf2"
5011   [(use (match_operand:SF 0 "register_operand" ""))
5012    (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5013   "!TARGET_64BIT"
5014 {
5015   if (TARGET_SSE_MATH && TARGET_SSE2)
5016     ix86_expand_convert_uns_sisf_sse (operands[0], operands[1]);
5017   else
5018     x86_emit_floatuns (operands);
5019   DONE;
5020 })
5021
5022 (define_expand "floatunssidf2"
5023   [(use (match_operand:DF 0 "register_operand" ""))
5024    (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5025   "!TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE2"
5026   "ix86_expand_convert_uns_sidf_sse (operands[0], operands[1]); DONE;")
5027
5028 (define_expand "floatunsdisf2"
5029   [(use (match_operand:SF 0 "register_operand" ""))
5030    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5031   "TARGET_64BIT && TARGET_SSE_MATH"
5032   "x86_emit_floatuns (operands); DONE;")
5033
5034 (define_expand "floatunsdidf2"
5035   [(use (match_operand:DF 0 "register_operand" ""))
5036    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5037   "TARGET_SSE_MATH && TARGET_SSE2
5038    && (TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)"
5039 {
5040   if (TARGET_64BIT)
5041     x86_emit_floatuns (operands);
5042   else
5043     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5044   DONE;
5045 })
5046 \f
5047 ;; SSE extract/set expanders
5048
5049 \f
5050 ;; Add instructions
5051
5052 ;; %%% splits for addditi3
5053
5054 (define_expand "addti3"
5055   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5056         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5057                  (match_operand:TI 2 "x86_64_general_operand" "")))
5058    (clobber (reg:CC FLAGS_REG))]
5059   "TARGET_64BIT"
5060   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5061
5062 (define_insn "*addti3_1"
5063   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5064         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5065                  (match_operand:TI 2 "general_operand" "roiF,riF")))
5066    (clobber (reg:CC FLAGS_REG))]
5067   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5068   "#")
5069
5070 (define_split
5071   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5072         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5073                  (match_operand:TI 2 "general_operand" "")))
5074    (clobber (reg:CC FLAGS_REG))]
5075   "TARGET_64BIT && reload_completed"
5076   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5077                                           UNSPEC_ADD_CARRY))
5078               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5079    (parallel [(set (match_dup 3)
5080                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5081                                      (match_dup 4))
5082                             (match_dup 5)))
5083               (clobber (reg:CC FLAGS_REG))])]
5084   "split_ti (operands+0, 1, operands+0, operands+3);
5085    split_ti (operands+1, 1, operands+1, operands+4);
5086    split_ti (operands+2, 1, operands+2, operands+5);")
5087
5088 ;; %%% splits for addsidi3
5089 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5090 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5091 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5092
5093 (define_expand "adddi3"
5094   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5095         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5096                  (match_operand:DI 2 "x86_64_general_operand" "")))
5097    (clobber (reg:CC FLAGS_REG))]
5098   ""
5099   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5100
5101 (define_insn "*adddi3_1"
5102   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5103         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5104                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5105    (clobber (reg:CC FLAGS_REG))]
5106   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5107   "#")
5108
5109 (define_split
5110   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5111         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5112                  (match_operand:DI 2 "general_operand" "")))
5113    (clobber (reg:CC FLAGS_REG))]
5114   "!TARGET_64BIT && reload_completed"
5115   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5116                                           UNSPEC_ADD_CARRY))
5117               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5118    (parallel [(set (match_dup 3)
5119                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5120                                      (match_dup 4))
5121                             (match_dup 5)))
5122               (clobber (reg:CC FLAGS_REG))])]
5123   "split_di (operands+0, 1, operands+0, operands+3);
5124    split_di (operands+1, 1, operands+1, operands+4);
5125    split_di (operands+2, 1, operands+2, operands+5);")
5126
5127 (define_insn "adddi3_carry_rex64"
5128   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5129           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5130                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5131                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5132    (clobber (reg:CC FLAGS_REG))]
5133   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5134   "adc{q}\t{%2, %0|%0, %2}"
5135   [(set_attr "type" "alu")
5136    (set_attr "pent_pair" "pu")
5137    (set_attr "mode" "DI")])
5138
5139 (define_insn "*adddi3_cc_rex64"
5140   [(set (reg:CC FLAGS_REG)
5141         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5142                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5143                    UNSPEC_ADD_CARRY))
5144    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5145         (plus:DI (match_dup 1) (match_dup 2)))]
5146   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5147   "add{q}\t{%2, %0|%0, %2}"
5148   [(set_attr "type" "alu")
5149    (set_attr "mode" "DI")])
5150
5151 (define_insn "addqi3_carry"
5152   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5153           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5154                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5155                    (match_operand:QI 2 "general_operand" "qi,qm")))
5156    (clobber (reg:CC FLAGS_REG))]
5157   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5158   "adc{b}\t{%2, %0|%0, %2}"
5159   [(set_attr "type" "alu")
5160    (set_attr "pent_pair" "pu")
5161    (set_attr "mode" "QI")])
5162
5163 (define_insn "addhi3_carry"
5164   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5165           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5166                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5167                    (match_operand:HI 2 "general_operand" "ri,rm")))
5168    (clobber (reg:CC FLAGS_REG))]
5169   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5170   "adc{w}\t{%2, %0|%0, %2}"
5171   [(set_attr "type" "alu")
5172    (set_attr "pent_pair" "pu")
5173    (set_attr "mode" "HI")])
5174
5175 (define_insn "addsi3_carry"
5176   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5177           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5178                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5179                    (match_operand:SI 2 "general_operand" "ri,rm")))
5180    (clobber (reg:CC FLAGS_REG))]
5181   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5182   "adc{l}\t{%2, %0|%0, %2}"
5183   [(set_attr "type" "alu")
5184    (set_attr "pent_pair" "pu")
5185    (set_attr "mode" "SI")])
5186
5187 (define_insn "*addsi3_carry_zext"
5188   [(set (match_operand:DI 0 "register_operand" "=r")
5189           (zero_extend:DI
5190             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5191                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5192                      (match_operand:SI 2 "general_operand" "rim"))))
5193    (clobber (reg:CC FLAGS_REG))]
5194   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5195   "adc{l}\t{%2, %k0|%k0, %2}"
5196   [(set_attr "type" "alu")
5197    (set_attr "pent_pair" "pu")
5198    (set_attr "mode" "SI")])
5199
5200 (define_insn "*addsi3_cc"
5201   [(set (reg:CC FLAGS_REG)
5202         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5203                     (match_operand:SI 2 "general_operand" "ri,rm")]
5204                    UNSPEC_ADD_CARRY))
5205    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5206         (plus:SI (match_dup 1) (match_dup 2)))]
5207   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5208   "add{l}\t{%2, %0|%0, %2}"
5209   [(set_attr "type" "alu")
5210    (set_attr "mode" "SI")])
5211
5212 (define_insn "addqi3_cc"
5213   [(set (reg:CC FLAGS_REG)
5214         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5215                     (match_operand:QI 2 "general_operand" "qi,qm")]
5216                    UNSPEC_ADD_CARRY))
5217    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5218         (plus:QI (match_dup 1) (match_dup 2)))]
5219   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5220   "add{b}\t{%2, %0|%0, %2}"
5221   [(set_attr "type" "alu")
5222    (set_attr "mode" "QI")])
5223
5224 (define_expand "addsi3"
5225   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5226                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5227                             (match_operand:SI 2 "general_operand" "")))
5228               (clobber (reg:CC FLAGS_REG))])]
5229   ""
5230   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5231
5232 (define_insn "*lea_1"
5233   [(set (match_operand:SI 0 "register_operand" "=r")
5234         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5235   "!TARGET_64BIT"
5236   "lea{l}\t{%a1, %0|%0, %a1}"
5237   [(set_attr "type" "lea")
5238    (set_attr "mode" "SI")])
5239
5240 (define_insn "*lea_1_rex64"
5241   [(set (match_operand:SI 0 "register_operand" "=r")
5242         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5243   "TARGET_64BIT"
5244   "lea{l}\t{%a1, %0|%0, %a1}"
5245   [(set_attr "type" "lea")
5246    (set_attr "mode" "SI")])
5247
5248 (define_insn "*lea_1_zext"
5249   [(set (match_operand:DI 0 "register_operand" "=r")
5250         (zero_extend:DI
5251          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5252   "TARGET_64BIT"
5253   "lea{l}\t{%a1, %k0|%k0, %a1}"
5254   [(set_attr "type" "lea")
5255    (set_attr "mode" "SI")])
5256
5257 (define_insn "*lea_2_rex64"
5258   [(set (match_operand:DI 0 "register_operand" "=r")
5259         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5260   "TARGET_64BIT"
5261   "lea{q}\t{%a1, %0|%0, %a1}"
5262   [(set_attr "type" "lea")
5263    (set_attr "mode" "DI")])
5264
5265 ;; The lea patterns for non-Pmodes needs to be matched by several
5266 ;; insns converted to real lea by splitters.
5267
5268 (define_insn_and_split "*lea_general_1"
5269   [(set (match_operand 0 "register_operand" "=r")
5270         (plus (plus (match_operand 1 "index_register_operand" "l")
5271                     (match_operand 2 "register_operand" "r"))
5272               (match_operand 3 "immediate_operand" "i")))]
5273   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5274     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5275    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5276    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5277    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5278    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5279        || GET_MODE (operands[3]) == VOIDmode)"
5280   "#"
5281   "&& reload_completed"
5282   [(const_int 0)]
5283 {
5284   rtx pat;
5285   operands[0] = gen_lowpart (SImode, operands[0]);
5286   operands[1] = gen_lowpart (Pmode, operands[1]);
5287   operands[2] = gen_lowpart (Pmode, operands[2]);
5288   operands[3] = gen_lowpart (Pmode, operands[3]);
5289   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5290                       operands[3]);
5291   if (Pmode != SImode)
5292     pat = gen_rtx_SUBREG (SImode, pat, 0);
5293   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5294   DONE;
5295 }
5296   [(set_attr "type" "lea")
5297    (set_attr "mode" "SI")])
5298
5299 (define_insn_and_split "*lea_general_1_zext"
5300   [(set (match_operand:DI 0 "register_operand" "=r")
5301         (zero_extend:DI
5302           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5303                             (match_operand:SI 2 "register_operand" "r"))
5304                    (match_operand:SI 3 "immediate_operand" "i"))))]
5305   "TARGET_64BIT"
5306   "#"
5307   "&& reload_completed"
5308   [(set (match_dup 0)
5309         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5310                                                      (match_dup 2))
5311                                             (match_dup 3)) 0)))]
5312 {
5313   operands[1] = gen_lowpart (Pmode, operands[1]);
5314   operands[2] = gen_lowpart (Pmode, operands[2]);
5315   operands[3] = gen_lowpart (Pmode, operands[3]);
5316 }
5317   [(set_attr "type" "lea")
5318    (set_attr "mode" "SI")])
5319
5320 (define_insn_and_split "*lea_general_2"
5321   [(set (match_operand 0 "register_operand" "=r")
5322         (plus (mult (match_operand 1 "index_register_operand" "l")
5323                     (match_operand 2 "const248_operand" "i"))
5324               (match_operand 3 "nonmemory_operand" "ri")))]
5325   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5326     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5327    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5328    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5329    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5330        || GET_MODE (operands[3]) == VOIDmode)"
5331   "#"
5332   "&& reload_completed"
5333   [(const_int 0)]
5334 {
5335   rtx pat;
5336   operands[0] = gen_lowpart (SImode, operands[0]);
5337   operands[1] = gen_lowpart (Pmode, operands[1]);
5338   operands[3] = gen_lowpart (Pmode, operands[3]);
5339   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5340                       operands[3]);
5341   if (Pmode != SImode)
5342     pat = gen_rtx_SUBREG (SImode, pat, 0);
5343   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5344   DONE;
5345 }
5346   [(set_attr "type" "lea")
5347    (set_attr "mode" "SI")])
5348
5349 (define_insn_and_split "*lea_general_2_zext"
5350   [(set (match_operand:DI 0 "register_operand" "=r")
5351         (zero_extend:DI
5352           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5353                             (match_operand:SI 2 "const248_operand" "n"))
5354                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5355   "TARGET_64BIT"
5356   "#"
5357   "&& reload_completed"
5358   [(set (match_dup 0)
5359         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5360                                                      (match_dup 2))
5361                                             (match_dup 3)) 0)))]
5362 {
5363   operands[1] = gen_lowpart (Pmode, operands[1]);
5364   operands[3] = gen_lowpart (Pmode, operands[3]);
5365 }
5366   [(set_attr "type" "lea")
5367    (set_attr "mode" "SI")])
5368
5369 (define_insn_and_split "*lea_general_3"
5370   [(set (match_operand 0 "register_operand" "=r")
5371         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5372                           (match_operand 2 "const248_operand" "i"))
5373                     (match_operand 3 "register_operand" "r"))
5374               (match_operand 4 "immediate_operand" "i")))]
5375   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5376     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5377    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5378    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5379    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5380   "#"
5381   "&& reload_completed"
5382   [(const_int 0)]
5383 {
5384   rtx pat;
5385   operands[0] = gen_lowpart (SImode, operands[0]);
5386   operands[1] = gen_lowpart (Pmode, operands[1]);
5387   operands[3] = gen_lowpart (Pmode, operands[3]);
5388   operands[4] = gen_lowpart (Pmode, operands[4]);
5389   pat = gen_rtx_PLUS (Pmode,
5390                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5391                                                          operands[2]),
5392                                     operands[3]),
5393                       operands[4]);
5394   if (Pmode != SImode)
5395     pat = gen_rtx_SUBREG (SImode, pat, 0);
5396   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5397   DONE;
5398 }
5399   [(set_attr "type" "lea")
5400    (set_attr "mode" "SI")])
5401
5402 (define_insn_and_split "*lea_general_3_zext"
5403   [(set (match_operand:DI 0 "register_operand" "=r")
5404         (zero_extend:DI
5405           (plus:SI (plus:SI (mult:SI
5406                               (match_operand:SI 1 "index_register_operand" "l")
5407                               (match_operand:SI 2 "const248_operand" "n"))
5408                             (match_operand:SI 3 "register_operand" "r"))
5409                    (match_operand:SI 4 "immediate_operand" "i"))))]
5410   "TARGET_64BIT"
5411   "#"
5412   "&& reload_completed"
5413   [(set (match_dup 0)
5414         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5415                                                               (match_dup 2))
5416                                                      (match_dup 3))
5417                                             (match_dup 4)) 0)))]
5418 {
5419   operands[1] = gen_lowpart (Pmode, operands[1]);
5420   operands[3] = gen_lowpart (Pmode, operands[3]);
5421   operands[4] = gen_lowpart (Pmode, operands[4]);
5422 }
5423   [(set_attr "type" "lea")
5424    (set_attr "mode" "SI")])
5425
5426 (define_insn "*adddi_1_rex64"
5427   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5428         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5429                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5430    (clobber (reg:CC FLAGS_REG))]
5431   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5432 {
5433   switch (get_attr_type (insn))
5434     {
5435     case TYPE_LEA:
5436       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5437       return "lea{q}\t{%a2, %0|%0, %a2}";
5438
5439     case TYPE_INCDEC:
5440       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5441       if (operands[2] == const1_rtx)
5442         return "inc{q}\t%0";
5443       else
5444         {
5445           gcc_assert (operands[2] == constm1_rtx);
5446           return "dec{q}\t%0";
5447         }
5448
5449     default:
5450       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5451
5452       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5453          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5454       if (CONST_INT_P (operands[2])
5455           /* Avoid overflows.  */
5456           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5457           && (INTVAL (operands[2]) == 128
5458               || (INTVAL (operands[2]) < 0
5459                   && INTVAL (operands[2]) != -128)))
5460         {
5461           operands[2] = GEN_INT (-INTVAL (operands[2]));
5462           return "sub{q}\t{%2, %0|%0, %2}";
5463         }
5464       return "add{q}\t{%2, %0|%0, %2}";
5465     }
5466 }
5467   [(set (attr "type")
5468      (cond [(eq_attr "alternative" "2")
5469               (const_string "lea")
5470             ; Current assemblers are broken and do not allow @GOTOFF in
5471             ; ought but a memory context.
5472             (match_operand:DI 2 "pic_symbolic_operand" "")
5473               (const_string "lea")
5474             (match_operand:DI 2 "incdec_operand" "")
5475               (const_string "incdec")
5476            ]
5477            (const_string "alu")))
5478    (set_attr "mode" "DI")])
5479
5480 ;; Convert lea to the lea pattern to avoid flags dependency.
5481 (define_split
5482   [(set (match_operand:DI 0 "register_operand" "")
5483         (plus:DI (match_operand:DI 1 "register_operand" "")
5484                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5485    (clobber (reg:CC FLAGS_REG))]
5486   "TARGET_64BIT && reload_completed
5487    && true_regnum (operands[0]) != true_regnum (operands[1])"
5488   [(set (match_dup 0)
5489         (plus:DI (match_dup 1)
5490                  (match_dup 2)))]
5491   "")
5492
5493 (define_insn "*adddi_2_rex64"
5494   [(set (reg FLAGS_REG)
5495         (compare
5496           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5497                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5498           (const_int 0)))
5499    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5500         (plus:DI (match_dup 1) (match_dup 2)))]
5501   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5502    && ix86_binary_operator_ok (PLUS, DImode, operands)
5503    /* Current assemblers are broken and do not allow @GOTOFF in
5504       ought but a memory context.  */
5505    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5506 {
5507   switch (get_attr_type (insn))
5508     {
5509     case TYPE_INCDEC:
5510       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5511       if (operands[2] == const1_rtx)
5512         return "inc{q}\t%0";
5513       else
5514         {
5515           gcc_assert (operands[2] == constm1_rtx);
5516           return "dec{q}\t%0";
5517         }
5518
5519     default:
5520       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5521       /* ???? We ought to handle there the 32bit case too
5522          - do we need new constraint?  */
5523       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5524          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5525       if (CONST_INT_P (operands[2])
5526           /* Avoid overflows.  */
5527           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5528           && (INTVAL (operands[2]) == 128
5529               || (INTVAL (operands[2]) < 0
5530                   && INTVAL (operands[2]) != -128)))
5531         {
5532           operands[2] = GEN_INT (-INTVAL (operands[2]));
5533           return "sub{q}\t{%2, %0|%0, %2}";
5534         }
5535       return "add{q}\t{%2, %0|%0, %2}";
5536     }
5537 }
5538   [(set (attr "type")
5539      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5540         (const_string "incdec")
5541         (const_string "alu")))
5542    (set_attr "mode" "DI")])
5543
5544 (define_insn "*adddi_3_rex64"
5545   [(set (reg FLAGS_REG)
5546         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5547                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5548    (clobber (match_scratch:DI 0 "=r"))]
5549   "TARGET_64BIT
5550    && ix86_match_ccmode (insn, CCZmode)
5551    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5552    /* Current assemblers are broken and do not allow @GOTOFF in
5553       ought but a memory context.  */
5554    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5555 {
5556   switch (get_attr_type (insn))
5557     {
5558     case TYPE_INCDEC:
5559       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5560       if (operands[2] == const1_rtx)
5561         return "inc{q}\t%0";
5562       else
5563         {
5564           gcc_assert (operands[2] == constm1_rtx);
5565           return "dec{q}\t%0";
5566         }
5567
5568     default:
5569       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5570       /* ???? We ought to handle there the 32bit case too
5571          - do we need new constraint?  */
5572       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5573          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5574       if (CONST_INT_P (operands[2])
5575           /* Avoid overflows.  */
5576           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5577           && (INTVAL (operands[2]) == 128
5578               || (INTVAL (operands[2]) < 0
5579                   && INTVAL (operands[2]) != -128)))
5580         {
5581           operands[2] = GEN_INT (-INTVAL (operands[2]));
5582           return "sub{q}\t{%2, %0|%0, %2}";
5583         }
5584       return "add{q}\t{%2, %0|%0, %2}";
5585     }
5586 }
5587   [(set (attr "type")
5588      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5589         (const_string "incdec")
5590         (const_string "alu")))
5591    (set_attr "mode" "DI")])
5592
5593 ; For comparisons against 1, -1 and 128, we may generate better code
5594 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5595 ; is matched then.  We can't accept general immediate, because for
5596 ; case of overflows,  the result is messed up.
5597 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5598 ; when negated.
5599 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5600 ; only for comparisons not depending on it.
5601 (define_insn "*adddi_4_rex64"
5602   [(set (reg FLAGS_REG)
5603         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5604                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5605    (clobber (match_scratch:DI 0 "=rm"))]
5606   "TARGET_64BIT
5607    &&  ix86_match_ccmode (insn, CCGCmode)"
5608 {
5609   switch (get_attr_type (insn))
5610     {
5611     case TYPE_INCDEC:
5612       if (operands[2] == constm1_rtx)
5613         return "inc{q}\t%0";
5614       else
5615         {
5616           gcc_assert (operands[2] == const1_rtx);
5617           return "dec{q}\t%0";
5618         }
5619
5620     default:
5621       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5622       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5623          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5624       if ((INTVAL (operands[2]) == -128
5625            || (INTVAL (operands[2]) > 0
5626                && INTVAL (operands[2]) != 128))
5627           /* Avoid overflows.  */
5628           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5629         return "sub{q}\t{%2, %0|%0, %2}";
5630       operands[2] = GEN_INT (-INTVAL (operands[2]));
5631       return "add{q}\t{%2, %0|%0, %2}";
5632     }
5633 }
5634   [(set (attr "type")
5635      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5636         (const_string "incdec")
5637         (const_string "alu")))
5638    (set_attr "mode" "DI")])
5639
5640 (define_insn "*adddi_5_rex64"
5641   [(set (reg FLAGS_REG)
5642         (compare
5643           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5644                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5645           (const_int 0)))
5646    (clobber (match_scratch:DI 0 "=r"))]
5647   "TARGET_64BIT
5648    && ix86_match_ccmode (insn, CCGOCmode)
5649    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5650    /* Current assemblers are broken and do not allow @GOTOFF in
5651       ought but a memory context.  */
5652    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5653 {
5654   switch (get_attr_type (insn))
5655     {
5656     case TYPE_INCDEC:
5657       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5658       if (operands[2] == const1_rtx)
5659         return "inc{q}\t%0";
5660       else
5661         {
5662           gcc_assert (operands[2] == constm1_rtx);
5663           return "dec{q}\t%0";
5664         }
5665
5666     default:
5667       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5668       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5669          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5670       if (CONST_INT_P (operands[2])
5671           /* Avoid overflows.  */
5672           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5673           && (INTVAL (operands[2]) == 128
5674               || (INTVAL (operands[2]) < 0
5675                   && INTVAL (operands[2]) != -128)))
5676         {
5677           operands[2] = GEN_INT (-INTVAL (operands[2]));
5678           return "sub{q}\t{%2, %0|%0, %2}";
5679         }
5680       return "add{q}\t{%2, %0|%0, %2}";
5681     }
5682 }
5683   [(set (attr "type")
5684      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5685         (const_string "incdec")
5686         (const_string "alu")))
5687    (set_attr "mode" "DI")])
5688
5689
5690 (define_insn "*addsi_1"
5691   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5692         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5693                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5694    (clobber (reg:CC FLAGS_REG))]
5695   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5696 {
5697   switch (get_attr_type (insn))
5698     {
5699     case TYPE_LEA:
5700       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5701       return "lea{l}\t{%a2, %0|%0, %a2}";
5702
5703     case TYPE_INCDEC:
5704       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5705       if (operands[2] == const1_rtx)
5706         return "inc{l}\t%0";
5707       else
5708         {
5709           gcc_assert (operands[2] == constm1_rtx);
5710           return "dec{l}\t%0";
5711         }
5712
5713     default:
5714       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5715
5716       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5717          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5718       if (CONST_INT_P (operands[2])
5719           && (INTVAL (operands[2]) == 128
5720               || (INTVAL (operands[2]) < 0
5721                   && INTVAL (operands[2]) != -128)))
5722         {
5723           operands[2] = GEN_INT (-INTVAL (operands[2]));
5724           return "sub{l}\t{%2, %0|%0, %2}";
5725         }
5726       return "add{l}\t{%2, %0|%0, %2}";
5727     }
5728 }
5729   [(set (attr "type")
5730      (cond [(eq_attr "alternative" "2")
5731               (const_string "lea")
5732             ; Current assemblers are broken and do not allow @GOTOFF in
5733             ; ought but a memory context.
5734             (match_operand:SI 2 "pic_symbolic_operand" "")
5735               (const_string "lea")
5736             (match_operand:SI 2 "incdec_operand" "")
5737               (const_string "incdec")
5738            ]
5739            (const_string "alu")))
5740    (set_attr "mode" "SI")])
5741
5742 ;; Convert lea to the lea pattern to avoid flags dependency.
5743 (define_split
5744   [(set (match_operand 0 "register_operand" "")
5745         (plus (match_operand 1 "register_operand" "")
5746               (match_operand 2 "nonmemory_operand" "")))
5747    (clobber (reg:CC FLAGS_REG))]
5748   "reload_completed
5749    && true_regnum (operands[0]) != true_regnum (operands[1])"
5750   [(const_int 0)]
5751 {
5752   rtx pat;
5753   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5754      may confuse gen_lowpart.  */
5755   if (GET_MODE (operands[0]) != Pmode)
5756     {
5757       operands[1] = gen_lowpart (Pmode, operands[1]);
5758       operands[2] = gen_lowpart (Pmode, operands[2]);
5759     }
5760   operands[0] = gen_lowpart (SImode, operands[0]);
5761   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5762   if (Pmode != SImode)
5763     pat = gen_rtx_SUBREG (SImode, pat, 0);
5764   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5765   DONE;
5766 })
5767
5768 ;; It may seem that nonimmediate operand is proper one for operand 1.
5769 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5770 ;; we take care in ix86_binary_operator_ok to not allow two memory
5771 ;; operands so proper swapping will be done in reload.  This allow
5772 ;; patterns constructed from addsi_1 to match.
5773 (define_insn "addsi_1_zext"
5774   [(set (match_operand:DI 0 "register_operand" "=r,r")
5775         (zero_extend:DI
5776           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5777                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5778    (clobber (reg:CC FLAGS_REG))]
5779   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5780 {
5781   switch (get_attr_type (insn))
5782     {
5783     case TYPE_LEA:
5784       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5785       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5786
5787     case TYPE_INCDEC:
5788       if (operands[2] == const1_rtx)
5789         return "inc{l}\t%k0";
5790       else
5791         {
5792           gcc_assert (operands[2] == constm1_rtx);
5793           return "dec{l}\t%k0";
5794         }
5795
5796     default:
5797       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5798          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5799       if (CONST_INT_P (operands[2])
5800           && (INTVAL (operands[2]) == 128
5801               || (INTVAL (operands[2]) < 0
5802                   && INTVAL (operands[2]) != -128)))
5803         {
5804           operands[2] = GEN_INT (-INTVAL (operands[2]));
5805           return "sub{l}\t{%2, %k0|%k0, %2}";
5806         }
5807       return "add{l}\t{%2, %k0|%k0, %2}";
5808     }
5809 }
5810   [(set (attr "type")
5811      (cond [(eq_attr "alternative" "1")
5812               (const_string "lea")
5813             ; Current assemblers are broken and do not allow @GOTOFF in
5814             ; ought but a memory context.
5815             (match_operand:SI 2 "pic_symbolic_operand" "")
5816               (const_string "lea")
5817             (match_operand:SI 2 "incdec_operand" "")
5818               (const_string "incdec")
5819            ]
5820            (const_string "alu")))
5821    (set_attr "mode" "SI")])
5822
5823 ;; Convert lea to the lea pattern to avoid flags dependency.
5824 (define_split
5825   [(set (match_operand:DI 0 "register_operand" "")
5826         (zero_extend:DI
5827           (plus:SI (match_operand:SI 1 "register_operand" "")
5828                    (match_operand:SI 2 "nonmemory_operand" ""))))
5829    (clobber (reg:CC FLAGS_REG))]
5830   "TARGET_64BIT && reload_completed
5831    && true_regnum (operands[0]) != true_regnum (operands[1])"
5832   [(set (match_dup 0)
5833         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5834 {
5835   operands[1] = gen_lowpart (Pmode, operands[1]);
5836   operands[2] = gen_lowpart (Pmode, operands[2]);
5837 })
5838
5839 (define_insn "*addsi_2"
5840   [(set (reg FLAGS_REG)
5841         (compare
5842           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5843                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5844           (const_int 0)))
5845    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5846         (plus:SI (match_dup 1) (match_dup 2)))]
5847   "ix86_match_ccmode (insn, CCGOCmode)
5848    && ix86_binary_operator_ok (PLUS, SImode, operands)
5849    /* Current assemblers are broken and do not allow @GOTOFF in
5850       ought but a memory context.  */
5851    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5852 {
5853   switch (get_attr_type (insn))
5854     {
5855     case TYPE_INCDEC:
5856       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5857       if (operands[2] == const1_rtx)
5858         return "inc{l}\t%0";
5859       else
5860         {
5861           gcc_assert (operands[2] == constm1_rtx);
5862           return "dec{l}\t%0";
5863         }
5864
5865     default:
5866       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5867       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5868          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5869       if (CONST_INT_P (operands[2])
5870           && (INTVAL (operands[2]) == 128
5871               || (INTVAL (operands[2]) < 0
5872                   && INTVAL (operands[2]) != -128)))
5873         {
5874           operands[2] = GEN_INT (-INTVAL (operands[2]));
5875           return "sub{l}\t{%2, %0|%0, %2}";
5876         }
5877       return "add{l}\t{%2, %0|%0, %2}";
5878     }
5879 }
5880   [(set (attr "type")
5881      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5882         (const_string "incdec")
5883         (const_string "alu")))
5884    (set_attr "mode" "SI")])
5885
5886 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5887 (define_insn "*addsi_2_zext"
5888   [(set (reg FLAGS_REG)
5889         (compare
5890           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5891                    (match_operand:SI 2 "general_operand" "rmni"))
5892           (const_int 0)))
5893    (set (match_operand:DI 0 "register_operand" "=r")
5894         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5895   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5896    && ix86_binary_operator_ok (PLUS, SImode, operands)
5897    /* Current assemblers are broken and do not allow @GOTOFF in
5898       ought but a memory context.  */
5899    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5900 {
5901   switch (get_attr_type (insn))
5902     {
5903     case TYPE_INCDEC:
5904       if (operands[2] == const1_rtx)
5905         return "inc{l}\t%k0";
5906       else
5907         {
5908           gcc_assert (operands[2] == constm1_rtx);
5909           return "dec{l}\t%k0";
5910         }
5911
5912     default:
5913       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5914          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5915       if (CONST_INT_P (operands[2])
5916           && (INTVAL (operands[2]) == 128
5917               || (INTVAL (operands[2]) < 0
5918                   && INTVAL (operands[2]) != -128)))
5919         {
5920           operands[2] = GEN_INT (-INTVAL (operands[2]));
5921           return "sub{l}\t{%2, %k0|%k0, %2}";
5922         }
5923       return "add{l}\t{%2, %k0|%k0, %2}";
5924     }
5925 }
5926   [(set (attr "type")
5927      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5928         (const_string "incdec")
5929         (const_string "alu")))
5930    (set_attr "mode" "SI")])
5931
5932 (define_insn "*addsi_3"
5933   [(set (reg FLAGS_REG)
5934         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5935                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5936    (clobber (match_scratch:SI 0 "=r"))]
5937   "ix86_match_ccmode (insn, CCZmode)
5938    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5939    /* Current assemblers are broken and do not allow @GOTOFF in
5940       ought but a memory context.  */
5941    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5942 {
5943   switch (get_attr_type (insn))
5944     {
5945     case TYPE_INCDEC:
5946       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5947       if (operands[2] == const1_rtx)
5948         return "inc{l}\t%0";
5949       else
5950         {
5951           gcc_assert (operands[2] == constm1_rtx);
5952           return "dec{l}\t%0";
5953         }
5954
5955     default:
5956       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5957       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5958          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5959       if (CONST_INT_P (operands[2])
5960           && (INTVAL (operands[2]) == 128
5961               || (INTVAL (operands[2]) < 0
5962                   && INTVAL (operands[2]) != -128)))
5963         {
5964           operands[2] = GEN_INT (-INTVAL (operands[2]));
5965           return "sub{l}\t{%2, %0|%0, %2}";
5966         }
5967       return "add{l}\t{%2, %0|%0, %2}";
5968     }
5969 }
5970   [(set (attr "type")
5971      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5972         (const_string "incdec")
5973         (const_string "alu")))
5974    (set_attr "mode" "SI")])
5975
5976 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5977 (define_insn "*addsi_3_zext"
5978   [(set (reg FLAGS_REG)
5979         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5980                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5981    (set (match_operand:DI 0 "register_operand" "=r")
5982         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5983   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5984    && ix86_binary_operator_ok (PLUS, SImode, operands)
5985    /* Current assemblers are broken and do not allow @GOTOFF in
5986       ought but a memory context.  */
5987    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5988 {
5989   switch (get_attr_type (insn))
5990     {
5991     case TYPE_INCDEC:
5992       if (operands[2] == const1_rtx)
5993         return "inc{l}\t%k0";
5994       else
5995         {
5996           gcc_assert (operands[2] == constm1_rtx);
5997           return "dec{l}\t%k0";
5998         }
5999
6000     default:
6001       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6002          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6003       if (CONST_INT_P (operands[2])
6004           && (INTVAL (operands[2]) == 128
6005               || (INTVAL (operands[2]) < 0
6006                   && INTVAL (operands[2]) != -128)))
6007         {
6008           operands[2] = GEN_INT (-INTVAL (operands[2]));
6009           return "sub{l}\t{%2, %k0|%k0, %2}";
6010         }
6011       return "add{l}\t{%2, %k0|%k0, %2}";
6012     }
6013 }
6014   [(set (attr "type")
6015      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6016         (const_string "incdec")
6017         (const_string "alu")))
6018    (set_attr "mode" "SI")])
6019
6020 ; For comparisons against 1, -1 and 128, we may generate better code
6021 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6022 ; is matched then.  We can't accept general immediate, because for
6023 ; case of overflows,  the result is messed up.
6024 ; This pattern also don't hold of 0x80000000, since the value overflows
6025 ; when negated.
6026 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6027 ; only for comparisons not depending on it.
6028 (define_insn "*addsi_4"
6029   [(set (reg FLAGS_REG)
6030         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6031                  (match_operand:SI 2 "const_int_operand" "n")))
6032    (clobber (match_scratch:SI 0 "=rm"))]
6033   "ix86_match_ccmode (insn, CCGCmode)
6034    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6035 {
6036   switch (get_attr_type (insn))
6037     {
6038     case TYPE_INCDEC:
6039       if (operands[2] == constm1_rtx)
6040         return "inc{l}\t%0";
6041       else
6042         {
6043           gcc_assert (operands[2] == const1_rtx);
6044           return "dec{l}\t%0";
6045         }
6046
6047     default:
6048       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6049       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6050          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6051       if ((INTVAL (operands[2]) == -128
6052            || (INTVAL (operands[2]) > 0
6053                && INTVAL (operands[2]) != 128)))
6054         return "sub{l}\t{%2, %0|%0, %2}";
6055       operands[2] = GEN_INT (-INTVAL (operands[2]));
6056       return "add{l}\t{%2, %0|%0, %2}";
6057     }
6058 }
6059   [(set (attr "type")
6060      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6061         (const_string "incdec")
6062         (const_string "alu")))
6063    (set_attr "mode" "SI")])
6064
6065 (define_insn "*addsi_5"
6066   [(set (reg FLAGS_REG)
6067         (compare
6068           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6069                    (match_operand:SI 2 "general_operand" "rmni"))
6070           (const_int 0)))
6071    (clobber (match_scratch:SI 0 "=r"))]
6072   "ix86_match_ccmode (insn, CCGOCmode)
6073    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6074    /* Current assemblers are broken and do not allow @GOTOFF in
6075       ought but a memory context.  */
6076    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6077 {
6078   switch (get_attr_type (insn))
6079     {
6080     case TYPE_INCDEC:
6081       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6082       if (operands[2] == const1_rtx)
6083         return "inc{l}\t%0";
6084       else
6085         {
6086           gcc_assert (operands[2] == constm1_rtx);
6087           return "dec{l}\t%0";
6088         }
6089
6090     default:
6091       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6092       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6093          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6094       if (CONST_INT_P (operands[2])
6095           && (INTVAL (operands[2]) == 128
6096               || (INTVAL (operands[2]) < 0
6097                   && INTVAL (operands[2]) != -128)))
6098         {
6099           operands[2] = GEN_INT (-INTVAL (operands[2]));
6100           return "sub{l}\t{%2, %0|%0, %2}";
6101         }
6102       return "add{l}\t{%2, %0|%0, %2}";
6103     }
6104 }
6105   [(set (attr "type")
6106      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6107         (const_string "incdec")
6108         (const_string "alu")))
6109    (set_attr "mode" "SI")])
6110
6111 (define_expand "addhi3"
6112   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6113                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6114                             (match_operand:HI 2 "general_operand" "")))
6115               (clobber (reg:CC FLAGS_REG))])]
6116   "TARGET_HIMODE_MATH"
6117   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6118
6119 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6120 ;; type optimizations enabled by define-splits.  This is not important
6121 ;; for PII, and in fact harmful because of partial register stalls.
6122
6123 (define_insn "*addhi_1_lea"
6124   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6125         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6126                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6127    (clobber (reg:CC FLAGS_REG))]
6128   "!TARGET_PARTIAL_REG_STALL
6129    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6130 {
6131   switch (get_attr_type (insn))
6132     {
6133     case TYPE_LEA:
6134       return "#";
6135     case TYPE_INCDEC:
6136       if (operands[2] == const1_rtx)
6137         return "inc{w}\t%0";
6138       else
6139         {
6140           gcc_assert (operands[2] == constm1_rtx);
6141           return "dec{w}\t%0";
6142         }
6143
6144     default:
6145       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6146          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6147       if (CONST_INT_P (operands[2])
6148           && (INTVAL (operands[2]) == 128
6149               || (INTVAL (operands[2]) < 0
6150                   && INTVAL (operands[2]) != -128)))
6151         {
6152           operands[2] = GEN_INT (-INTVAL (operands[2]));
6153           return "sub{w}\t{%2, %0|%0, %2}";
6154         }
6155       return "add{w}\t{%2, %0|%0, %2}";
6156     }
6157 }
6158   [(set (attr "type")
6159      (if_then_else (eq_attr "alternative" "2")
6160         (const_string "lea")
6161         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6162            (const_string "incdec")
6163            (const_string "alu"))))
6164    (set_attr "mode" "HI,HI,SI")])
6165
6166 (define_insn "*addhi_1"
6167   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6168         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6169                  (match_operand:HI 2 "general_operand" "ri,rm")))
6170    (clobber (reg:CC FLAGS_REG))]
6171   "TARGET_PARTIAL_REG_STALL
6172    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6173 {
6174   switch (get_attr_type (insn))
6175     {
6176     case TYPE_INCDEC:
6177       if (operands[2] == const1_rtx)
6178         return "inc{w}\t%0";
6179       else
6180         {
6181           gcc_assert (operands[2] == constm1_rtx);
6182           return "dec{w}\t%0";
6183         }
6184
6185     default:
6186       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6187          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6188       if (CONST_INT_P (operands[2])
6189           && (INTVAL (operands[2]) == 128
6190               || (INTVAL (operands[2]) < 0
6191                   && INTVAL (operands[2]) != -128)))
6192         {
6193           operands[2] = GEN_INT (-INTVAL (operands[2]));
6194           return "sub{w}\t{%2, %0|%0, %2}";
6195         }
6196       return "add{w}\t{%2, %0|%0, %2}";
6197     }
6198 }
6199   [(set (attr "type")
6200      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6201         (const_string "incdec")
6202         (const_string "alu")))
6203    (set_attr "mode" "HI")])
6204
6205 (define_insn "*addhi_2"
6206   [(set (reg FLAGS_REG)
6207         (compare
6208           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6209                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6210           (const_int 0)))
6211    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6212         (plus:HI (match_dup 1) (match_dup 2)))]
6213   "ix86_match_ccmode (insn, CCGOCmode)
6214    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6215 {
6216   switch (get_attr_type (insn))
6217     {
6218     case TYPE_INCDEC:
6219       if (operands[2] == const1_rtx)
6220         return "inc{w}\t%0";
6221       else
6222         {
6223           gcc_assert (operands[2] == constm1_rtx);
6224           return "dec{w}\t%0";
6225         }
6226
6227     default:
6228       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6229          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6230       if (CONST_INT_P (operands[2])
6231           && (INTVAL (operands[2]) == 128
6232               || (INTVAL (operands[2]) < 0
6233                   && INTVAL (operands[2]) != -128)))
6234         {
6235           operands[2] = GEN_INT (-INTVAL (operands[2]));
6236           return "sub{w}\t{%2, %0|%0, %2}";
6237         }
6238       return "add{w}\t{%2, %0|%0, %2}";
6239     }
6240 }
6241   [(set (attr "type")
6242      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6243         (const_string "incdec")
6244         (const_string "alu")))
6245    (set_attr "mode" "HI")])
6246
6247 (define_insn "*addhi_3"
6248   [(set (reg FLAGS_REG)
6249         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6250                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6251    (clobber (match_scratch:HI 0 "=r"))]
6252   "ix86_match_ccmode (insn, CCZmode)
6253    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6254 {
6255   switch (get_attr_type (insn))
6256     {
6257     case TYPE_INCDEC:
6258       if (operands[2] == const1_rtx)
6259         return "inc{w}\t%0";
6260       else
6261         {
6262           gcc_assert (operands[2] == constm1_rtx);
6263           return "dec{w}\t%0";
6264         }
6265
6266     default:
6267       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6268          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6269       if (CONST_INT_P (operands[2])
6270           && (INTVAL (operands[2]) == 128
6271               || (INTVAL (operands[2]) < 0
6272                   && INTVAL (operands[2]) != -128)))
6273         {
6274           operands[2] = GEN_INT (-INTVAL (operands[2]));
6275           return "sub{w}\t{%2, %0|%0, %2}";
6276         }
6277       return "add{w}\t{%2, %0|%0, %2}";
6278     }
6279 }
6280   [(set (attr "type")
6281      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6282         (const_string "incdec")
6283         (const_string "alu")))
6284    (set_attr "mode" "HI")])
6285
6286 ; See comments above addsi_4 for details.
6287 (define_insn "*addhi_4"
6288   [(set (reg FLAGS_REG)
6289         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6290                  (match_operand:HI 2 "const_int_operand" "n")))
6291    (clobber (match_scratch:HI 0 "=rm"))]
6292   "ix86_match_ccmode (insn, CCGCmode)
6293    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6294 {
6295   switch (get_attr_type (insn))
6296     {
6297     case TYPE_INCDEC:
6298       if (operands[2] == constm1_rtx)
6299         return "inc{w}\t%0";
6300       else
6301         {
6302           gcc_assert (operands[2] == const1_rtx);
6303           return "dec{w}\t%0";
6304         }
6305
6306     default:
6307       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6308       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6309          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6310       if ((INTVAL (operands[2]) == -128
6311            || (INTVAL (operands[2]) > 0
6312                && INTVAL (operands[2]) != 128)))
6313         return "sub{w}\t{%2, %0|%0, %2}";
6314       operands[2] = GEN_INT (-INTVAL (operands[2]));
6315       return "add{w}\t{%2, %0|%0, %2}";
6316     }
6317 }
6318   [(set (attr "type")
6319      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6320         (const_string "incdec")
6321         (const_string "alu")))
6322    (set_attr "mode" "SI")])
6323
6324
6325 (define_insn "*addhi_5"
6326   [(set (reg FLAGS_REG)
6327         (compare
6328           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6329                    (match_operand:HI 2 "general_operand" "rmni"))
6330           (const_int 0)))
6331    (clobber (match_scratch:HI 0 "=r"))]
6332   "ix86_match_ccmode (insn, CCGOCmode)
6333    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6334 {
6335   switch (get_attr_type (insn))
6336     {
6337     case TYPE_INCDEC:
6338       if (operands[2] == const1_rtx)
6339         return "inc{w}\t%0";
6340       else
6341         {
6342           gcc_assert (operands[2] == constm1_rtx);
6343           return "dec{w}\t%0";
6344         }
6345
6346     default:
6347       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6348          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6349       if (CONST_INT_P (operands[2])
6350           && (INTVAL (operands[2]) == 128
6351               || (INTVAL (operands[2]) < 0
6352                   && INTVAL (operands[2]) != -128)))
6353         {
6354           operands[2] = GEN_INT (-INTVAL (operands[2]));
6355           return "sub{w}\t{%2, %0|%0, %2}";
6356         }
6357       return "add{w}\t{%2, %0|%0, %2}";
6358     }
6359 }
6360   [(set (attr "type")
6361      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6362         (const_string "incdec")
6363         (const_string "alu")))
6364    (set_attr "mode" "HI")])
6365
6366 (define_expand "addqi3"
6367   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6368                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6369                             (match_operand:QI 2 "general_operand" "")))
6370               (clobber (reg:CC FLAGS_REG))])]
6371   "TARGET_QIMODE_MATH"
6372   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6373
6374 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6375 (define_insn "*addqi_1_lea"
6376   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6377         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6378                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6379    (clobber (reg:CC FLAGS_REG))]
6380   "!TARGET_PARTIAL_REG_STALL
6381    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6382 {
6383   int widen = (which_alternative == 2);
6384   switch (get_attr_type (insn))
6385     {
6386     case TYPE_LEA:
6387       return "#";
6388     case TYPE_INCDEC:
6389       if (operands[2] == const1_rtx)
6390         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6391       else
6392         {
6393           gcc_assert (operands[2] == constm1_rtx);
6394           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6395         }
6396
6397     default:
6398       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6399          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6400       if (CONST_INT_P (operands[2])
6401           && (INTVAL (operands[2]) == 128
6402               || (INTVAL (operands[2]) < 0
6403                   && INTVAL (operands[2]) != -128)))
6404         {
6405           operands[2] = GEN_INT (-INTVAL (operands[2]));
6406           if (widen)
6407             return "sub{l}\t{%2, %k0|%k0, %2}";
6408           else
6409             return "sub{b}\t{%2, %0|%0, %2}";
6410         }
6411       if (widen)
6412         return "add{l}\t{%k2, %k0|%k0, %k2}";
6413       else
6414         return "add{b}\t{%2, %0|%0, %2}";
6415     }
6416 }
6417   [(set (attr "type")
6418      (if_then_else (eq_attr "alternative" "3")
6419         (const_string "lea")
6420         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6421            (const_string "incdec")
6422            (const_string "alu"))))
6423    (set_attr "mode" "QI,QI,SI,SI")])
6424
6425 (define_insn "*addqi_1"
6426   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6427         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6428                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6429    (clobber (reg:CC FLAGS_REG))]
6430   "TARGET_PARTIAL_REG_STALL
6431    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6432 {
6433   int widen = (which_alternative == 2);
6434   switch (get_attr_type (insn))
6435     {
6436     case TYPE_INCDEC:
6437       if (operands[2] == const1_rtx)
6438         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6439       else
6440         {
6441           gcc_assert (operands[2] == constm1_rtx);
6442           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6443         }
6444
6445     default:
6446       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6447          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6448       if (CONST_INT_P (operands[2])
6449           && (INTVAL (operands[2]) == 128
6450               || (INTVAL (operands[2]) < 0
6451                   && INTVAL (operands[2]) != -128)))
6452         {
6453           operands[2] = GEN_INT (-INTVAL (operands[2]));
6454           if (widen)
6455             return "sub{l}\t{%2, %k0|%k0, %2}";
6456           else
6457             return "sub{b}\t{%2, %0|%0, %2}";
6458         }
6459       if (widen)
6460         return "add{l}\t{%k2, %k0|%k0, %k2}";
6461       else
6462         return "add{b}\t{%2, %0|%0, %2}";
6463     }
6464 }
6465   [(set (attr "type")
6466      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6467         (const_string "incdec")
6468         (const_string "alu")))
6469    (set_attr "mode" "QI,QI,SI")])
6470
6471 (define_insn "*addqi_1_slp"
6472   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6473         (plus:QI (match_dup 0)
6474                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6475    (clobber (reg:CC FLAGS_REG))]
6476   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6477    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6478 {
6479   switch (get_attr_type (insn))
6480     {
6481     case TYPE_INCDEC:
6482       if (operands[1] == const1_rtx)
6483         return "inc{b}\t%0";
6484       else
6485         {
6486           gcc_assert (operands[1] == constm1_rtx);
6487           return "dec{b}\t%0";
6488         }
6489
6490     default:
6491       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6492       if (CONST_INT_P (operands[1])
6493           && INTVAL (operands[1]) < 0)
6494         {
6495           operands[1] = GEN_INT (-INTVAL (operands[1]));
6496           return "sub{b}\t{%1, %0|%0, %1}";
6497         }
6498       return "add{b}\t{%1, %0|%0, %1}";
6499     }
6500 }
6501   [(set (attr "type")
6502      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6503         (const_string "incdec")
6504         (const_string "alu1")))
6505    (set (attr "memory")
6506      (if_then_else (match_operand 1 "memory_operand" "")
6507         (const_string "load")
6508         (const_string "none")))
6509    (set_attr "mode" "QI")])
6510
6511 (define_insn "*addqi_2"
6512   [(set (reg FLAGS_REG)
6513         (compare
6514           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6515                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6516           (const_int 0)))
6517    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6518         (plus:QI (match_dup 1) (match_dup 2)))]
6519   "ix86_match_ccmode (insn, CCGOCmode)
6520    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6521 {
6522   switch (get_attr_type (insn))
6523     {
6524     case TYPE_INCDEC:
6525       if (operands[2] == const1_rtx)
6526         return "inc{b}\t%0";
6527       else
6528         {
6529           gcc_assert (operands[2] == constm1_rtx
6530                       || (CONST_INT_P (operands[2])
6531                           && INTVAL (operands[2]) == 255));
6532           return "dec{b}\t%0";
6533         }
6534
6535     default:
6536       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6537       if (CONST_INT_P (operands[2])
6538           && INTVAL (operands[2]) < 0)
6539         {
6540           operands[2] = GEN_INT (-INTVAL (operands[2]));
6541           return "sub{b}\t{%2, %0|%0, %2}";
6542         }
6543       return "add{b}\t{%2, %0|%0, %2}";
6544     }
6545 }
6546   [(set (attr "type")
6547      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6548         (const_string "incdec")
6549         (const_string "alu")))
6550    (set_attr "mode" "QI")])
6551
6552 (define_insn "*addqi_3"
6553   [(set (reg FLAGS_REG)
6554         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6555                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6556    (clobber (match_scratch:QI 0 "=q"))]
6557   "ix86_match_ccmode (insn, CCZmode)
6558    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6559 {
6560   switch (get_attr_type (insn))
6561     {
6562     case TYPE_INCDEC:
6563       if (operands[2] == const1_rtx)
6564         return "inc{b}\t%0";
6565       else
6566         {
6567           gcc_assert (operands[2] == constm1_rtx
6568                       || (CONST_INT_P (operands[2])
6569                           && INTVAL (operands[2]) == 255));
6570           return "dec{b}\t%0";
6571         }
6572
6573     default:
6574       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6575       if (CONST_INT_P (operands[2])
6576           && INTVAL (operands[2]) < 0)
6577         {
6578           operands[2] = GEN_INT (-INTVAL (operands[2]));
6579           return "sub{b}\t{%2, %0|%0, %2}";
6580         }
6581       return "add{b}\t{%2, %0|%0, %2}";
6582     }
6583 }
6584   [(set (attr "type")
6585      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6586         (const_string "incdec")
6587         (const_string "alu")))
6588    (set_attr "mode" "QI")])
6589
6590 ; See comments above addsi_4 for details.
6591 (define_insn "*addqi_4"
6592   [(set (reg FLAGS_REG)
6593         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6594                  (match_operand:QI 2 "const_int_operand" "n")))
6595    (clobber (match_scratch:QI 0 "=qm"))]
6596   "ix86_match_ccmode (insn, CCGCmode)
6597    && (INTVAL (operands[2]) & 0xff) != 0x80"
6598 {
6599   switch (get_attr_type (insn))
6600     {
6601     case TYPE_INCDEC:
6602       if (operands[2] == constm1_rtx
6603           || (CONST_INT_P (operands[2])
6604               && INTVAL (operands[2]) == 255))
6605         return "inc{b}\t%0";
6606       else
6607         {
6608           gcc_assert (operands[2] == const1_rtx);
6609           return "dec{b}\t%0";
6610         }
6611
6612     default:
6613       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6614       if (INTVAL (operands[2]) < 0)
6615         {
6616           operands[2] = GEN_INT (-INTVAL (operands[2]));
6617           return "add{b}\t{%2, %0|%0, %2}";
6618         }
6619       return "sub{b}\t{%2, %0|%0, %2}";
6620     }
6621 }
6622   [(set (attr "type")
6623      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6624         (const_string "incdec")
6625         (const_string "alu")))
6626    (set_attr "mode" "QI")])
6627
6628
6629 (define_insn "*addqi_5"
6630   [(set (reg FLAGS_REG)
6631         (compare
6632           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6633                    (match_operand:QI 2 "general_operand" "qmni"))
6634           (const_int 0)))
6635    (clobber (match_scratch:QI 0 "=q"))]
6636   "ix86_match_ccmode (insn, CCGOCmode)
6637    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6638 {
6639   switch (get_attr_type (insn))
6640     {
6641     case TYPE_INCDEC:
6642       if (operands[2] == const1_rtx)
6643         return "inc{b}\t%0";
6644       else
6645         {
6646           gcc_assert (operands[2] == constm1_rtx
6647                       || (CONST_INT_P (operands[2])
6648                           && INTVAL (operands[2]) == 255));
6649           return "dec{b}\t%0";
6650         }
6651
6652     default:
6653       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6654       if (CONST_INT_P (operands[2])
6655           && INTVAL (operands[2]) < 0)
6656         {
6657           operands[2] = GEN_INT (-INTVAL (operands[2]));
6658           return "sub{b}\t{%2, %0|%0, %2}";
6659         }
6660       return "add{b}\t{%2, %0|%0, %2}";
6661     }
6662 }
6663   [(set (attr "type")
6664      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6665         (const_string "incdec")
6666         (const_string "alu")))
6667    (set_attr "mode" "QI")])
6668
6669
6670 (define_insn "addqi_ext_1"
6671   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6672                          (const_int 8)
6673                          (const_int 8))
6674         (plus:SI
6675           (zero_extract:SI
6676             (match_operand 1 "ext_register_operand" "0")
6677             (const_int 8)
6678             (const_int 8))
6679           (match_operand:QI 2 "general_operand" "Qmn")))
6680    (clobber (reg:CC FLAGS_REG))]
6681   "!TARGET_64BIT"
6682 {
6683   switch (get_attr_type (insn))
6684     {
6685     case TYPE_INCDEC:
6686       if (operands[2] == const1_rtx)
6687         return "inc{b}\t%h0";
6688       else
6689         {
6690           gcc_assert (operands[2] == constm1_rtx
6691                       || (CONST_INT_P (operands[2])
6692                           && INTVAL (operands[2]) == 255));
6693           return "dec{b}\t%h0";
6694         }
6695
6696     default:
6697       return "add{b}\t{%2, %h0|%h0, %2}";
6698     }
6699 }
6700   [(set (attr "type")
6701      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6702         (const_string "incdec")
6703         (const_string "alu")))
6704    (set_attr "mode" "QI")])
6705
6706 (define_insn "*addqi_ext_1_rex64"
6707   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6708                          (const_int 8)
6709                          (const_int 8))
6710         (plus:SI
6711           (zero_extract:SI
6712             (match_operand 1 "ext_register_operand" "0")
6713             (const_int 8)
6714             (const_int 8))
6715           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6716    (clobber (reg:CC FLAGS_REG))]
6717   "TARGET_64BIT"
6718 {
6719   switch (get_attr_type (insn))
6720     {
6721     case TYPE_INCDEC:
6722       if (operands[2] == const1_rtx)
6723         return "inc{b}\t%h0";
6724       else
6725         {
6726           gcc_assert (operands[2] == constm1_rtx
6727                       || (CONST_INT_P (operands[2])
6728                           && INTVAL (operands[2]) == 255));
6729           return "dec{b}\t%h0";
6730         }
6731
6732     default:
6733       return "add{b}\t{%2, %h0|%h0, %2}";
6734     }
6735 }
6736   [(set (attr "type")
6737      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6738         (const_string "incdec")
6739         (const_string "alu")))
6740    (set_attr "mode" "QI")])
6741
6742 (define_insn "*addqi_ext_2"
6743   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6744                          (const_int 8)
6745                          (const_int 8))
6746         (plus:SI
6747           (zero_extract:SI
6748             (match_operand 1 "ext_register_operand" "%0")
6749             (const_int 8)
6750             (const_int 8))
6751           (zero_extract:SI
6752             (match_operand 2 "ext_register_operand" "Q")
6753             (const_int 8)
6754             (const_int 8))))
6755    (clobber (reg:CC FLAGS_REG))]
6756   ""
6757   "add{b}\t{%h2, %h0|%h0, %h2}"
6758   [(set_attr "type" "alu")
6759    (set_attr "mode" "QI")])
6760
6761 ;; The patterns that match these are at the end of this file.
6762
6763 (define_expand "addxf3"
6764   [(set (match_operand:XF 0 "register_operand" "")
6765         (plus:XF (match_operand:XF 1 "register_operand" "")
6766                  (match_operand:XF 2 "register_operand" "")))]
6767   "TARGET_80387"
6768   "")
6769
6770 (define_expand "adddf3"
6771   [(set (match_operand:DF 0 "register_operand" "")
6772         (plus:DF (match_operand:DF 1 "register_operand" "")
6773                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6774   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6775   "")
6776
6777 (define_expand "addsf3"
6778   [(set (match_operand:SF 0 "register_operand" "")
6779         (plus:SF (match_operand:SF 1 "register_operand" "")
6780                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6781   "TARGET_80387 || TARGET_SSE_MATH"
6782   "")
6783 \f
6784 ;; Subtract instructions
6785
6786 ;; %%% splits for subditi3
6787
6788 (define_expand "subti3"
6789   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6790                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6791                              (match_operand:TI 2 "x86_64_general_operand" "")))
6792               (clobber (reg:CC FLAGS_REG))])]
6793   "TARGET_64BIT"
6794   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6795
6796 (define_insn "*subti3_1"
6797   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6798         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6799                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6800    (clobber (reg:CC FLAGS_REG))]
6801   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6802   "#")
6803
6804 (define_split
6805   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6806         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6807                   (match_operand:TI 2 "general_operand" "")))
6808    (clobber (reg:CC FLAGS_REG))]
6809   "TARGET_64BIT && reload_completed"
6810   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6811               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6812    (parallel [(set (match_dup 3)
6813                    (minus:DI (match_dup 4)
6814                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6815                                       (match_dup 5))))
6816               (clobber (reg:CC FLAGS_REG))])]
6817   "split_ti (operands+0, 1, operands+0, operands+3);
6818    split_ti (operands+1, 1, operands+1, operands+4);
6819    split_ti (operands+2, 1, operands+2, operands+5);")
6820
6821 ;; %%% splits for subsidi3
6822
6823 (define_expand "subdi3"
6824   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6825                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6826                              (match_operand:DI 2 "x86_64_general_operand" "")))
6827               (clobber (reg:CC FLAGS_REG))])]
6828   ""
6829   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6830
6831 (define_insn "*subdi3_1"
6832   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6833         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6834                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6835    (clobber (reg:CC FLAGS_REG))]
6836   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6837   "#")
6838
6839 (define_split
6840   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6841         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6842                   (match_operand:DI 2 "general_operand" "")))
6843    (clobber (reg:CC FLAGS_REG))]
6844   "!TARGET_64BIT && reload_completed"
6845   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6846               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6847    (parallel [(set (match_dup 3)
6848                    (minus:SI (match_dup 4)
6849                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6850                                       (match_dup 5))))
6851               (clobber (reg:CC FLAGS_REG))])]
6852   "split_di (operands+0, 1, operands+0, operands+3);
6853    split_di (operands+1, 1, operands+1, operands+4);
6854    split_di (operands+2, 1, operands+2, operands+5);")
6855
6856 (define_insn "subdi3_carry_rex64"
6857   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6858           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6859             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6860                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6861    (clobber (reg:CC FLAGS_REG))]
6862   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6863   "sbb{q}\t{%2, %0|%0, %2}"
6864   [(set_attr "type" "alu")
6865    (set_attr "pent_pair" "pu")
6866    (set_attr "mode" "DI")])
6867
6868 (define_insn "*subdi_1_rex64"
6869   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6870         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6871                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6872    (clobber (reg:CC FLAGS_REG))]
6873   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6874   "sub{q}\t{%2, %0|%0, %2}"
6875   [(set_attr "type" "alu")
6876    (set_attr "mode" "DI")])
6877
6878 (define_insn "*subdi_2_rex64"
6879   [(set (reg FLAGS_REG)
6880         (compare
6881           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6882                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6883           (const_int 0)))
6884    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6885         (minus:DI (match_dup 1) (match_dup 2)))]
6886   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6887    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6888   "sub{q}\t{%2, %0|%0, %2}"
6889   [(set_attr "type" "alu")
6890    (set_attr "mode" "DI")])
6891
6892 (define_insn "*subdi_3_rex63"
6893   [(set (reg FLAGS_REG)
6894         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6895                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6896    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6897         (minus:DI (match_dup 1) (match_dup 2)))]
6898   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6899    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6900   "sub{q}\t{%2, %0|%0, %2}"
6901   [(set_attr "type" "alu")
6902    (set_attr "mode" "DI")])
6903
6904 (define_insn "subqi3_carry"
6905   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6906           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6907             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6908                (match_operand:QI 2 "general_operand" "qi,qm"))))
6909    (clobber (reg:CC FLAGS_REG))]
6910   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6911   "sbb{b}\t{%2, %0|%0, %2}"
6912   [(set_attr "type" "alu")
6913    (set_attr "pent_pair" "pu")
6914    (set_attr "mode" "QI")])
6915
6916 (define_insn "subhi3_carry"
6917   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6918           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6919             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6920                (match_operand:HI 2 "general_operand" "ri,rm"))))
6921    (clobber (reg:CC FLAGS_REG))]
6922   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6923   "sbb{w}\t{%2, %0|%0, %2}"
6924   [(set_attr "type" "alu")
6925    (set_attr "pent_pair" "pu")
6926    (set_attr "mode" "HI")])
6927
6928 (define_insn "subsi3_carry"
6929   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6930           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6931             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6932                (match_operand:SI 2 "general_operand" "ri,rm"))))
6933    (clobber (reg:CC FLAGS_REG))]
6934   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6935   "sbb{l}\t{%2, %0|%0, %2}"
6936   [(set_attr "type" "alu")
6937    (set_attr "pent_pair" "pu")
6938    (set_attr "mode" "SI")])
6939
6940 (define_insn "subsi3_carry_zext"
6941   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6942           (zero_extend:DI
6943             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6944               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6945                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6946    (clobber (reg:CC FLAGS_REG))]
6947   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6948   "sbb{l}\t{%2, %k0|%k0, %2}"
6949   [(set_attr "type" "alu")
6950    (set_attr "pent_pair" "pu")
6951    (set_attr "mode" "SI")])
6952
6953 (define_expand "subsi3"
6954   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6955                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6956                              (match_operand:SI 2 "general_operand" "")))
6957               (clobber (reg:CC FLAGS_REG))])]
6958   ""
6959   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6960
6961 (define_insn "*subsi_1"
6962   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6963         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6964                   (match_operand:SI 2 "general_operand" "ri,rm")))
6965    (clobber (reg:CC FLAGS_REG))]
6966   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6967   "sub{l}\t{%2, %0|%0, %2}"
6968   [(set_attr "type" "alu")
6969    (set_attr "mode" "SI")])
6970
6971 (define_insn "*subsi_1_zext"
6972   [(set (match_operand:DI 0 "register_operand" "=r")
6973         (zero_extend:DI
6974           (minus:SI (match_operand:SI 1 "register_operand" "0")
6975                     (match_operand:SI 2 "general_operand" "rim"))))
6976    (clobber (reg:CC FLAGS_REG))]
6977   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6978   "sub{l}\t{%2, %k0|%k0, %2}"
6979   [(set_attr "type" "alu")
6980    (set_attr "mode" "SI")])
6981
6982 (define_insn "*subsi_2"
6983   [(set (reg FLAGS_REG)
6984         (compare
6985           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6986                     (match_operand:SI 2 "general_operand" "ri,rm"))
6987           (const_int 0)))
6988    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6989         (minus:SI (match_dup 1) (match_dup 2)))]
6990   "ix86_match_ccmode (insn, CCGOCmode)
6991    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6992   "sub{l}\t{%2, %0|%0, %2}"
6993   [(set_attr "type" "alu")
6994    (set_attr "mode" "SI")])
6995
6996 (define_insn "*subsi_2_zext"
6997   [(set (reg FLAGS_REG)
6998         (compare
6999           (minus:SI (match_operand:SI 1 "register_operand" "0")
7000                     (match_operand:SI 2 "general_operand" "rim"))
7001           (const_int 0)))
7002    (set (match_operand:DI 0 "register_operand" "=r")
7003         (zero_extend:DI
7004           (minus:SI (match_dup 1)
7005                     (match_dup 2))))]
7006   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7007    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7008   "sub{l}\t{%2, %k0|%k0, %2}"
7009   [(set_attr "type" "alu")
7010    (set_attr "mode" "SI")])
7011
7012 (define_insn "*subsi_3"
7013   [(set (reg FLAGS_REG)
7014         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7015                  (match_operand:SI 2 "general_operand" "ri,rm")))
7016    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7017         (minus:SI (match_dup 1) (match_dup 2)))]
7018   "ix86_match_ccmode (insn, CCmode)
7019    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7020   "sub{l}\t{%2, %0|%0, %2}"
7021   [(set_attr "type" "alu")
7022    (set_attr "mode" "SI")])
7023
7024 (define_insn "*subsi_3_zext"
7025   [(set (reg FLAGS_REG)
7026         (compare (match_operand:SI 1 "register_operand" "0")
7027                  (match_operand:SI 2 "general_operand" "rim")))
7028    (set (match_operand:DI 0 "register_operand" "=r")
7029         (zero_extend:DI
7030           (minus:SI (match_dup 1)
7031                     (match_dup 2))))]
7032   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7033    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7034   "sub{l}\t{%2, %1|%1, %2}"
7035   [(set_attr "type" "alu")
7036    (set_attr "mode" "DI")])
7037
7038 (define_expand "subhi3"
7039   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7040                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7041                              (match_operand:HI 2 "general_operand" "")))
7042               (clobber (reg:CC FLAGS_REG))])]
7043   "TARGET_HIMODE_MATH"
7044   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7045
7046 (define_insn "*subhi_1"
7047   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7048         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7049                   (match_operand:HI 2 "general_operand" "ri,rm")))
7050    (clobber (reg:CC FLAGS_REG))]
7051   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7052   "sub{w}\t{%2, %0|%0, %2}"
7053   [(set_attr "type" "alu")
7054    (set_attr "mode" "HI")])
7055
7056 (define_insn "*subhi_2"
7057   [(set (reg FLAGS_REG)
7058         (compare
7059           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7060                     (match_operand:HI 2 "general_operand" "ri,rm"))
7061           (const_int 0)))
7062    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7063         (minus:HI (match_dup 1) (match_dup 2)))]
7064   "ix86_match_ccmode (insn, CCGOCmode)
7065    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7066   "sub{w}\t{%2, %0|%0, %2}"
7067   [(set_attr "type" "alu")
7068    (set_attr "mode" "HI")])
7069
7070 (define_insn "*subhi_3"
7071   [(set (reg FLAGS_REG)
7072         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7073                  (match_operand:HI 2 "general_operand" "ri,rm")))
7074    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7075         (minus:HI (match_dup 1) (match_dup 2)))]
7076   "ix86_match_ccmode (insn, CCmode)
7077    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7078   "sub{w}\t{%2, %0|%0, %2}"
7079   [(set_attr "type" "alu")
7080    (set_attr "mode" "HI")])
7081
7082 (define_expand "subqi3"
7083   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7084                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7085                              (match_operand:QI 2 "general_operand" "")))
7086               (clobber (reg:CC FLAGS_REG))])]
7087   "TARGET_QIMODE_MATH"
7088   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7089
7090 (define_insn "*subqi_1"
7091   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7092         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7093                   (match_operand:QI 2 "general_operand" "qn,qmn")))
7094    (clobber (reg:CC FLAGS_REG))]
7095   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7096   "sub{b}\t{%2, %0|%0, %2}"
7097   [(set_attr "type" "alu")
7098    (set_attr "mode" "QI")])
7099
7100 (define_insn "*subqi_1_slp"
7101   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7102         (minus:QI (match_dup 0)
7103                   (match_operand:QI 1 "general_operand" "qn,qmn")))
7104    (clobber (reg:CC FLAGS_REG))]
7105   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7106    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7107   "sub{b}\t{%1, %0|%0, %1}"
7108   [(set_attr "type" "alu1")
7109    (set_attr "mode" "QI")])
7110
7111 (define_insn "*subqi_2"
7112   [(set (reg FLAGS_REG)
7113         (compare
7114           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7115                     (match_operand:QI 2 "general_operand" "qi,qm"))
7116           (const_int 0)))
7117    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7118         (minus:HI (match_dup 1) (match_dup 2)))]
7119   "ix86_match_ccmode (insn, CCGOCmode)
7120    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7121   "sub{b}\t{%2, %0|%0, %2}"
7122   [(set_attr "type" "alu")
7123    (set_attr "mode" "QI")])
7124
7125 (define_insn "*subqi_3"
7126   [(set (reg FLAGS_REG)
7127         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7128                  (match_operand:QI 2 "general_operand" "qi,qm")))
7129    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7130         (minus:HI (match_dup 1) (match_dup 2)))]
7131   "ix86_match_ccmode (insn, CCmode)
7132    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7133   "sub{b}\t{%2, %0|%0, %2}"
7134   [(set_attr "type" "alu")
7135    (set_attr "mode" "QI")])
7136
7137 ;; The patterns that match these are at the end of this file.
7138
7139 (define_expand "subxf3"
7140   [(set (match_operand:XF 0 "register_operand" "")
7141         (minus:XF (match_operand:XF 1 "register_operand" "")
7142                   (match_operand:XF 2 "register_operand" "")))]
7143   "TARGET_80387"
7144   "")
7145
7146 (define_expand "subdf3"
7147   [(set (match_operand:DF 0 "register_operand" "")
7148         (minus:DF (match_operand:DF 1 "register_operand" "")
7149                   (match_operand:DF 2 "nonimmediate_operand" "")))]
7150   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7151   "")
7152
7153 (define_expand "subsf3"
7154   [(set (match_operand:SF 0 "register_operand" "")
7155         (minus:SF (match_operand:SF 1 "register_operand" "")
7156                   (match_operand:SF 2 "nonimmediate_operand" "")))]
7157   "TARGET_80387 || TARGET_SSE_MATH"
7158   "")
7159 \f
7160 ;; Multiply instructions
7161
7162 (define_expand "muldi3"
7163   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7164                    (mult:DI (match_operand:DI 1 "register_operand" "")
7165                             (match_operand:DI 2 "x86_64_general_operand" "")))
7166               (clobber (reg:CC FLAGS_REG))])]
7167   "TARGET_64BIT"
7168   "")
7169
7170 ;; On AMDFAM10 
7171 ;; IMUL reg64, reg64, imm8      Direct
7172 ;; IMUL reg64, mem64, imm8      VectorPath
7173 ;; IMUL reg64, reg64, imm32     Direct
7174 ;; IMUL reg64, mem64, imm32     VectorPath 
7175 ;; IMUL reg64, reg64            Direct
7176 ;; IMUL reg64, mem64            Direct
7177
7178 (define_insn "*muldi3_1_rex64"
7179   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7180         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7181                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7182    (clobber (reg:CC FLAGS_REG))]
7183   "TARGET_64BIT
7184    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7185   "@
7186    imul{q}\t{%2, %1, %0|%0, %1, %2}
7187    imul{q}\t{%2, %1, %0|%0, %1, %2}
7188    imul{q}\t{%2, %0|%0, %2}"
7189   [(set_attr "type" "imul")
7190    (set_attr "prefix_0f" "0,0,1")
7191    (set (attr "athlon_decode")
7192         (cond [(eq_attr "cpu" "athlon")
7193                   (const_string "vector")
7194                (eq_attr "alternative" "1")
7195                   (const_string "vector")
7196                (and (eq_attr "alternative" "2")
7197                     (match_operand 1 "memory_operand" ""))
7198                   (const_string "vector")]
7199               (const_string "direct")))
7200    (set (attr "amdfam10_decode")
7201         (cond [(and (eq_attr "alternative" "0,1")
7202                     (match_operand 1 "memory_operand" ""))
7203                   (const_string "vector")]
7204               (const_string "direct")))       
7205    (set_attr "mode" "DI")])
7206
7207 (define_expand "mulsi3"
7208   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7209                    (mult:SI (match_operand:SI 1 "register_operand" "")
7210                             (match_operand:SI 2 "general_operand" "")))
7211               (clobber (reg:CC FLAGS_REG))])]
7212   ""
7213   "")
7214
7215 ;; On AMDFAM10 
7216 ;; IMUL reg32, reg32, imm8      Direct
7217 ;; IMUL reg32, mem32, imm8      VectorPath
7218 ;; IMUL reg32, reg32, imm32     Direct
7219 ;; IMUL reg32, mem32, imm32     VectorPath
7220 ;; IMUL reg32, reg32            Direct
7221 ;; IMUL reg32, mem32            Direct
7222
7223 (define_insn "*mulsi3_1"
7224   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7225         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7226                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7227    (clobber (reg:CC FLAGS_REG))]
7228   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7229   "@
7230    imul{l}\t{%2, %1, %0|%0, %1, %2}
7231    imul{l}\t{%2, %1, %0|%0, %1, %2}
7232    imul{l}\t{%2, %0|%0, %2}"
7233   [(set_attr "type" "imul")
7234    (set_attr "prefix_0f" "0,0,1")
7235    (set (attr "athlon_decode")
7236         (cond [(eq_attr "cpu" "athlon")
7237                   (const_string "vector")
7238                (eq_attr "alternative" "1")
7239                   (const_string "vector")
7240                (and (eq_attr "alternative" "2")
7241                     (match_operand 1 "memory_operand" ""))
7242                   (const_string "vector")]
7243               (const_string "direct")))
7244    (set (attr "amdfam10_decode")
7245         (cond [(and (eq_attr "alternative" "0,1")
7246                     (match_operand 1 "memory_operand" ""))
7247                   (const_string "vector")]
7248               (const_string "direct")))       
7249    (set_attr "mode" "SI")])
7250
7251 (define_insn "*mulsi3_1_zext"
7252   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7253         (zero_extend:DI
7254           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7255                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7256    (clobber (reg:CC FLAGS_REG))]
7257   "TARGET_64BIT
7258    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7259   "@
7260    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7261    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7262    imul{l}\t{%2, %k0|%k0, %2}"
7263   [(set_attr "type" "imul")
7264    (set_attr "prefix_0f" "0,0,1")
7265    (set (attr "athlon_decode")
7266         (cond [(eq_attr "cpu" "athlon")
7267                   (const_string "vector")
7268                (eq_attr "alternative" "1")
7269                   (const_string "vector")
7270                (and (eq_attr "alternative" "2")
7271                     (match_operand 1 "memory_operand" ""))
7272                   (const_string "vector")]
7273               (const_string "direct")))
7274    (set (attr "amdfam10_decode")
7275         (cond [(and (eq_attr "alternative" "0,1")
7276                     (match_operand 1 "memory_operand" ""))
7277                   (const_string "vector")]
7278               (const_string "direct")))       
7279    (set_attr "mode" "SI")])
7280
7281 (define_expand "mulhi3"
7282   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7283                    (mult:HI (match_operand:HI 1 "register_operand" "")
7284                             (match_operand:HI 2 "general_operand" "")))
7285               (clobber (reg:CC FLAGS_REG))])]
7286   "TARGET_HIMODE_MATH"
7287   "")
7288
7289 ;; On AMDFAM10
7290 ;; IMUL reg16, reg16, imm8      VectorPath
7291 ;; IMUL reg16, mem16, imm8      VectorPath
7292 ;; IMUL reg16, reg16, imm16     VectorPath
7293 ;; IMUL reg16, mem16, imm16     VectorPath
7294 ;; IMUL reg16, reg16            Direct
7295 ;; IMUL reg16, mem16            Direct
7296 (define_insn "*mulhi3_1"
7297   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7298         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7299                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7300    (clobber (reg:CC FLAGS_REG))]
7301   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7302   "@
7303    imul{w}\t{%2, %1, %0|%0, %1, %2}
7304    imul{w}\t{%2, %1, %0|%0, %1, %2}
7305    imul{w}\t{%2, %0|%0, %2}"
7306   [(set_attr "type" "imul")
7307    (set_attr "prefix_0f" "0,0,1")
7308    (set (attr "athlon_decode")
7309         (cond [(eq_attr "cpu" "athlon")
7310                   (const_string "vector")
7311                (eq_attr "alternative" "1,2")
7312                   (const_string "vector")]
7313               (const_string "direct")))
7314    (set (attr "amdfam10_decode")
7315         (cond [(eq_attr "alternative" "0,1")
7316                   (const_string "vector")]
7317               (const_string "direct")))
7318    (set_attr "mode" "HI")])
7319
7320 (define_expand "mulqi3"
7321   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7322                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7323                             (match_operand:QI 2 "register_operand" "")))
7324               (clobber (reg:CC FLAGS_REG))])]
7325   "TARGET_QIMODE_MATH"
7326   "")
7327
7328 ;;On AMDFAM10
7329 ;; MUL reg8     Direct
7330 ;; MUL mem8     Direct
7331
7332 (define_insn "*mulqi3_1"
7333   [(set (match_operand:QI 0 "register_operand" "=a")
7334         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7335                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7336    (clobber (reg:CC FLAGS_REG))]
7337   "TARGET_QIMODE_MATH
7338    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7339   "mul{b}\t%2"
7340   [(set_attr "type" "imul")
7341    (set_attr "length_immediate" "0")
7342    (set (attr "athlon_decode")
7343      (if_then_else (eq_attr "cpu" "athlon")
7344         (const_string "vector")
7345         (const_string "direct")))
7346    (set_attr "amdfam10_decode" "direct")        
7347    (set_attr "mode" "QI")])
7348
7349 (define_expand "umulqihi3"
7350   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7351                    (mult:HI (zero_extend:HI
7352                               (match_operand:QI 1 "nonimmediate_operand" ""))
7353                             (zero_extend:HI
7354                               (match_operand:QI 2 "register_operand" ""))))
7355               (clobber (reg:CC FLAGS_REG))])]
7356   "TARGET_QIMODE_MATH"
7357   "")
7358
7359 (define_insn "*umulqihi3_1"
7360   [(set (match_operand:HI 0 "register_operand" "=a")
7361         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7362                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7363    (clobber (reg:CC FLAGS_REG))]
7364   "TARGET_QIMODE_MATH
7365    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7366   "mul{b}\t%2"
7367   [(set_attr "type" "imul")
7368    (set_attr "length_immediate" "0")
7369    (set (attr "athlon_decode")
7370      (if_then_else (eq_attr "cpu" "athlon")
7371         (const_string "vector")
7372         (const_string "direct")))
7373    (set_attr "amdfam10_decode" "direct")        
7374    (set_attr "mode" "QI")])
7375
7376 (define_expand "mulqihi3"
7377   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7378                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7379                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7380               (clobber (reg:CC FLAGS_REG))])]
7381   "TARGET_QIMODE_MATH"
7382   "")
7383
7384 (define_insn "*mulqihi3_insn"
7385   [(set (match_operand:HI 0 "register_operand" "=a")
7386         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7387                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7388    (clobber (reg:CC FLAGS_REG))]
7389   "TARGET_QIMODE_MATH
7390    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7391   "imul{b}\t%2"
7392   [(set_attr "type" "imul")
7393    (set_attr "length_immediate" "0")
7394    (set (attr "athlon_decode")
7395      (if_then_else (eq_attr "cpu" "athlon")
7396         (const_string "vector")
7397         (const_string "direct")))
7398    (set_attr "amdfam10_decode" "direct")        
7399    (set_attr "mode" "QI")])
7400
7401 (define_expand "umulditi3"
7402   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7403                    (mult:TI (zero_extend:TI
7404                               (match_operand:DI 1 "nonimmediate_operand" ""))
7405                             (zero_extend:TI
7406                               (match_operand:DI 2 "register_operand" ""))))
7407               (clobber (reg:CC FLAGS_REG))])]
7408   "TARGET_64BIT"
7409   "")
7410
7411 (define_insn "*umulditi3_insn"
7412   [(set (match_operand:TI 0 "register_operand" "=A")
7413         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7414                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7415    (clobber (reg:CC FLAGS_REG))]
7416   "TARGET_64BIT
7417    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7418   "mul{q}\t%2"
7419   [(set_attr "type" "imul")
7420    (set_attr "length_immediate" "0")
7421    (set (attr "athlon_decode")
7422      (if_then_else (eq_attr "cpu" "athlon")
7423         (const_string "vector")
7424         (const_string "double")))
7425    (set_attr "amdfam10_decode" "double")        
7426    (set_attr "mode" "DI")])
7427
7428 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7429 (define_expand "umulsidi3"
7430   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7431                    (mult:DI (zero_extend:DI
7432                               (match_operand:SI 1 "nonimmediate_operand" ""))
7433                             (zero_extend:DI
7434                               (match_operand:SI 2 "register_operand" ""))))
7435               (clobber (reg:CC FLAGS_REG))])]
7436   "!TARGET_64BIT"
7437   "")
7438
7439 (define_insn "*umulsidi3_insn"
7440   [(set (match_operand:DI 0 "register_operand" "=A")
7441         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7442                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7443    (clobber (reg:CC FLAGS_REG))]
7444   "!TARGET_64BIT
7445    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7446   "mul{l}\t%2"
7447   [(set_attr "type" "imul")
7448    (set_attr "length_immediate" "0")
7449    (set (attr "athlon_decode")
7450      (if_then_else (eq_attr "cpu" "athlon")
7451         (const_string "vector")
7452         (const_string "double")))
7453    (set_attr "amdfam10_decode" "double")        
7454    (set_attr "mode" "SI")])
7455
7456 (define_expand "mulditi3"
7457   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7458                    (mult:TI (sign_extend:TI
7459                               (match_operand:DI 1 "nonimmediate_operand" ""))
7460                             (sign_extend:TI
7461                               (match_operand:DI 2 "register_operand" ""))))
7462               (clobber (reg:CC FLAGS_REG))])]
7463   "TARGET_64BIT"
7464   "")
7465
7466 (define_insn "*mulditi3_insn"
7467   [(set (match_operand:TI 0 "register_operand" "=A")
7468         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7469                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7470    (clobber (reg:CC FLAGS_REG))]
7471   "TARGET_64BIT
7472    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7473   "imul{q}\t%2"
7474   [(set_attr "type" "imul")
7475    (set_attr "length_immediate" "0")
7476    (set (attr "athlon_decode")
7477      (if_then_else (eq_attr "cpu" "athlon")
7478         (const_string "vector")
7479         (const_string "double")))
7480    (set_attr "amdfam10_decode" "double")
7481    (set_attr "mode" "DI")])
7482
7483 (define_expand "mulsidi3"
7484   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7485                    (mult:DI (sign_extend:DI
7486                               (match_operand:SI 1 "nonimmediate_operand" ""))
7487                             (sign_extend:DI
7488                               (match_operand:SI 2 "register_operand" ""))))
7489               (clobber (reg:CC FLAGS_REG))])]
7490   "!TARGET_64BIT"
7491   "")
7492
7493 (define_insn "*mulsidi3_insn"
7494   [(set (match_operand:DI 0 "register_operand" "=A")
7495         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7496                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7497    (clobber (reg:CC FLAGS_REG))]
7498   "!TARGET_64BIT
7499    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7500   "imul{l}\t%2"
7501   [(set_attr "type" "imul")
7502    (set_attr "length_immediate" "0")
7503    (set (attr "athlon_decode")
7504      (if_then_else (eq_attr "cpu" "athlon")
7505         (const_string "vector")
7506         (const_string "double")))
7507    (set_attr "amdfam10_decode" "double")        
7508    (set_attr "mode" "SI")])
7509
7510 (define_expand "umuldi3_highpart"
7511   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7512                    (truncate:DI
7513                      (lshiftrt:TI
7514                        (mult:TI (zero_extend:TI
7515                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7516                                 (zero_extend:TI
7517                                   (match_operand:DI 2 "register_operand" "")))
7518                        (const_int 64))))
7519               (clobber (match_scratch:DI 3 ""))
7520               (clobber (reg:CC FLAGS_REG))])]
7521   "TARGET_64BIT"
7522   "")
7523
7524 (define_insn "*umuldi3_highpart_rex64"
7525   [(set (match_operand:DI 0 "register_operand" "=d")
7526         (truncate:DI
7527           (lshiftrt:TI
7528             (mult:TI (zero_extend:TI
7529                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7530                      (zero_extend:TI
7531                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7532             (const_int 64))))
7533    (clobber (match_scratch:DI 3 "=1"))
7534    (clobber (reg:CC FLAGS_REG))]
7535   "TARGET_64BIT
7536    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7537   "mul{q}\t%2"
7538   [(set_attr "type" "imul")
7539    (set_attr "length_immediate" "0")
7540    (set (attr "athlon_decode")
7541      (if_then_else (eq_attr "cpu" "athlon")
7542         (const_string "vector")
7543         (const_string "double")))
7544    (set_attr "amdfam10_decode" "double")        
7545    (set_attr "mode" "DI")])
7546
7547 (define_expand "umulsi3_highpart"
7548   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7549                    (truncate:SI
7550                      (lshiftrt:DI
7551                        (mult:DI (zero_extend:DI
7552                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7553                                 (zero_extend:DI
7554                                   (match_operand:SI 2 "register_operand" "")))
7555                        (const_int 32))))
7556               (clobber (match_scratch:SI 3 ""))
7557               (clobber (reg:CC FLAGS_REG))])]
7558   ""
7559   "")
7560
7561 (define_insn "*umulsi3_highpart_insn"
7562   [(set (match_operand:SI 0 "register_operand" "=d")
7563         (truncate:SI
7564           (lshiftrt:DI
7565             (mult:DI (zero_extend:DI
7566                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7567                      (zero_extend:DI
7568                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7569             (const_int 32))))
7570    (clobber (match_scratch:SI 3 "=1"))
7571    (clobber (reg:CC FLAGS_REG))]
7572   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7573   "mul{l}\t%2"
7574   [(set_attr "type" "imul")
7575    (set_attr "length_immediate" "0")
7576    (set (attr "athlon_decode")
7577      (if_then_else (eq_attr "cpu" "athlon")
7578         (const_string "vector")
7579         (const_string "double")))
7580    (set_attr "amdfam10_decode" "double")
7581    (set_attr "mode" "SI")])
7582
7583 (define_insn "*umulsi3_highpart_zext"
7584   [(set (match_operand:DI 0 "register_operand" "=d")
7585         (zero_extend:DI (truncate:SI
7586           (lshiftrt:DI
7587             (mult:DI (zero_extend:DI
7588                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7589                      (zero_extend:DI
7590                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7591             (const_int 32)))))
7592    (clobber (match_scratch:SI 3 "=1"))
7593    (clobber (reg:CC FLAGS_REG))]
7594   "TARGET_64BIT
7595    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7596   "mul{l}\t%2"
7597   [(set_attr "type" "imul")
7598    (set_attr "length_immediate" "0")
7599    (set (attr "athlon_decode")
7600      (if_then_else (eq_attr "cpu" "athlon")
7601         (const_string "vector")
7602         (const_string "double")))
7603    (set_attr "amdfam10_decode" "double")
7604    (set_attr "mode" "SI")])
7605
7606 (define_expand "smuldi3_highpart"
7607   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7608                    (truncate:DI
7609                      (lshiftrt:TI
7610                        (mult:TI (sign_extend:TI
7611                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7612                                 (sign_extend:TI
7613                                   (match_operand:DI 2 "register_operand" "")))
7614                        (const_int 64))))
7615               (clobber (match_scratch:DI 3 ""))
7616               (clobber (reg:CC FLAGS_REG))])]
7617   "TARGET_64BIT"
7618   "")
7619
7620 (define_insn "*smuldi3_highpart_rex64"
7621   [(set (match_operand:DI 0 "register_operand" "=d")
7622         (truncate:DI
7623           (lshiftrt:TI
7624             (mult:TI (sign_extend:TI
7625                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7626                      (sign_extend:TI
7627                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7628             (const_int 64))))
7629    (clobber (match_scratch:DI 3 "=1"))
7630    (clobber (reg:CC FLAGS_REG))]
7631   "TARGET_64BIT
7632    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7633   "imul{q}\t%2"
7634   [(set_attr "type" "imul")
7635    (set (attr "athlon_decode")
7636      (if_then_else (eq_attr "cpu" "athlon")
7637         (const_string "vector")
7638         (const_string "double")))
7639    (set_attr "amdfam10_decode" "double")
7640    (set_attr "mode" "DI")])
7641
7642 (define_expand "smulsi3_highpart"
7643   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7644                    (truncate:SI
7645                      (lshiftrt:DI
7646                        (mult:DI (sign_extend:DI
7647                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7648                                 (sign_extend:DI
7649                                   (match_operand:SI 2 "register_operand" "")))
7650                        (const_int 32))))
7651               (clobber (match_scratch:SI 3 ""))
7652               (clobber (reg:CC FLAGS_REG))])]
7653   ""
7654   "")
7655
7656 (define_insn "*smulsi3_highpart_insn"
7657   [(set (match_operand:SI 0 "register_operand" "=d")
7658         (truncate:SI
7659           (lshiftrt:DI
7660             (mult:DI (sign_extend:DI
7661                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7662                      (sign_extend:DI
7663                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7664             (const_int 32))))
7665    (clobber (match_scratch:SI 3 "=1"))
7666    (clobber (reg:CC FLAGS_REG))]
7667   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7668   "imul{l}\t%2"
7669   [(set_attr "type" "imul")
7670    (set (attr "athlon_decode")
7671      (if_then_else (eq_attr "cpu" "athlon")
7672         (const_string "vector")
7673         (const_string "double")))
7674    (set_attr "amdfam10_decode" "double")
7675    (set_attr "mode" "SI")])
7676
7677 (define_insn "*smulsi3_highpart_zext"
7678   [(set (match_operand:DI 0 "register_operand" "=d")
7679         (zero_extend:DI (truncate:SI
7680           (lshiftrt:DI
7681             (mult:DI (sign_extend:DI
7682                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7683                      (sign_extend:DI
7684                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7685             (const_int 32)))))
7686    (clobber (match_scratch:SI 3 "=1"))
7687    (clobber (reg:CC FLAGS_REG))]
7688   "TARGET_64BIT
7689    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7690   "imul{l}\t%2"
7691   [(set_attr "type" "imul")
7692    (set (attr "athlon_decode")
7693      (if_then_else (eq_attr "cpu" "athlon")
7694         (const_string "vector")
7695         (const_string "double")))
7696    (set_attr "amdfam10_decode" "double")
7697    (set_attr "mode" "SI")])
7698
7699 ;; The patterns that match these are at the end of this file.
7700
7701 (define_expand "mulxf3"
7702   [(set (match_operand:XF 0 "register_operand" "")
7703         (mult:XF (match_operand:XF 1 "register_operand" "")
7704                  (match_operand:XF 2 "register_operand" "")))]
7705   "TARGET_80387"
7706   "")
7707
7708 (define_expand "muldf3"
7709   [(set (match_operand:DF 0 "register_operand" "")
7710         (mult:DF (match_operand:DF 1 "register_operand" "")
7711                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7712   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7713   "")
7714
7715 (define_expand "mulsf3"
7716   [(set (match_operand:SF 0 "register_operand" "")
7717         (mult:SF (match_operand:SF 1 "register_operand" "")
7718                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7719   "TARGET_80387 || TARGET_SSE_MATH"
7720   "")
7721 \f
7722 ;; Divide instructions
7723
7724 (define_insn "divqi3"
7725   [(set (match_operand:QI 0 "register_operand" "=a")
7726         (div:QI (match_operand:HI 1 "register_operand" "0")
7727                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7728    (clobber (reg:CC FLAGS_REG))]
7729   "TARGET_QIMODE_MATH"
7730   "idiv{b}\t%2"
7731   [(set_attr "type" "idiv")
7732    (set_attr "mode" "QI")])
7733
7734 (define_insn "udivqi3"
7735   [(set (match_operand:QI 0 "register_operand" "=a")
7736         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7737                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7738    (clobber (reg:CC FLAGS_REG))]
7739   "TARGET_QIMODE_MATH"
7740   "div{b}\t%2"
7741   [(set_attr "type" "idiv")
7742    (set_attr "mode" "QI")])
7743
7744 ;; The patterns that match these are at the end of this file.
7745
7746 (define_expand "divxf3"
7747   [(set (match_operand:XF 0 "register_operand" "")
7748         (div:XF (match_operand:XF 1 "register_operand" "")
7749                 (match_operand:XF 2 "register_operand" "")))]
7750   "TARGET_80387"
7751   "")
7752
7753 (define_expand "divdf3"
7754   [(set (match_operand:DF 0 "register_operand" "")
7755         (div:DF (match_operand:DF 1 "register_operand" "")
7756                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7757    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7758    "")
7759
7760 (define_expand "divsf3"
7761   [(set (match_operand:SF 0 "register_operand" "")
7762         (div:SF (match_operand:SF 1 "register_operand" "")
7763                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7764   "TARGET_80387 || TARGET_SSE_MATH"
7765   "")
7766 \f
7767 ;; Remainder instructions.
7768
7769 (define_expand "divmoddi4"
7770   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7771                    (div:DI (match_operand:DI 1 "register_operand" "")
7772                            (match_operand:DI 2 "nonimmediate_operand" "")))
7773               (set (match_operand:DI 3 "register_operand" "")
7774                    (mod:DI (match_dup 1) (match_dup 2)))
7775               (clobber (reg:CC FLAGS_REG))])]
7776   "TARGET_64BIT"
7777   "")
7778
7779 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7780 ;; Penalize eax case slightly because it results in worse scheduling
7781 ;; of code.
7782 (define_insn "*divmoddi4_nocltd_rex64"
7783   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7784         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7785                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7786    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7787         (mod:DI (match_dup 2) (match_dup 3)))
7788    (clobber (reg:CC FLAGS_REG))]
7789   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7790   "#"
7791   [(set_attr "type" "multi")])
7792
7793 (define_insn "*divmoddi4_cltd_rex64"
7794   [(set (match_operand:DI 0 "register_operand" "=a")
7795         (div:DI (match_operand:DI 2 "register_operand" "a")
7796                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7797    (set (match_operand:DI 1 "register_operand" "=&d")
7798         (mod:DI (match_dup 2) (match_dup 3)))
7799    (clobber (reg:CC FLAGS_REG))]
7800   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7801   "#"
7802   [(set_attr "type" "multi")])
7803
7804 (define_insn "*divmoddi_noext_rex64"
7805   [(set (match_operand:DI 0 "register_operand" "=a")
7806         (div:DI (match_operand:DI 1 "register_operand" "0")
7807                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7808    (set (match_operand:DI 3 "register_operand" "=d")
7809         (mod:DI (match_dup 1) (match_dup 2)))
7810    (use (match_operand:DI 4 "register_operand" "3"))
7811    (clobber (reg:CC FLAGS_REG))]
7812   "TARGET_64BIT"
7813   "idiv{q}\t%2"
7814   [(set_attr "type" "idiv")
7815    (set_attr "mode" "DI")])
7816
7817 (define_split
7818   [(set (match_operand:DI 0 "register_operand" "")
7819         (div:DI (match_operand:DI 1 "register_operand" "")
7820                 (match_operand:DI 2 "nonimmediate_operand" "")))
7821    (set (match_operand:DI 3 "register_operand" "")
7822         (mod:DI (match_dup 1) (match_dup 2)))
7823    (clobber (reg:CC FLAGS_REG))]
7824   "TARGET_64BIT && reload_completed"
7825   [(parallel [(set (match_dup 3)
7826                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7827               (clobber (reg:CC FLAGS_REG))])
7828    (parallel [(set (match_dup 0)
7829                    (div:DI (reg:DI 0) (match_dup 2)))
7830               (set (match_dup 3)
7831                    (mod:DI (reg:DI 0) (match_dup 2)))
7832               (use (match_dup 3))
7833               (clobber (reg:CC FLAGS_REG))])]
7834 {
7835   /* Avoid use of cltd in favor of a mov+shift.  */
7836   if (!TARGET_USE_CLTD && !optimize_size)
7837     {
7838       if (true_regnum (operands[1]))
7839         emit_move_insn (operands[0], operands[1]);
7840       else
7841         emit_move_insn (operands[3], operands[1]);
7842       operands[4] = operands[3];
7843     }
7844   else
7845     {
7846       gcc_assert (!true_regnum (operands[1]));
7847       operands[4] = operands[1];
7848     }
7849 })
7850
7851
7852 (define_expand "divmodsi4"
7853   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7854                    (div:SI (match_operand:SI 1 "register_operand" "")
7855                            (match_operand:SI 2 "nonimmediate_operand" "")))
7856               (set (match_operand:SI 3 "register_operand" "")
7857                    (mod:SI (match_dup 1) (match_dup 2)))
7858               (clobber (reg:CC FLAGS_REG))])]
7859   ""
7860   "")
7861
7862 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7863 ;; Penalize eax case slightly because it results in worse scheduling
7864 ;; of code.
7865 (define_insn "*divmodsi4_nocltd"
7866   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7867         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7868                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7869    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7870         (mod:SI (match_dup 2) (match_dup 3)))
7871    (clobber (reg:CC FLAGS_REG))]
7872   "!optimize_size && !TARGET_USE_CLTD"
7873   "#"
7874   [(set_attr "type" "multi")])
7875
7876 (define_insn "*divmodsi4_cltd"
7877   [(set (match_operand:SI 0 "register_operand" "=a")
7878         (div:SI (match_operand:SI 2 "register_operand" "a")
7879                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7880    (set (match_operand:SI 1 "register_operand" "=&d")
7881         (mod:SI (match_dup 2) (match_dup 3)))
7882    (clobber (reg:CC FLAGS_REG))]
7883   "optimize_size || TARGET_USE_CLTD"
7884   "#"
7885   [(set_attr "type" "multi")])
7886
7887 (define_insn "*divmodsi_noext"
7888   [(set (match_operand:SI 0 "register_operand" "=a")
7889         (div:SI (match_operand:SI 1 "register_operand" "0")
7890                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7891    (set (match_operand:SI 3 "register_operand" "=d")
7892         (mod:SI (match_dup 1) (match_dup 2)))
7893    (use (match_operand:SI 4 "register_operand" "3"))
7894    (clobber (reg:CC FLAGS_REG))]
7895   ""
7896   "idiv{l}\t%2"
7897   [(set_attr "type" "idiv")
7898    (set_attr "mode" "SI")])
7899
7900 (define_split
7901   [(set (match_operand:SI 0 "register_operand" "")
7902         (div:SI (match_operand:SI 1 "register_operand" "")
7903                 (match_operand:SI 2 "nonimmediate_operand" "")))
7904    (set (match_operand:SI 3 "register_operand" "")
7905         (mod:SI (match_dup 1) (match_dup 2)))
7906    (clobber (reg:CC FLAGS_REG))]
7907   "reload_completed"
7908   [(parallel [(set (match_dup 3)
7909                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7910               (clobber (reg:CC FLAGS_REG))])
7911    (parallel [(set (match_dup 0)
7912                    (div:SI (reg:SI 0) (match_dup 2)))
7913               (set (match_dup 3)
7914                    (mod:SI (reg:SI 0) (match_dup 2)))
7915               (use (match_dup 3))
7916               (clobber (reg:CC FLAGS_REG))])]
7917 {
7918   /* Avoid use of cltd in favor of a mov+shift.  */
7919   if (!TARGET_USE_CLTD && !optimize_size)
7920     {
7921       if (true_regnum (operands[1]))
7922         emit_move_insn (operands[0], operands[1]);
7923       else
7924         emit_move_insn (operands[3], operands[1]);
7925       operands[4] = operands[3];
7926     }
7927   else
7928     {
7929       gcc_assert (!true_regnum (operands[1]));
7930       operands[4] = operands[1];
7931     }
7932 })
7933 ;; %%% Split me.
7934 (define_insn "divmodhi4"
7935   [(set (match_operand:HI 0 "register_operand" "=a")
7936         (div:HI (match_operand:HI 1 "register_operand" "0")
7937                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7938    (set (match_operand:HI 3 "register_operand" "=&d")
7939         (mod:HI (match_dup 1) (match_dup 2)))
7940    (clobber (reg:CC FLAGS_REG))]
7941   "TARGET_HIMODE_MATH"
7942   "cwtd\;idiv{w}\t%2"
7943   [(set_attr "type" "multi")
7944    (set_attr "length_immediate" "0")
7945    (set_attr "mode" "SI")])
7946
7947 (define_insn "udivmoddi4"
7948   [(set (match_operand:DI 0 "register_operand" "=a")
7949         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7950                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7951    (set (match_operand:DI 3 "register_operand" "=&d")
7952         (umod:DI (match_dup 1) (match_dup 2)))
7953    (clobber (reg:CC FLAGS_REG))]
7954   "TARGET_64BIT"
7955   "xor{q}\t%3, %3\;div{q}\t%2"
7956   [(set_attr "type" "multi")
7957    (set_attr "length_immediate" "0")
7958    (set_attr "mode" "DI")])
7959
7960 (define_insn "*udivmoddi4_noext"
7961   [(set (match_operand:DI 0 "register_operand" "=a")
7962         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7963                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7964    (set (match_operand:DI 3 "register_operand" "=d")
7965         (umod:DI (match_dup 1) (match_dup 2)))
7966    (use (match_dup 3))
7967    (clobber (reg:CC FLAGS_REG))]
7968   "TARGET_64BIT"
7969   "div{q}\t%2"
7970   [(set_attr "type" "idiv")
7971    (set_attr "mode" "DI")])
7972
7973 (define_split
7974   [(set (match_operand:DI 0 "register_operand" "")
7975         (udiv:DI (match_operand:DI 1 "register_operand" "")
7976                  (match_operand:DI 2 "nonimmediate_operand" "")))
7977    (set (match_operand:DI 3 "register_operand" "")
7978         (umod:DI (match_dup 1) (match_dup 2)))
7979    (clobber (reg:CC FLAGS_REG))]
7980   "TARGET_64BIT && reload_completed"
7981   [(set (match_dup 3) (const_int 0))
7982    (parallel [(set (match_dup 0)
7983                    (udiv:DI (match_dup 1) (match_dup 2)))
7984               (set (match_dup 3)
7985                    (umod:DI (match_dup 1) (match_dup 2)))
7986               (use (match_dup 3))
7987               (clobber (reg:CC FLAGS_REG))])]
7988   "")
7989
7990 (define_insn "udivmodsi4"
7991   [(set (match_operand:SI 0 "register_operand" "=a")
7992         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7993                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7994    (set (match_operand:SI 3 "register_operand" "=&d")
7995         (umod:SI (match_dup 1) (match_dup 2)))
7996    (clobber (reg:CC FLAGS_REG))]
7997   ""
7998   "xor{l}\t%3, %3\;div{l}\t%2"
7999   [(set_attr "type" "multi")
8000    (set_attr "length_immediate" "0")
8001    (set_attr "mode" "SI")])
8002
8003 (define_insn "*udivmodsi4_noext"
8004   [(set (match_operand:SI 0 "register_operand" "=a")
8005         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8006                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8007    (set (match_operand:SI 3 "register_operand" "=d")
8008         (umod:SI (match_dup 1) (match_dup 2)))
8009    (use (match_dup 3))
8010    (clobber (reg:CC FLAGS_REG))]
8011   ""
8012   "div{l}\t%2"
8013   [(set_attr "type" "idiv")
8014    (set_attr "mode" "SI")])
8015
8016 (define_split
8017   [(set (match_operand:SI 0 "register_operand" "")
8018         (udiv:SI (match_operand:SI 1 "register_operand" "")
8019                  (match_operand:SI 2 "nonimmediate_operand" "")))
8020    (set (match_operand:SI 3 "register_operand" "")
8021         (umod:SI (match_dup 1) (match_dup 2)))
8022    (clobber (reg:CC FLAGS_REG))]
8023   "reload_completed"
8024   [(set (match_dup 3) (const_int 0))
8025    (parallel [(set (match_dup 0)
8026                    (udiv:SI (match_dup 1) (match_dup 2)))
8027               (set (match_dup 3)
8028                    (umod:SI (match_dup 1) (match_dup 2)))
8029               (use (match_dup 3))
8030               (clobber (reg:CC FLAGS_REG))])]
8031   "")
8032
8033 (define_expand "udivmodhi4"
8034   [(set (match_dup 4) (const_int 0))
8035    (parallel [(set (match_operand:HI 0 "register_operand" "")
8036                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8037                             (match_operand:HI 2 "nonimmediate_operand" "")))
8038               (set (match_operand:HI 3 "register_operand" "")
8039                    (umod:HI (match_dup 1) (match_dup 2)))
8040               (use (match_dup 4))
8041               (clobber (reg:CC FLAGS_REG))])]
8042   "TARGET_HIMODE_MATH"
8043   "operands[4] = gen_reg_rtx (HImode);")
8044
8045 (define_insn "*udivmodhi_noext"
8046   [(set (match_operand:HI 0 "register_operand" "=a")
8047         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8048                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8049    (set (match_operand:HI 3 "register_operand" "=d")
8050         (umod:HI (match_dup 1) (match_dup 2)))
8051    (use (match_operand:HI 4 "register_operand" "3"))
8052    (clobber (reg:CC FLAGS_REG))]
8053   ""
8054   "div{w}\t%2"
8055   [(set_attr "type" "idiv")
8056    (set_attr "mode" "HI")])
8057
8058 ;; We cannot use div/idiv for double division, because it causes
8059 ;; "division by zero" on the overflow and that's not what we expect
8060 ;; from truncate.  Because true (non truncating) double division is
8061 ;; never generated, we can't create this insn anyway.
8062 ;
8063 ;(define_insn ""
8064 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8065 ;       (truncate:SI
8066 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8067 ;                  (zero_extend:DI
8068 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8069 ;   (set (match_operand:SI 3 "register_operand" "=d")
8070 ;       (truncate:SI
8071 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8072 ;   (clobber (reg:CC FLAGS_REG))]
8073 ;  ""
8074 ;  "div{l}\t{%2, %0|%0, %2}"
8075 ;  [(set_attr "type" "idiv")])
8076 \f
8077 ;;- Logical AND instructions
8078
8079 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8080 ;; Note that this excludes ah.
8081
8082 (define_insn "*testdi_1_rex64"
8083   [(set (reg FLAGS_REG)
8084         (compare
8085           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8086                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8087           (const_int 0)))]
8088   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8089    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8090   "@
8091    test{l}\t{%k1, %k0|%k0, %k1}
8092    test{l}\t{%k1, %k0|%k0, %k1}
8093    test{q}\t{%1, %0|%0, %1}
8094    test{q}\t{%1, %0|%0, %1}
8095    test{q}\t{%1, %0|%0, %1}"
8096   [(set_attr "type" "test")
8097    (set_attr "modrm" "0,1,0,1,1")
8098    (set_attr "mode" "SI,SI,DI,DI,DI")
8099    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8100
8101 (define_insn "testsi_1"
8102   [(set (reg FLAGS_REG)
8103         (compare
8104           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8105                   (match_operand:SI 1 "general_operand" "in,in,rin"))
8106           (const_int 0)))]
8107   "ix86_match_ccmode (insn, CCNOmode)
8108    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8109   "test{l}\t{%1, %0|%0, %1}"
8110   [(set_attr "type" "test")
8111    (set_attr "modrm" "0,1,1")
8112    (set_attr "mode" "SI")
8113    (set_attr "pent_pair" "uv,np,uv")])
8114
8115 (define_expand "testsi_ccno_1"
8116   [(set (reg:CCNO FLAGS_REG)
8117         (compare:CCNO
8118           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8119                   (match_operand:SI 1 "nonmemory_operand" ""))
8120           (const_int 0)))]
8121   ""
8122   "")
8123
8124 (define_insn "*testhi_1"
8125   [(set (reg FLAGS_REG)
8126         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8127                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8128                  (const_int 0)))]
8129   "ix86_match_ccmode (insn, CCNOmode)
8130    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8131   "test{w}\t{%1, %0|%0, %1}"
8132   [(set_attr "type" "test")
8133    (set_attr "modrm" "0,1,1")
8134    (set_attr "mode" "HI")
8135    (set_attr "pent_pair" "uv,np,uv")])
8136
8137 (define_expand "testqi_ccz_1"
8138   [(set (reg:CCZ FLAGS_REG)
8139         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8140                              (match_operand:QI 1 "nonmemory_operand" ""))
8141                  (const_int 0)))]
8142   ""
8143   "")
8144
8145 (define_insn "*testqi_1_maybe_si"
8146   [(set (reg FLAGS_REG)
8147         (compare
8148           (and:QI
8149             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8150             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8151           (const_int 0)))]
8152    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8153     && ix86_match_ccmode (insn,
8154                          CONST_INT_P (operands[1])
8155                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8156 {
8157   if (which_alternative == 3)
8158     {
8159       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8160         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8161       return "test{l}\t{%1, %k0|%k0, %1}";
8162     }
8163   return "test{b}\t{%1, %0|%0, %1}";
8164 }
8165   [(set_attr "type" "test")
8166    (set_attr "modrm" "0,1,1,1")
8167    (set_attr "mode" "QI,QI,QI,SI")
8168    (set_attr "pent_pair" "uv,np,uv,np")])
8169
8170 (define_insn "*testqi_1"
8171   [(set (reg FLAGS_REG)
8172         (compare
8173           (and:QI
8174             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8175             (match_operand:QI 1 "general_operand" "n,n,qn"))
8176           (const_int 0)))]
8177   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8178    && ix86_match_ccmode (insn, CCNOmode)"
8179   "test{b}\t{%1, %0|%0, %1}"
8180   [(set_attr "type" "test")
8181    (set_attr "modrm" "0,1,1")
8182    (set_attr "mode" "QI")
8183    (set_attr "pent_pair" "uv,np,uv")])
8184
8185 (define_expand "testqi_ext_ccno_0"
8186   [(set (reg:CCNO FLAGS_REG)
8187         (compare:CCNO
8188           (and:SI
8189             (zero_extract:SI
8190               (match_operand 0 "ext_register_operand" "")
8191               (const_int 8)
8192               (const_int 8))
8193             (match_operand 1 "const_int_operand" ""))
8194           (const_int 0)))]
8195   ""
8196   "")
8197
8198 (define_insn "*testqi_ext_0"
8199   [(set (reg FLAGS_REG)
8200         (compare
8201           (and:SI
8202             (zero_extract:SI
8203               (match_operand 0 "ext_register_operand" "Q")
8204               (const_int 8)
8205               (const_int 8))
8206             (match_operand 1 "const_int_operand" "n"))
8207           (const_int 0)))]
8208   "ix86_match_ccmode (insn, CCNOmode)"
8209   "test{b}\t{%1, %h0|%h0, %1}"
8210   [(set_attr "type" "test")
8211    (set_attr "mode" "QI")
8212    (set_attr "length_immediate" "1")
8213    (set_attr "pent_pair" "np")])
8214
8215 (define_insn "*testqi_ext_1"
8216   [(set (reg FLAGS_REG)
8217         (compare
8218           (and:SI
8219             (zero_extract:SI
8220               (match_operand 0 "ext_register_operand" "Q")
8221               (const_int 8)
8222               (const_int 8))
8223             (zero_extend:SI
8224               (match_operand:QI 1 "general_operand" "Qm")))
8225           (const_int 0)))]
8226   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8227    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8228   "test{b}\t{%1, %h0|%h0, %1}"
8229   [(set_attr "type" "test")
8230    (set_attr "mode" "QI")])
8231
8232 (define_insn "*testqi_ext_1_rex64"
8233   [(set (reg FLAGS_REG)
8234         (compare
8235           (and:SI
8236             (zero_extract:SI
8237               (match_operand 0 "ext_register_operand" "Q")
8238               (const_int 8)
8239               (const_int 8))
8240             (zero_extend:SI
8241               (match_operand:QI 1 "register_operand" "Q")))
8242           (const_int 0)))]
8243   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8244   "test{b}\t{%1, %h0|%h0, %1}"
8245   [(set_attr "type" "test")
8246    (set_attr "mode" "QI")])
8247
8248 (define_insn "*testqi_ext_2"
8249   [(set (reg FLAGS_REG)
8250         (compare
8251           (and:SI
8252             (zero_extract:SI
8253               (match_operand 0 "ext_register_operand" "Q")
8254               (const_int 8)
8255               (const_int 8))
8256             (zero_extract:SI
8257               (match_operand 1 "ext_register_operand" "Q")
8258               (const_int 8)
8259               (const_int 8)))
8260           (const_int 0)))]
8261   "ix86_match_ccmode (insn, CCNOmode)"
8262   "test{b}\t{%h1, %h0|%h0, %h1}"
8263   [(set_attr "type" "test")
8264    (set_attr "mode" "QI")])
8265
8266 ;; Combine likes to form bit extractions for some tests.  Humor it.
8267 (define_insn "*testqi_ext_3"
8268   [(set (reg FLAGS_REG)
8269         (compare (zero_extract:SI
8270                    (match_operand 0 "nonimmediate_operand" "rm")
8271                    (match_operand:SI 1 "const_int_operand" "")
8272                    (match_operand:SI 2 "const_int_operand" ""))
8273                  (const_int 0)))]
8274   "ix86_match_ccmode (insn, CCNOmode)
8275    && INTVAL (operands[1]) > 0
8276    && INTVAL (operands[2]) >= 0
8277    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8278    && (GET_MODE (operands[0]) == SImode
8279        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8280        || GET_MODE (operands[0]) == HImode
8281        || GET_MODE (operands[0]) == QImode)"
8282   "#")
8283
8284 (define_insn "*testqi_ext_3_rex64"
8285   [(set (reg FLAGS_REG)
8286         (compare (zero_extract:DI
8287                    (match_operand 0 "nonimmediate_operand" "rm")
8288                    (match_operand:DI 1 "const_int_operand" "")
8289                    (match_operand:DI 2 "const_int_operand" ""))
8290                  (const_int 0)))]
8291   "TARGET_64BIT
8292    && ix86_match_ccmode (insn, CCNOmode)
8293    && INTVAL (operands[1]) > 0
8294    && INTVAL (operands[2]) >= 0
8295    /* Ensure that resulting mask is zero or sign extended operand.  */
8296    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8297        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8298            && INTVAL (operands[1]) > 32))
8299    && (GET_MODE (operands[0]) == SImode
8300        || GET_MODE (operands[0]) == DImode
8301        || GET_MODE (operands[0]) == HImode
8302        || GET_MODE (operands[0]) == QImode)"
8303   "#")
8304
8305 (define_split
8306   [(set (match_operand 0 "flags_reg_operand" "")
8307         (match_operator 1 "compare_operator"
8308           [(zero_extract
8309              (match_operand 2 "nonimmediate_operand" "")
8310              (match_operand 3 "const_int_operand" "")
8311              (match_operand 4 "const_int_operand" ""))
8312            (const_int 0)]))]
8313   "ix86_match_ccmode (insn, CCNOmode)"
8314   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8315 {
8316   rtx val = operands[2];
8317   HOST_WIDE_INT len = INTVAL (operands[3]);
8318   HOST_WIDE_INT pos = INTVAL (operands[4]);
8319   HOST_WIDE_INT mask;
8320   enum machine_mode mode, submode;
8321
8322   mode = GET_MODE (val);
8323   if (MEM_P (val))
8324     {
8325       /* ??? Combine likes to put non-volatile mem extractions in QImode
8326          no matter the size of the test.  So find a mode that works.  */
8327       if (! MEM_VOLATILE_P (val))
8328         {
8329           mode = smallest_mode_for_size (pos + len, MODE_INT);
8330           val = adjust_address (val, mode, 0);
8331         }
8332     }
8333   else if (GET_CODE (val) == SUBREG
8334            && (submode = GET_MODE (SUBREG_REG (val)),
8335                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8336            && pos + len <= GET_MODE_BITSIZE (submode))
8337     {
8338       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8339       mode = submode;
8340       val = SUBREG_REG (val);
8341     }
8342   else if (mode == HImode && pos + len <= 8)
8343     {
8344       /* Small HImode tests can be converted to QImode.  */
8345       mode = QImode;
8346       val = gen_lowpart (QImode, val);
8347     }
8348
8349   if (len == HOST_BITS_PER_WIDE_INT)
8350     mask = -1;
8351   else
8352     mask = ((HOST_WIDE_INT)1 << len) - 1;
8353   mask <<= pos;
8354
8355   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8356 })
8357
8358 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8359 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8360 ;; this is relatively important trick.
8361 ;; Do the conversion only post-reload to avoid limiting of the register class
8362 ;; to QI regs.
8363 (define_split
8364   [(set (match_operand 0 "flags_reg_operand" "")
8365         (match_operator 1 "compare_operator"
8366           [(and (match_operand 2 "register_operand" "")
8367                 (match_operand 3 "const_int_operand" ""))
8368            (const_int 0)]))]
8369    "reload_completed
8370     && QI_REG_P (operands[2])
8371     && GET_MODE (operands[2]) != QImode
8372     && ((ix86_match_ccmode (insn, CCZmode)
8373          && !(INTVAL (operands[3]) & ~(255 << 8)))
8374         || (ix86_match_ccmode (insn, CCNOmode)
8375             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8376   [(set (match_dup 0)
8377         (match_op_dup 1
8378           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8379                    (match_dup 3))
8380            (const_int 0)]))]
8381   "operands[2] = gen_lowpart (SImode, operands[2]);
8382    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8383
8384 (define_split
8385   [(set (match_operand 0 "flags_reg_operand" "")
8386         (match_operator 1 "compare_operator"
8387           [(and (match_operand 2 "nonimmediate_operand" "")
8388                 (match_operand 3 "const_int_operand" ""))
8389            (const_int 0)]))]
8390    "reload_completed
8391     && GET_MODE (operands[2]) != QImode
8392     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8393     && ((ix86_match_ccmode (insn, CCZmode)
8394          && !(INTVAL (operands[3]) & ~255))
8395         || (ix86_match_ccmode (insn, CCNOmode)
8396             && !(INTVAL (operands[3]) & ~127)))"
8397   [(set (match_dup 0)
8398         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8399                          (const_int 0)]))]
8400   "operands[2] = gen_lowpart (QImode, operands[2]);
8401    operands[3] = gen_lowpart (QImode, operands[3]);")
8402
8403
8404 ;; %%% This used to optimize known byte-wide and operations to memory,
8405 ;; and sometimes to QImode registers.  If this is considered useful,
8406 ;; it should be done with splitters.
8407
8408 (define_expand "anddi3"
8409   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8410         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8411                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8412    (clobber (reg:CC FLAGS_REG))]
8413   "TARGET_64BIT"
8414   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8415
8416 (define_insn "*anddi_1_rex64"
8417   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8418         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8419                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8420    (clobber (reg:CC FLAGS_REG))]
8421   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8422 {
8423   switch (get_attr_type (insn))
8424     {
8425     case TYPE_IMOVX:
8426       {
8427         enum machine_mode mode;
8428
8429         gcc_assert (CONST_INT_P (operands[2]));
8430         if (INTVAL (operands[2]) == 0xff)
8431           mode = QImode;
8432         else
8433           {
8434             gcc_assert (INTVAL (operands[2]) == 0xffff);
8435             mode = HImode;
8436           }
8437
8438         operands[1] = gen_lowpart (mode, operands[1]);
8439         if (mode == QImode)
8440           return "movz{bq|x}\t{%1,%0|%0, %1}";
8441         else
8442           return "movz{wq|x}\t{%1,%0|%0, %1}";
8443       }
8444
8445     default:
8446       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8447       if (get_attr_mode (insn) == MODE_SI)
8448         return "and{l}\t{%k2, %k0|%k0, %k2}";
8449       else
8450         return "and{q}\t{%2, %0|%0, %2}";
8451     }
8452 }
8453   [(set_attr "type" "alu,alu,alu,imovx")
8454    (set_attr "length_immediate" "*,*,*,0")
8455    (set_attr "mode" "SI,DI,DI,DI")])
8456
8457 (define_insn "*anddi_2"
8458   [(set (reg FLAGS_REG)
8459         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8460                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8461                  (const_int 0)))
8462    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8463         (and:DI (match_dup 1) (match_dup 2)))]
8464   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8465    && ix86_binary_operator_ok (AND, DImode, operands)"
8466   "@
8467    and{l}\t{%k2, %k0|%k0, %k2}
8468    and{q}\t{%2, %0|%0, %2}
8469    and{q}\t{%2, %0|%0, %2}"
8470   [(set_attr "type" "alu")
8471    (set_attr "mode" "SI,DI,DI")])
8472
8473 (define_expand "andsi3"
8474   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8475         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8476                 (match_operand:SI 2 "general_operand" "")))
8477    (clobber (reg:CC FLAGS_REG))]
8478   ""
8479   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8480
8481 (define_insn "*andsi_1"
8482   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8483         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8484                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8485    (clobber (reg:CC FLAGS_REG))]
8486   "ix86_binary_operator_ok (AND, SImode, operands)"
8487 {
8488   switch (get_attr_type (insn))
8489     {
8490     case TYPE_IMOVX:
8491       {
8492         enum machine_mode mode;
8493
8494         gcc_assert (CONST_INT_P (operands[2]));
8495         if (INTVAL (operands[2]) == 0xff)
8496           mode = QImode;
8497         else
8498           {
8499             gcc_assert (INTVAL (operands[2]) == 0xffff);
8500             mode = HImode;
8501           }
8502
8503         operands[1] = gen_lowpart (mode, operands[1]);
8504         if (mode == QImode)
8505           return "movz{bl|x}\t{%1,%0|%0, %1}";
8506         else
8507           return "movz{wl|x}\t{%1,%0|%0, %1}";
8508       }
8509
8510     default:
8511       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8512       return "and{l}\t{%2, %0|%0, %2}";
8513     }
8514 }
8515   [(set_attr "type" "alu,alu,imovx")
8516    (set_attr "length_immediate" "*,*,0")
8517    (set_attr "mode" "SI")])
8518
8519 (define_split
8520   [(set (match_operand 0 "register_operand" "")
8521         (and (match_dup 0)
8522              (const_int -65536)))
8523    (clobber (reg:CC FLAGS_REG))]
8524   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8525   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8526   "operands[1] = gen_lowpart (HImode, operands[0]);")
8527
8528 (define_split
8529   [(set (match_operand 0 "ext_register_operand" "")
8530         (and (match_dup 0)
8531              (const_int -256)))
8532    (clobber (reg:CC FLAGS_REG))]
8533   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8534   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8535   "operands[1] = gen_lowpart (QImode, operands[0]);")
8536
8537 (define_split
8538   [(set (match_operand 0 "ext_register_operand" "")
8539         (and (match_dup 0)
8540              (const_int -65281)))
8541    (clobber (reg:CC FLAGS_REG))]
8542   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8543   [(parallel [(set (zero_extract:SI (match_dup 0)
8544                                     (const_int 8)
8545                                     (const_int 8))
8546                    (xor:SI
8547                      (zero_extract:SI (match_dup 0)
8548                                       (const_int 8)
8549                                       (const_int 8))
8550                      (zero_extract:SI (match_dup 0)
8551                                       (const_int 8)
8552                                       (const_int 8))))
8553               (clobber (reg:CC FLAGS_REG))])]
8554   "operands[0] = gen_lowpart (SImode, operands[0]);")
8555
8556 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8557 (define_insn "*andsi_1_zext"
8558   [(set (match_operand:DI 0 "register_operand" "=r")
8559         (zero_extend:DI
8560           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8561                   (match_operand:SI 2 "general_operand" "rim"))))
8562    (clobber (reg:CC FLAGS_REG))]
8563   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8564   "and{l}\t{%2, %k0|%k0, %2}"
8565   [(set_attr "type" "alu")
8566    (set_attr "mode" "SI")])
8567
8568 (define_insn "*andsi_2"
8569   [(set (reg FLAGS_REG)
8570         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8571                          (match_operand:SI 2 "general_operand" "rim,ri"))
8572                  (const_int 0)))
8573    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8574         (and:SI (match_dup 1) (match_dup 2)))]
8575   "ix86_match_ccmode (insn, CCNOmode)
8576    && ix86_binary_operator_ok (AND, SImode, operands)"
8577   "and{l}\t{%2, %0|%0, %2}"
8578   [(set_attr "type" "alu")
8579    (set_attr "mode" "SI")])
8580
8581 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8582 (define_insn "*andsi_2_zext"
8583   [(set (reg FLAGS_REG)
8584         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8585                          (match_operand:SI 2 "general_operand" "rim"))
8586                  (const_int 0)))
8587    (set (match_operand:DI 0 "register_operand" "=r")
8588         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8589   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8590    && ix86_binary_operator_ok (AND, SImode, operands)"
8591   "and{l}\t{%2, %k0|%k0, %2}"
8592   [(set_attr "type" "alu")
8593    (set_attr "mode" "SI")])
8594
8595 (define_expand "andhi3"
8596   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8597         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8598                 (match_operand:HI 2 "general_operand" "")))
8599    (clobber (reg:CC FLAGS_REG))]
8600   "TARGET_HIMODE_MATH"
8601   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8602
8603 (define_insn "*andhi_1"
8604   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8605         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8606                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8607    (clobber (reg:CC FLAGS_REG))]
8608   "ix86_binary_operator_ok (AND, HImode, operands)"
8609 {
8610   switch (get_attr_type (insn))
8611     {
8612     case TYPE_IMOVX:
8613       gcc_assert (CONST_INT_P (operands[2]));
8614       gcc_assert (INTVAL (operands[2]) == 0xff);
8615       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8616
8617     default:
8618       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8619
8620       return "and{w}\t{%2, %0|%0, %2}";
8621     }
8622 }
8623   [(set_attr "type" "alu,alu,imovx")
8624    (set_attr "length_immediate" "*,*,0")
8625    (set_attr "mode" "HI,HI,SI")])
8626
8627 (define_insn "*andhi_2"
8628   [(set (reg FLAGS_REG)
8629         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8630                          (match_operand:HI 2 "general_operand" "rim,ri"))
8631                  (const_int 0)))
8632    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8633         (and:HI (match_dup 1) (match_dup 2)))]
8634   "ix86_match_ccmode (insn, CCNOmode)
8635    && ix86_binary_operator_ok (AND, HImode, operands)"
8636   "and{w}\t{%2, %0|%0, %2}"
8637   [(set_attr "type" "alu")
8638    (set_attr "mode" "HI")])
8639
8640 (define_expand "andqi3"
8641   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8642         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8643                 (match_operand:QI 2 "general_operand" "")))
8644    (clobber (reg:CC FLAGS_REG))]
8645   "TARGET_QIMODE_MATH"
8646   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8647
8648 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8649 (define_insn "*andqi_1"
8650   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8651         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8652                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8653    (clobber (reg:CC FLAGS_REG))]
8654   "ix86_binary_operator_ok (AND, QImode, operands)"
8655   "@
8656    and{b}\t{%2, %0|%0, %2}
8657    and{b}\t{%2, %0|%0, %2}
8658    and{l}\t{%k2, %k0|%k0, %k2}"
8659   [(set_attr "type" "alu")
8660    (set_attr "mode" "QI,QI,SI")])
8661
8662 (define_insn "*andqi_1_slp"
8663   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8664         (and:QI (match_dup 0)
8665                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8666    (clobber (reg:CC FLAGS_REG))]
8667   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8668    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8669   "and{b}\t{%1, %0|%0, %1}"
8670   [(set_attr "type" "alu1")
8671    (set_attr "mode" "QI")])
8672
8673 (define_insn "*andqi_2_maybe_si"
8674   [(set (reg FLAGS_REG)
8675         (compare (and:QI
8676                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8677                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8678                  (const_int 0)))
8679    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8680         (and:QI (match_dup 1) (match_dup 2)))]
8681   "ix86_binary_operator_ok (AND, QImode, operands)
8682    && ix86_match_ccmode (insn,
8683                          CONST_INT_P (operands[2])
8684                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8685 {
8686   if (which_alternative == 2)
8687     {
8688       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8689         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8690       return "and{l}\t{%2, %k0|%k0, %2}";
8691     }
8692   return "and{b}\t{%2, %0|%0, %2}";
8693 }
8694   [(set_attr "type" "alu")
8695    (set_attr "mode" "QI,QI,SI")])
8696
8697 (define_insn "*andqi_2"
8698   [(set (reg FLAGS_REG)
8699         (compare (and:QI
8700                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8701                    (match_operand:QI 2 "general_operand" "qim,qi"))
8702                  (const_int 0)))
8703    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8704         (and:QI (match_dup 1) (match_dup 2)))]
8705   "ix86_match_ccmode (insn, CCNOmode)
8706    && ix86_binary_operator_ok (AND, QImode, operands)"
8707   "and{b}\t{%2, %0|%0, %2}"
8708   [(set_attr "type" "alu")
8709    (set_attr "mode" "QI")])
8710
8711 (define_insn "*andqi_2_slp"
8712   [(set (reg FLAGS_REG)
8713         (compare (and:QI
8714                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8715                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8716                  (const_int 0)))
8717    (set (strict_low_part (match_dup 0))
8718         (and:QI (match_dup 0) (match_dup 1)))]
8719   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8720    && ix86_match_ccmode (insn, CCNOmode)
8721    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8722   "and{b}\t{%1, %0|%0, %1}"
8723   [(set_attr "type" "alu1")
8724    (set_attr "mode" "QI")])
8725
8726 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8727 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8728 ;; for a QImode operand, which of course failed.
8729
8730 (define_insn "andqi_ext_0"
8731   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8732                          (const_int 8)
8733                          (const_int 8))
8734         (and:SI
8735           (zero_extract:SI
8736             (match_operand 1 "ext_register_operand" "0")
8737             (const_int 8)
8738             (const_int 8))
8739           (match_operand 2 "const_int_operand" "n")))
8740    (clobber (reg:CC FLAGS_REG))]
8741   ""
8742   "and{b}\t{%2, %h0|%h0, %2}"
8743   [(set_attr "type" "alu")
8744    (set_attr "length_immediate" "1")
8745    (set_attr "mode" "QI")])
8746
8747 ;; Generated by peephole translating test to and.  This shows up
8748 ;; often in fp comparisons.
8749
8750 (define_insn "*andqi_ext_0_cc"
8751   [(set (reg FLAGS_REG)
8752         (compare
8753           (and:SI
8754             (zero_extract:SI
8755               (match_operand 1 "ext_register_operand" "0")
8756               (const_int 8)
8757               (const_int 8))
8758             (match_operand 2 "const_int_operand" "n"))
8759           (const_int 0)))
8760    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8761                          (const_int 8)
8762                          (const_int 8))
8763         (and:SI
8764           (zero_extract:SI
8765             (match_dup 1)
8766             (const_int 8)
8767             (const_int 8))
8768           (match_dup 2)))]
8769   "ix86_match_ccmode (insn, CCNOmode)"
8770   "and{b}\t{%2, %h0|%h0, %2}"
8771   [(set_attr "type" "alu")
8772    (set_attr "length_immediate" "1")
8773    (set_attr "mode" "QI")])
8774
8775 (define_insn "*andqi_ext_1"
8776   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8777                          (const_int 8)
8778                          (const_int 8))
8779         (and:SI
8780           (zero_extract:SI
8781             (match_operand 1 "ext_register_operand" "0")
8782             (const_int 8)
8783             (const_int 8))
8784           (zero_extend:SI
8785             (match_operand:QI 2 "general_operand" "Qm"))))
8786    (clobber (reg:CC FLAGS_REG))]
8787   "!TARGET_64BIT"
8788   "and{b}\t{%2, %h0|%h0, %2}"
8789   [(set_attr "type" "alu")
8790    (set_attr "length_immediate" "0")
8791    (set_attr "mode" "QI")])
8792
8793 (define_insn "*andqi_ext_1_rex64"
8794   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8795                          (const_int 8)
8796                          (const_int 8))
8797         (and:SI
8798           (zero_extract:SI
8799             (match_operand 1 "ext_register_operand" "0")
8800             (const_int 8)
8801             (const_int 8))
8802           (zero_extend:SI
8803             (match_operand 2 "ext_register_operand" "Q"))))
8804    (clobber (reg:CC FLAGS_REG))]
8805   "TARGET_64BIT"
8806   "and{b}\t{%2, %h0|%h0, %2}"
8807   [(set_attr "type" "alu")
8808    (set_attr "length_immediate" "0")
8809    (set_attr "mode" "QI")])
8810
8811 (define_insn "*andqi_ext_2"
8812   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8813                          (const_int 8)
8814                          (const_int 8))
8815         (and:SI
8816           (zero_extract:SI
8817             (match_operand 1 "ext_register_operand" "%0")
8818             (const_int 8)
8819             (const_int 8))
8820           (zero_extract:SI
8821             (match_operand 2 "ext_register_operand" "Q")
8822             (const_int 8)
8823             (const_int 8))))
8824    (clobber (reg:CC FLAGS_REG))]
8825   ""
8826   "and{b}\t{%h2, %h0|%h0, %h2}"
8827   [(set_attr "type" "alu")
8828    (set_attr "length_immediate" "0")
8829    (set_attr "mode" "QI")])
8830
8831 ;; Convert wide AND instructions with immediate operand to shorter QImode
8832 ;; equivalents when possible.
8833 ;; Don't do the splitting with memory operands, since it introduces risk
8834 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8835 ;; for size, but that can (should?) be handled by generic code instead.
8836 (define_split
8837   [(set (match_operand 0 "register_operand" "")
8838         (and (match_operand 1 "register_operand" "")
8839              (match_operand 2 "const_int_operand" "")))
8840    (clobber (reg:CC FLAGS_REG))]
8841    "reload_completed
8842     && QI_REG_P (operands[0])
8843     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8844     && !(~INTVAL (operands[2]) & ~(255 << 8))
8845     && GET_MODE (operands[0]) != QImode"
8846   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8847                    (and:SI (zero_extract:SI (match_dup 1)
8848                                             (const_int 8) (const_int 8))
8849                            (match_dup 2)))
8850               (clobber (reg:CC FLAGS_REG))])]
8851   "operands[0] = gen_lowpart (SImode, operands[0]);
8852    operands[1] = gen_lowpart (SImode, operands[1]);
8853    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8854
8855 ;; Since AND can be encoded with sign extended immediate, this is only
8856 ;; profitable when 7th bit is not set.
8857 (define_split
8858   [(set (match_operand 0 "register_operand" "")
8859         (and (match_operand 1 "general_operand" "")
8860              (match_operand 2 "const_int_operand" "")))
8861    (clobber (reg:CC FLAGS_REG))]
8862    "reload_completed
8863     && ANY_QI_REG_P (operands[0])
8864     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8865     && !(~INTVAL (operands[2]) & ~255)
8866     && !(INTVAL (operands[2]) & 128)
8867     && GET_MODE (operands[0]) != QImode"
8868   [(parallel [(set (strict_low_part (match_dup 0))
8869                    (and:QI (match_dup 1)
8870                            (match_dup 2)))
8871               (clobber (reg:CC FLAGS_REG))])]
8872   "operands[0] = gen_lowpart (QImode, operands[0]);
8873    operands[1] = gen_lowpart (QImode, operands[1]);
8874    operands[2] = gen_lowpart (QImode, operands[2]);")
8875 \f
8876 ;; Logical inclusive OR instructions
8877
8878 ;; %%% This used to optimize known byte-wide and operations to memory.
8879 ;; If this is considered useful, it should be done with splitters.
8880
8881 (define_expand "iordi3"
8882   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8883         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8884                 (match_operand:DI 2 "x86_64_general_operand" "")))
8885    (clobber (reg:CC FLAGS_REG))]
8886   "TARGET_64BIT"
8887   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8888
8889 (define_insn "*iordi_1_rex64"
8890   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8891         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8892                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8893    (clobber (reg:CC FLAGS_REG))]
8894   "TARGET_64BIT
8895    && ix86_binary_operator_ok (IOR, DImode, operands)"
8896   "or{q}\t{%2, %0|%0, %2}"
8897   [(set_attr "type" "alu")
8898    (set_attr "mode" "DI")])
8899
8900 (define_insn "*iordi_2_rex64"
8901   [(set (reg FLAGS_REG)
8902         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8903                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8904                  (const_int 0)))
8905    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8906         (ior:DI (match_dup 1) (match_dup 2)))]
8907   "TARGET_64BIT
8908    && ix86_match_ccmode (insn, CCNOmode)
8909    && ix86_binary_operator_ok (IOR, DImode, operands)"
8910   "or{q}\t{%2, %0|%0, %2}"
8911   [(set_attr "type" "alu")
8912    (set_attr "mode" "DI")])
8913
8914 (define_insn "*iordi_3_rex64"
8915   [(set (reg FLAGS_REG)
8916         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8917                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8918                  (const_int 0)))
8919    (clobber (match_scratch:DI 0 "=r"))]
8920   "TARGET_64BIT
8921    && ix86_match_ccmode (insn, CCNOmode)
8922    && ix86_binary_operator_ok (IOR, DImode, operands)"
8923   "or{q}\t{%2, %0|%0, %2}"
8924   [(set_attr "type" "alu")
8925    (set_attr "mode" "DI")])
8926
8927
8928 (define_expand "iorsi3"
8929   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8930         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8931                 (match_operand:SI 2 "general_operand" "")))
8932    (clobber (reg:CC FLAGS_REG))]
8933   ""
8934   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8935
8936 (define_insn "*iorsi_1"
8937   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8938         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8939                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8940    (clobber (reg:CC FLAGS_REG))]
8941   "ix86_binary_operator_ok (IOR, SImode, operands)"
8942   "or{l}\t{%2, %0|%0, %2}"
8943   [(set_attr "type" "alu")
8944    (set_attr "mode" "SI")])
8945
8946 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8947 (define_insn "*iorsi_1_zext"
8948   [(set (match_operand:DI 0 "register_operand" "=rm")
8949         (zero_extend:DI
8950           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8951                   (match_operand:SI 2 "general_operand" "rim"))))
8952    (clobber (reg:CC FLAGS_REG))]
8953   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8954   "or{l}\t{%2, %k0|%k0, %2}"
8955   [(set_attr "type" "alu")
8956    (set_attr "mode" "SI")])
8957
8958 (define_insn "*iorsi_1_zext_imm"
8959   [(set (match_operand:DI 0 "register_operand" "=rm")
8960         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8961                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8962    (clobber (reg:CC FLAGS_REG))]
8963   "TARGET_64BIT"
8964   "or{l}\t{%2, %k0|%k0, %2}"
8965   [(set_attr "type" "alu")
8966    (set_attr "mode" "SI")])
8967
8968 (define_insn "*iorsi_2"
8969   [(set (reg FLAGS_REG)
8970         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8971                          (match_operand:SI 2 "general_operand" "rim,ri"))
8972                  (const_int 0)))
8973    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8974         (ior:SI (match_dup 1) (match_dup 2)))]
8975   "ix86_match_ccmode (insn, CCNOmode)
8976    && ix86_binary_operator_ok (IOR, SImode, operands)"
8977   "or{l}\t{%2, %0|%0, %2}"
8978   [(set_attr "type" "alu")
8979    (set_attr "mode" "SI")])
8980
8981 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8982 ;; ??? Special case for immediate operand is missing - it is tricky.
8983 (define_insn "*iorsi_2_zext"
8984   [(set (reg FLAGS_REG)
8985         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8986                          (match_operand:SI 2 "general_operand" "rim"))
8987                  (const_int 0)))
8988    (set (match_operand:DI 0 "register_operand" "=r")
8989         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8990   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8991    && ix86_binary_operator_ok (IOR, SImode, operands)"
8992   "or{l}\t{%2, %k0|%k0, %2}"
8993   [(set_attr "type" "alu")
8994    (set_attr "mode" "SI")])
8995
8996 (define_insn "*iorsi_2_zext_imm"
8997   [(set (reg FLAGS_REG)
8998         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8999                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9000                  (const_int 0)))
9001    (set (match_operand:DI 0 "register_operand" "=r")
9002         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9003   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9004    && ix86_binary_operator_ok (IOR, SImode, operands)"
9005   "or{l}\t{%2, %k0|%k0, %2}"
9006   [(set_attr "type" "alu")
9007    (set_attr "mode" "SI")])
9008
9009 (define_insn "*iorsi_3"
9010   [(set (reg FLAGS_REG)
9011         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9012                          (match_operand:SI 2 "general_operand" "rim"))
9013                  (const_int 0)))
9014    (clobber (match_scratch:SI 0 "=r"))]
9015   "ix86_match_ccmode (insn, CCNOmode)
9016    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9017   "or{l}\t{%2, %0|%0, %2}"
9018   [(set_attr "type" "alu")
9019    (set_attr "mode" "SI")])
9020
9021 (define_expand "iorhi3"
9022   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9023         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9024                 (match_operand:HI 2 "general_operand" "")))
9025    (clobber (reg:CC FLAGS_REG))]
9026   "TARGET_HIMODE_MATH"
9027   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9028
9029 (define_insn "*iorhi_1"
9030   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9031         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9032                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9033    (clobber (reg:CC FLAGS_REG))]
9034   "ix86_binary_operator_ok (IOR, HImode, operands)"
9035   "or{w}\t{%2, %0|%0, %2}"
9036   [(set_attr "type" "alu")
9037    (set_attr "mode" "HI")])
9038
9039 (define_insn "*iorhi_2"
9040   [(set (reg FLAGS_REG)
9041         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9042                          (match_operand:HI 2 "general_operand" "rim,ri"))
9043                  (const_int 0)))
9044    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9045         (ior:HI (match_dup 1) (match_dup 2)))]
9046   "ix86_match_ccmode (insn, CCNOmode)
9047    && ix86_binary_operator_ok (IOR, HImode, operands)"
9048   "or{w}\t{%2, %0|%0, %2}"
9049   [(set_attr "type" "alu")
9050    (set_attr "mode" "HI")])
9051
9052 (define_insn "*iorhi_3"
9053   [(set (reg FLAGS_REG)
9054         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9055                          (match_operand:HI 2 "general_operand" "rim"))
9056                  (const_int 0)))
9057    (clobber (match_scratch:HI 0 "=r"))]
9058   "ix86_match_ccmode (insn, CCNOmode)
9059    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9060   "or{w}\t{%2, %0|%0, %2}"
9061   [(set_attr "type" "alu")
9062    (set_attr "mode" "HI")])
9063
9064 (define_expand "iorqi3"
9065   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9066         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9067                 (match_operand:QI 2 "general_operand" "")))
9068    (clobber (reg:CC FLAGS_REG))]
9069   "TARGET_QIMODE_MATH"
9070   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9071
9072 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9073 (define_insn "*iorqi_1"
9074   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9075         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9076                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9077    (clobber (reg:CC FLAGS_REG))]
9078   "ix86_binary_operator_ok (IOR, QImode, operands)"
9079   "@
9080    or{b}\t{%2, %0|%0, %2}
9081    or{b}\t{%2, %0|%0, %2}
9082    or{l}\t{%k2, %k0|%k0, %k2}"
9083   [(set_attr "type" "alu")
9084    (set_attr "mode" "QI,QI,SI")])
9085
9086 (define_insn "*iorqi_1_slp"
9087   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9088         (ior:QI (match_dup 0)
9089                 (match_operand:QI 1 "general_operand" "qmi,qi")))
9090    (clobber (reg:CC FLAGS_REG))]
9091   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9092    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9093   "or{b}\t{%1, %0|%0, %1}"
9094   [(set_attr "type" "alu1")
9095    (set_attr "mode" "QI")])
9096
9097 (define_insn "*iorqi_2"
9098   [(set (reg FLAGS_REG)
9099         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9100                          (match_operand:QI 2 "general_operand" "qim,qi"))
9101                  (const_int 0)))
9102    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9103         (ior:QI (match_dup 1) (match_dup 2)))]
9104   "ix86_match_ccmode (insn, CCNOmode)
9105    && ix86_binary_operator_ok (IOR, QImode, operands)"
9106   "or{b}\t{%2, %0|%0, %2}"
9107   [(set_attr "type" "alu")
9108    (set_attr "mode" "QI")])
9109
9110 (define_insn "*iorqi_2_slp"
9111   [(set (reg FLAGS_REG)
9112         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9113                          (match_operand:QI 1 "general_operand" "qim,qi"))
9114                  (const_int 0)))
9115    (set (strict_low_part (match_dup 0))
9116         (ior:QI (match_dup 0) (match_dup 1)))]
9117   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9118    && ix86_match_ccmode (insn, CCNOmode)
9119    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9120   "or{b}\t{%1, %0|%0, %1}"
9121   [(set_attr "type" "alu1")
9122    (set_attr "mode" "QI")])
9123
9124 (define_insn "*iorqi_3"
9125   [(set (reg FLAGS_REG)
9126         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9127                          (match_operand:QI 2 "general_operand" "qim"))
9128                  (const_int 0)))
9129    (clobber (match_scratch:QI 0 "=q"))]
9130   "ix86_match_ccmode (insn, CCNOmode)
9131    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9132   "or{b}\t{%2, %0|%0, %2}"
9133   [(set_attr "type" "alu")
9134    (set_attr "mode" "QI")])
9135
9136 (define_insn "iorqi_ext_0"
9137   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9138                          (const_int 8)
9139                          (const_int 8))
9140         (ior:SI
9141           (zero_extract:SI
9142             (match_operand 1 "ext_register_operand" "0")
9143             (const_int 8)
9144             (const_int 8))
9145           (match_operand 2 "const_int_operand" "n")))
9146    (clobber (reg:CC FLAGS_REG))]
9147   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9148   "or{b}\t{%2, %h0|%h0, %2}"
9149   [(set_attr "type" "alu")
9150    (set_attr "length_immediate" "1")
9151    (set_attr "mode" "QI")])
9152
9153 (define_insn "*iorqi_ext_1"
9154   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9155                          (const_int 8)
9156                          (const_int 8))
9157         (ior:SI
9158           (zero_extract:SI
9159             (match_operand 1 "ext_register_operand" "0")
9160             (const_int 8)
9161             (const_int 8))
9162           (zero_extend:SI
9163             (match_operand:QI 2 "general_operand" "Qm"))))
9164    (clobber (reg:CC FLAGS_REG))]
9165   "!TARGET_64BIT
9166    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9167   "or{b}\t{%2, %h0|%h0, %2}"
9168   [(set_attr "type" "alu")
9169    (set_attr "length_immediate" "0")
9170    (set_attr "mode" "QI")])
9171
9172 (define_insn "*iorqi_ext_1_rex64"
9173   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9174                          (const_int 8)
9175                          (const_int 8))
9176         (ior:SI
9177           (zero_extract:SI
9178             (match_operand 1 "ext_register_operand" "0")
9179             (const_int 8)
9180             (const_int 8))
9181           (zero_extend:SI
9182             (match_operand 2 "ext_register_operand" "Q"))))
9183    (clobber (reg:CC FLAGS_REG))]
9184   "TARGET_64BIT
9185    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9186   "or{b}\t{%2, %h0|%h0, %2}"
9187   [(set_attr "type" "alu")
9188    (set_attr "length_immediate" "0")
9189    (set_attr "mode" "QI")])
9190
9191 (define_insn "*iorqi_ext_2"
9192   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9193                          (const_int 8)
9194                          (const_int 8))
9195         (ior:SI
9196           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9197                            (const_int 8)
9198                            (const_int 8))
9199           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9200                            (const_int 8)
9201                            (const_int 8))))
9202    (clobber (reg:CC FLAGS_REG))]
9203   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9204   "ior{b}\t{%h2, %h0|%h0, %h2}"
9205   [(set_attr "type" "alu")
9206    (set_attr "length_immediate" "0")
9207    (set_attr "mode" "QI")])
9208
9209 (define_split
9210   [(set (match_operand 0 "register_operand" "")
9211         (ior (match_operand 1 "register_operand" "")
9212              (match_operand 2 "const_int_operand" "")))
9213    (clobber (reg:CC FLAGS_REG))]
9214    "reload_completed
9215     && QI_REG_P (operands[0])
9216     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9217     && !(INTVAL (operands[2]) & ~(255 << 8))
9218     && GET_MODE (operands[0]) != QImode"
9219   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9220                    (ior:SI (zero_extract:SI (match_dup 1)
9221                                             (const_int 8) (const_int 8))
9222                            (match_dup 2)))
9223               (clobber (reg:CC FLAGS_REG))])]
9224   "operands[0] = gen_lowpart (SImode, operands[0]);
9225    operands[1] = gen_lowpart (SImode, operands[1]);
9226    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9227
9228 ;; Since OR can be encoded with sign extended immediate, this is only
9229 ;; profitable when 7th bit is set.
9230 (define_split
9231   [(set (match_operand 0 "register_operand" "")
9232         (ior (match_operand 1 "general_operand" "")
9233              (match_operand 2 "const_int_operand" "")))
9234    (clobber (reg:CC FLAGS_REG))]
9235    "reload_completed
9236     && ANY_QI_REG_P (operands[0])
9237     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9238     && !(INTVAL (operands[2]) & ~255)
9239     && (INTVAL (operands[2]) & 128)
9240     && GET_MODE (operands[0]) != QImode"
9241   [(parallel [(set (strict_low_part (match_dup 0))
9242                    (ior:QI (match_dup 1)
9243                            (match_dup 2)))
9244               (clobber (reg:CC FLAGS_REG))])]
9245   "operands[0] = gen_lowpart (QImode, operands[0]);
9246    operands[1] = gen_lowpart (QImode, operands[1]);
9247    operands[2] = gen_lowpart (QImode, operands[2]);")
9248 \f
9249 ;; Logical XOR instructions
9250
9251 ;; %%% This used to optimize known byte-wide and operations to memory.
9252 ;; If this is considered useful, it should be done with splitters.
9253
9254 (define_expand "xordi3"
9255   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9256         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9257                 (match_operand:DI 2 "x86_64_general_operand" "")))
9258    (clobber (reg:CC FLAGS_REG))]
9259   "TARGET_64BIT"
9260   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9261
9262 (define_insn "*xordi_1_rex64"
9263   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9264         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9265                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9266    (clobber (reg:CC FLAGS_REG))]
9267   "TARGET_64BIT
9268    && ix86_binary_operator_ok (XOR, DImode, operands)"
9269   "@
9270    xor{q}\t{%2, %0|%0, %2}
9271    xor{q}\t{%2, %0|%0, %2}"
9272   [(set_attr "type" "alu")
9273    (set_attr "mode" "DI,DI")])
9274
9275 (define_insn "*xordi_2_rex64"
9276   [(set (reg FLAGS_REG)
9277         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9278                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9279                  (const_int 0)))
9280    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9281         (xor:DI (match_dup 1) (match_dup 2)))]
9282   "TARGET_64BIT
9283    && ix86_match_ccmode (insn, CCNOmode)
9284    && ix86_binary_operator_ok (XOR, DImode, operands)"
9285   "@
9286    xor{q}\t{%2, %0|%0, %2}
9287    xor{q}\t{%2, %0|%0, %2}"
9288   [(set_attr "type" "alu")
9289    (set_attr "mode" "DI,DI")])
9290
9291 (define_insn "*xordi_3_rex64"
9292   [(set (reg FLAGS_REG)
9293         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9294                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9295                  (const_int 0)))
9296    (clobber (match_scratch:DI 0 "=r"))]
9297   "TARGET_64BIT
9298    && ix86_match_ccmode (insn, CCNOmode)
9299    && ix86_binary_operator_ok (XOR, DImode, operands)"
9300   "xor{q}\t{%2, %0|%0, %2}"
9301   [(set_attr "type" "alu")
9302    (set_attr "mode" "DI")])
9303
9304 (define_expand "xorsi3"
9305   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9306         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9307                 (match_operand:SI 2 "general_operand" "")))
9308    (clobber (reg:CC FLAGS_REG))]
9309   ""
9310   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9311
9312 (define_insn "*xorsi_1"
9313   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9314         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9315                 (match_operand:SI 2 "general_operand" "ri,rm")))
9316    (clobber (reg:CC FLAGS_REG))]
9317   "ix86_binary_operator_ok (XOR, SImode, operands)"
9318   "xor{l}\t{%2, %0|%0, %2}"
9319   [(set_attr "type" "alu")
9320    (set_attr "mode" "SI")])
9321
9322 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9323 ;; Add speccase for immediates
9324 (define_insn "*xorsi_1_zext"
9325   [(set (match_operand:DI 0 "register_operand" "=r")
9326         (zero_extend:DI
9327           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9328                   (match_operand:SI 2 "general_operand" "rim"))))
9329    (clobber (reg:CC FLAGS_REG))]
9330   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9331   "xor{l}\t{%2, %k0|%k0, %2}"
9332   [(set_attr "type" "alu")
9333    (set_attr "mode" "SI")])
9334
9335 (define_insn "*xorsi_1_zext_imm"
9336   [(set (match_operand:DI 0 "register_operand" "=r")
9337         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9338                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9339    (clobber (reg:CC FLAGS_REG))]
9340   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9341   "xor{l}\t{%2, %k0|%k0, %2}"
9342   [(set_attr "type" "alu")
9343    (set_attr "mode" "SI")])
9344
9345 (define_insn "*xorsi_2"
9346   [(set (reg FLAGS_REG)
9347         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9348                          (match_operand:SI 2 "general_operand" "rim,ri"))
9349                  (const_int 0)))
9350    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9351         (xor:SI (match_dup 1) (match_dup 2)))]
9352   "ix86_match_ccmode (insn, CCNOmode)
9353    && ix86_binary_operator_ok (XOR, SImode, operands)"
9354   "xor{l}\t{%2, %0|%0, %2}"
9355   [(set_attr "type" "alu")
9356    (set_attr "mode" "SI")])
9357
9358 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9359 ;; ??? Special case for immediate operand is missing - it is tricky.
9360 (define_insn "*xorsi_2_zext"
9361   [(set (reg FLAGS_REG)
9362         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9363                          (match_operand:SI 2 "general_operand" "rim"))
9364                  (const_int 0)))
9365    (set (match_operand:DI 0 "register_operand" "=r")
9366         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9367   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9368    && ix86_binary_operator_ok (XOR, SImode, operands)"
9369   "xor{l}\t{%2, %k0|%k0, %2}"
9370   [(set_attr "type" "alu")
9371    (set_attr "mode" "SI")])
9372
9373 (define_insn "*xorsi_2_zext_imm"
9374   [(set (reg FLAGS_REG)
9375         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9376                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9377                  (const_int 0)))
9378    (set (match_operand:DI 0 "register_operand" "=r")
9379         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9380   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9381    && ix86_binary_operator_ok (XOR, SImode, operands)"
9382   "xor{l}\t{%2, %k0|%k0, %2}"
9383   [(set_attr "type" "alu")
9384    (set_attr "mode" "SI")])
9385
9386 (define_insn "*xorsi_3"
9387   [(set (reg FLAGS_REG)
9388         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9389                          (match_operand:SI 2 "general_operand" "rim"))
9390                  (const_int 0)))
9391    (clobber (match_scratch:SI 0 "=r"))]
9392   "ix86_match_ccmode (insn, CCNOmode)
9393    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9394   "xor{l}\t{%2, %0|%0, %2}"
9395   [(set_attr "type" "alu")
9396    (set_attr "mode" "SI")])
9397
9398 (define_expand "xorhi3"
9399   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9400         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9401                 (match_operand:HI 2 "general_operand" "")))
9402    (clobber (reg:CC FLAGS_REG))]
9403   "TARGET_HIMODE_MATH"
9404   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9405
9406 (define_insn "*xorhi_1"
9407   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9408         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9409                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9410    (clobber (reg:CC FLAGS_REG))]
9411   "ix86_binary_operator_ok (XOR, HImode, operands)"
9412   "xor{w}\t{%2, %0|%0, %2}"
9413   [(set_attr "type" "alu")
9414    (set_attr "mode" "HI")])
9415
9416 (define_insn "*xorhi_2"
9417   [(set (reg FLAGS_REG)
9418         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9419                          (match_operand:HI 2 "general_operand" "rim,ri"))
9420                  (const_int 0)))
9421    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9422         (xor:HI (match_dup 1) (match_dup 2)))]
9423   "ix86_match_ccmode (insn, CCNOmode)
9424    && ix86_binary_operator_ok (XOR, HImode, operands)"
9425   "xor{w}\t{%2, %0|%0, %2}"
9426   [(set_attr "type" "alu")
9427    (set_attr "mode" "HI")])
9428
9429 (define_insn "*xorhi_3"
9430   [(set (reg FLAGS_REG)
9431         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9432                          (match_operand:HI 2 "general_operand" "rim"))
9433                  (const_int 0)))
9434    (clobber (match_scratch:HI 0 "=r"))]
9435   "ix86_match_ccmode (insn, CCNOmode)
9436    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9437   "xor{w}\t{%2, %0|%0, %2}"
9438   [(set_attr "type" "alu")
9439    (set_attr "mode" "HI")])
9440
9441 (define_expand "xorqi3"
9442   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9443         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9444                 (match_operand:QI 2 "general_operand" "")))
9445    (clobber (reg:CC FLAGS_REG))]
9446   "TARGET_QIMODE_MATH"
9447   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9448
9449 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9450 (define_insn "*xorqi_1"
9451   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9452         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9453                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9454    (clobber (reg:CC FLAGS_REG))]
9455   "ix86_binary_operator_ok (XOR, QImode, operands)"
9456   "@
9457    xor{b}\t{%2, %0|%0, %2}
9458    xor{b}\t{%2, %0|%0, %2}
9459    xor{l}\t{%k2, %k0|%k0, %k2}"
9460   [(set_attr "type" "alu")
9461    (set_attr "mode" "QI,QI,SI")])
9462
9463 (define_insn "*xorqi_1_slp"
9464   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9465         (xor:QI (match_dup 0)
9466                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9467    (clobber (reg:CC FLAGS_REG))]
9468   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9469    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9470   "xor{b}\t{%1, %0|%0, %1}"
9471   [(set_attr "type" "alu1")
9472    (set_attr "mode" "QI")])
9473
9474 (define_insn "xorqi_ext_0"
9475   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9476                          (const_int 8)
9477                          (const_int 8))
9478         (xor:SI
9479           (zero_extract:SI
9480             (match_operand 1 "ext_register_operand" "0")
9481             (const_int 8)
9482             (const_int 8))
9483           (match_operand 2 "const_int_operand" "n")))
9484    (clobber (reg:CC FLAGS_REG))]
9485   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9486   "xor{b}\t{%2, %h0|%h0, %2}"
9487   [(set_attr "type" "alu")
9488    (set_attr "length_immediate" "1")
9489    (set_attr "mode" "QI")])
9490
9491 (define_insn "*xorqi_ext_1"
9492   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9493                          (const_int 8)
9494                          (const_int 8))
9495         (xor:SI
9496           (zero_extract:SI
9497             (match_operand 1 "ext_register_operand" "0")
9498             (const_int 8)
9499             (const_int 8))
9500           (zero_extend:SI
9501             (match_operand:QI 2 "general_operand" "Qm"))))
9502    (clobber (reg:CC FLAGS_REG))]
9503   "!TARGET_64BIT
9504    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9505   "xor{b}\t{%2, %h0|%h0, %2}"
9506   [(set_attr "type" "alu")
9507    (set_attr "length_immediate" "0")
9508    (set_attr "mode" "QI")])
9509
9510 (define_insn "*xorqi_ext_1_rex64"
9511   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9512                          (const_int 8)
9513                          (const_int 8))
9514         (xor:SI
9515           (zero_extract:SI
9516             (match_operand 1 "ext_register_operand" "0")
9517             (const_int 8)
9518             (const_int 8))
9519           (zero_extend:SI
9520             (match_operand 2 "ext_register_operand" "Q"))))
9521    (clobber (reg:CC FLAGS_REG))]
9522   "TARGET_64BIT
9523    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9524   "xor{b}\t{%2, %h0|%h0, %2}"
9525   [(set_attr "type" "alu")
9526    (set_attr "length_immediate" "0")
9527    (set_attr "mode" "QI")])
9528
9529 (define_insn "*xorqi_ext_2"
9530   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9531                          (const_int 8)
9532                          (const_int 8))
9533         (xor:SI
9534           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9535                            (const_int 8)
9536                            (const_int 8))
9537           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9538                            (const_int 8)
9539                            (const_int 8))))
9540    (clobber (reg:CC FLAGS_REG))]
9541   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9542   "xor{b}\t{%h2, %h0|%h0, %h2}"
9543   [(set_attr "type" "alu")
9544    (set_attr "length_immediate" "0")
9545    (set_attr "mode" "QI")])
9546
9547 (define_insn "*xorqi_cc_1"
9548   [(set (reg FLAGS_REG)
9549         (compare
9550           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9551                   (match_operand:QI 2 "general_operand" "qim,qi"))
9552           (const_int 0)))
9553    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9554         (xor:QI (match_dup 1) (match_dup 2)))]
9555   "ix86_match_ccmode (insn, CCNOmode)
9556    && ix86_binary_operator_ok (XOR, QImode, operands)"
9557   "xor{b}\t{%2, %0|%0, %2}"
9558   [(set_attr "type" "alu")
9559    (set_attr "mode" "QI")])
9560
9561 (define_insn "*xorqi_2_slp"
9562   [(set (reg FLAGS_REG)
9563         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9564                          (match_operand:QI 1 "general_operand" "qim,qi"))
9565                  (const_int 0)))
9566    (set (strict_low_part (match_dup 0))
9567         (xor:QI (match_dup 0) (match_dup 1)))]
9568   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9569    && ix86_match_ccmode (insn, CCNOmode)
9570    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9571   "xor{b}\t{%1, %0|%0, %1}"
9572   [(set_attr "type" "alu1")
9573    (set_attr "mode" "QI")])
9574
9575 (define_insn "*xorqi_cc_2"
9576   [(set (reg FLAGS_REG)
9577         (compare
9578           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9579                   (match_operand:QI 2 "general_operand" "qim"))
9580           (const_int 0)))
9581    (clobber (match_scratch:QI 0 "=q"))]
9582   "ix86_match_ccmode (insn, CCNOmode)
9583    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9584   "xor{b}\t{%2, %0|%0, %2}"
9585   [(set_attr "type" "alu")
9586    (set_attr "mode" "QI")])
9587
9588 (define_insn "*xorqi_cc_ext_1"
9589   [(set (reg FLAGS_REG)
9590         (compare
9591           (xor:SI
9592             (zero_extract:SI
9593               (match_operand 1 "ext_register_operand" "0")
9594               (const_int 8)
9595               (const_int 8))
9596             (match_operand:QI 2 "general_operand" "qmn"))
9597           (const_int 0)))
9598    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9599                          (const_int 8)
9600                          (const_int 8))
9601         (xor:SI
9602           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9603           (match_dup 2)))]
9604   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9605   "xor{b}\t{%2, %h0|%h0, %2}"
9606   [(set_attr "type" "alu")
9607    (set_attr "mode" "QI")])
9608
9609 (define_insn "*xorqi_cc_ext_1_rex64"
9610   [(set (reg FLAGS_REG)
9611         (compare
9612           (xor:SI
9613             (zero_extract:SI
9614               (match_operand 1 "ext_register_operand" "0")
9615               (const_int 8)
9616               (const_int 8))
9617             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9618           (const_int 0)))
9619    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9620                          (const_int 8)
9621                          (const_int 8))
9622         (xor:SI
9623           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9624           (match_dup 2)))]
9625   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9626   "xor{b}\t{%2, %h0|%h0, %2}"
9627   [(set_attr "type" "alu")
9628    (set_attr "mode" "QI")])
9629
9630 (define_expand "xorqi_cc_ext_1"
9631   [(parallel [
9632      (set (reg:CCNO FLAGS_REG)
9633           (compare:CCNO
9634             (xor:SI
9635               (zero_extract:SI
9636                 (match_operand 1 "ext_register_operand" "")
9637                 (const_int 8)
9638                 (const_int 8))
9639               (match_operand:QI 2 "general_operand" ""))
9640             (const_int 0)))
9641      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9642                            (const_int 8)
9643                            (const_int 8))
9644           (xor:SI
9645             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9646             (match_dup 2)))])]
9647   ""
9648   "")
9649
9650 (define_split
9651   [(set (match_operand 0 "register_operand" "")
9652         (xor (match_operand 1 "register_operand" "")
9653              (match_operand 2 "const_int_operand" "")))
9654    (clobber (reg:CC FLAGS_REG))]
9655    "reload_completed
9656     && QI_REG_P (operands[0])
9657     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9658     && !(INTVAL (operands[2]) & ~(255 << 8))
9659     && GET_MODE (operands[0]) != QImode"
9660   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9661                    (xor:SI (zero_extract:SI (match_dup 1)
9662                                             (const_int 8) (const_int 8))
9663                            (match_dup 2)))
9664               (clobber (reg:CC FLAGS_REG))])]
9665   "operands[0] = gen_lowpart (SImode, operands[0]);
9666    operands[1] = gen_lowpart (SImode, operands[1]);
9667    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9668
9669 ;; Since XOR can be encoded with sign extended immediate, this is only
9670 ;; profitable when 7th bit is set.
9671 (define_split
9672   [(set (match_operand 0 "register_operand" "")
9673         (xor (match_operand 1 "general_operand" "")
9674              (match_operand 2 "const_int_operand" "")))
9675    (clobber (reg:CC FLAGS_REG))]
9676    "reload_completed
9677     && ANY_QI_REG_P (operands[0])
9678     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9679     && !(INTVAL (operands[2]) & ~255)
9680     && (INTVAL (operands[2]) & 128)
9681     && GET_MODE (operands[0]) != QImode"
9682   [(parallel [(set (strict_low_part (match_dup 0))
9683                    (xor:QI (match_dup 1)
9684                            (match_dup 2)))
9685               (clobber (reg:CC FLAGS_REG))])]
9686   "operands[0] = gen_lowpart (QImode, operands[0]);
9687    operands[1] = gen_lowpart (QImode, operands[1]);
9688    operands[2] = gen_lowpart (QImode, operands[2]);")
9689 \f
9690 ;; Negation instructions
9691
9692 (define_expand "negti2"
9693   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9694                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9695               (clobber (reg:CC FLAGS_REG))])]
9696   "TARGET_64BIT"
9697   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9698
9699 (define_insn "*negti2_1"
9700   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9701         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9702    (clobber (reg:CC FLAGS_REG))]
9703   "TARGET_64BIT
9704    && ix86_unary_operator_ok (NEG, TImode, operands)"
9705   "#")
9706
9707 (define_split
9708   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9709         (neg:TI (match_operand:TI 1 "general_operand" "")))
9710    (clobber (reg:CC FLAGS_REG))]
9711   "TARGET_64BIT && reload_completed"
9712   [(parallel
9713     [(set (reg:CCZ FLAGS_REG)
9714           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9715      (set (match_dup 0) (neg:DI (match_dup 2)))])
9716    (parallel
9717     [(set (match_dup 1)
9718           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9719                             (match_dup 3))
9720                    (const_int 0)))
9721      (clobber (reg:CC FLAGS_REG))])
9722    (parallel
9723     [(set (match_dup 1)
9724           (neg:DI (match_dup 1)))
9725      (clobber (reg:CC FLAGS_REG))])]
9726   "split_ti (operands+1, 1, operands+2, operands+3);
9727    split_ti (operands+0, 1, operands+0, operands+1);")
9728
9729 (define_expand "negdi2"
9730   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9731                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9732               (clobber (reg:CC FLAGS_REG))])]
9733   ""
9734   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9735
9736 (define_insn "*negdi2_1"
9737   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9738         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9739    (clobber (reg:CC FLAGS_REG))]
9740   "!TARGET_64BIT
9741    && ix86_unary_operator_ok (NEG, DImode, operands)"
9742   "#")
9743
9744 (define_split
9745   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9746         (neg:DI (match_operand:DI 1 "general_operand" "")))
9747    (clobber (reg:CC FLAGS_REG))]
9748   "!TARGET_64BIT && reload_completed"
9749   [(parallel
9750     [(set (reg:CCZ FLAGS_REG)
9751           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9752      (set (match_dup 0) (neg:SI (match_dup 2)))])
9753    (parallel
9754     [(set (match_dup 1)
9755           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9756                             (match_dup 3))
9757                    (const_int 0)))
9758      (clobber (reg:CC FLAGS_REG))])
9759    (parallel
9760     [(set (match_dup 1)
9761           (neg:SI (match_dup 1)))
9762      (clobber (reg:CC FLAGS_REG))])]
9763   "split_di (operands+1, 1, operands+2, operands+3);
9764    split_di (operands+0, 1, operands+0, operands+1);")
9765
9766 (define_insn "*negdi2_1_rex64"
9767   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9768         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9769    (clobber (reg:CC FLAGS_REG))]
9770   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9771   "neg{q}\t%0"
9772   [(set_attr "type" "negnot")
9773    (set_attr "mode" "DI")])
9774
9775 ;; The problem with neg is that it does not perform (compare x 0),
9776 ;; it really performs (compare 0 x), which leaves us with the zero
9777 ;; flag being the only useful item.
9778
9779 (define_insn "*negdi2_cmpz_rex64"
9780   [(set (reg:CCZ FLAGS_REG)
9781         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9782                      (const_int 0)))
9783    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9784         (neg:DI (match_dup 1)))]
9785   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9786   "neg{q}\t%0"
9787   [(set_attr "type" "negnot")
9788    (set_attr "mode" "DI")])
9789
9790
9791 (define_expand "negsi2"
9792   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9793                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9794               (clobber (reg:CC FLAGS_REG))])]
9795   ""
9796   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9797
9798 (define_insn "*negsi2_1"
9799   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9800         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9801    (clobber (reg:CC FLAGS_REG))]
9802   "ix86_unary_operator_ok (NEG, SImode, operands)"
9803   "neg{l}\t%0"
9804   [(set_attr "type" "negnot")
9805    (set_attr "mode" "SI")])
9806
9807 ;; Combine is quite creative about this pattern.
9808 (define_insn "*negsi2_1_zext"
9809   [(set (match_operand:DI 0 "register_operand" "=r")
9810         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9811                                         (const_int 32)))
9812                      (const_int 32)))
9813    (clobber (reg:CC FLAGS_REG))]
9814   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9815   "neg{l}\t%k0"
9816   [(set_attr "type" "negnot")
9817    (set_attr "mode" "SI")])
9818
9819 ;; The problem with neg is that it does not perform (compare x 0),
9820 ;; it really performs (compare 0 x), which leaves us with the zero
9821 ;; flag being the only useful item.
9822
9823 (define_insn "*negsi2_cmpz"
9824   [(set (reg:CCZ FLAGS_REG)
9825         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9826                      (const_int 0)))
9827    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9828         (neg:SI (match_dup 1)))]
9829   "ix86_unary_operator_ok (NEG, SImode, operands)"
9830   "neg{l}\t%0"
9831   [(set_attr "type" "negnot")
9832    (set_attr "mode" "SI")])
9833
9834 (define_insn "*negsi2_cmpz_zext"
9835   [(set (reg:CCZ FLAGS_REG)
9836         (compare:CCZ (lshiftrt:DI
9837                        (neg:DI (ashift:DI
9838                                  (match_operand:DI 1 "register_operand" "0")
9839                                  (const_int 32)))
9840                        (const_int 32))
9841                      (const_int 0)))
9842    (set (match_operand:DI 0 "register_operand" "=r")
9843         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9844                                         (const_int 32)))
9845                      (const_int 32)))]
9846   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9847   "neg{l}\t%k0"
9848   [(set_attr "type" "negnot")
9849    (set_attr "mode" "SI")])
9850
9851 (define_expand "neghi2"
9852   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9853                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9854               (clobber (reg:CC FLAGS_REG))])]
9855   "TARGET_HIMODE_MATH"
9856   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9857
9858 (define_insn "*neghi2_1"
9859   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9860         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9861    (clobber (reg:CC FLAGS_REG))]
9862   "ix86_unary_operator_ok (NEG, HImode, operands)"
9863   "neg{w}\t%0"
9864   [(set_attr "type" "negnot")
9865    (set_attr "mode" "HI")])
9866
9867 (define_insn "*neghi2_cmpz"
9868   [(set (reg:CCZ FLAGS_REG)
9869         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9870                      (const_int 0)))
9871    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9872         (neg:HI (match_dup 1)))]
9873   "ix86_unary_operator_ok (NEG, HImode, operands)"
9874   "neg{w}\t%0"
9875   [(set_attr "type" "negnot")
9876    (set_attr "mode" "HI")])
9877
9878 (define_expand "negqi2"
9879   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9880                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9881               (clobber (reg:CC FLAGS_REG))])]
9882   "TARGET_QIMODE_MATH"
9883   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9884
9885 (define_insn "*negqi2_1"
9886   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9887         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9888    (clobber (reg:CC FLAGS_REG))]
9889   "ix86_unary_operator_ok (NEG, QImode, operands)"
9890   "neg{b}\t%0"
9891   [(set_attr "type" "negnot")
9892    (set_attr "mode" "QI")])
9893
9894 (define_insn "*negqi2_cmpz"
9895   [(set (reg:CCZ FLAGS_REG)
9896         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9897                      (const_int 0)))
9898    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9899         (neg:QI (match_dup 1)))]
9900   "ix86_unary_operator_ok (NEG, QImode, operands)"
9901   "neg{b}\t%0"
9902   [(set_attr "type" "negnot")
9903    (set_attr "mode" "QI")])
9904
9905 ;; Changing of sign for FP values is doable using integer unit too.
9906
9907 (define_expand "negsf2"
9908   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9909         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9910   "TARGET_80387 || TARGET_SSE_MATH"
9911   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9912
9913 (define_expand "abssf2"
9914   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9915         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9916   "TARGET_80387 || TARGET_SSE_MATH"
9917   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9918
9919 (define_insn "*absnegsf2_mixed"
9920   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9921         (match_operator:SF 3 "absneg_operator"
9922           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9923    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9924    (clobber (reg:CC FLAGS_REG))]
9925   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9926    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9927   "#")
9928
9929 (define_insn "*absnegsf2_sse"
9930   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9931         (match_operator:SF 3 "absneg_operator"
9932           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9933    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9934    (clobber (reg:CC FLAGS_REG))]
9935   "TARGET_SSE_MATH
9936    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9937   "#")
9938
9939 (define_insn "*absnegsf2_i387"
9940   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9941         (match_operator:SF 3 "absneg_operator"
9942           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9943    (use (match_operand 2 "" ""))
9944    (clobber (reg:CC FLAGS_REG))]
9945   "TARGET_80387 && !TARGET_SSE_MATH
9946    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9947   "#")
9948
9949 (define_expand "copysignsf3"
9950   [(match_operand:SF 0 "register_operand" "")
9951    (match_operand:SF 1 "nonmemory_operand" "")
9952    (match_operand:SF 2 "register_operand" "")]
9953   "TARGET_SSE_MATH"
9954 {
9955   ix86_expand_copysign (operands);
9956   DONE;
9957 })
9958
9959 (define_insn_and_split "copysignsf3_const"
9960   [(set (match_operand:SF 0 "register_operand"          "=x")
9961         (unspec:SF
9962           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9963            (match_operand:SF 2 "register_operand"       "0")
9964            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9965           UNSPEC_COPYSIGN))]
9966   "TARGET_SSE_MATH"
9967   "#"
9968   "&& reload_completed"
9969   [(const_int 0)]
9970 {
9971   ix86_split_copysign_const (operands);
9972   DONE;
9973 })
9974
9975 (define_insn "copysignsf3_var"
9976   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9977         (unspec:SF
9978           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9979            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9980            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9981            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9982           UNSPEC_COPYSIGN))
9983    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9984   "TARGET_SSE_MATH"
9985   "#")
9986
9987 (define_split
9988   [(set (match_operand:SF 0 "register_operand" "")
9989         (unspec:SF
9990           [(match_operand:SF 2 "register_operand" "")
9991            (match_operand:SF 3 "register_operand" "")
9992            (match_operand:V4SF 4 "" "")
9993            (match_operand:V4SF 5 "" "")]
9994           UNSPEC_COPYSIGN))
9995    (clobber (match_scratch:V4SF 1 ""))]
9996   "TARGET_SSE_MATH && reload_completed"
9997   [(const_int 0)]
9998 {
9999   ix86_split_copysign_var (operands);
10000   DONE;
10001 })
10002
10003 (define_expand "negdf2"
10004   [(set (match_operand:DF 0 "nonimmediate_operand" "")
10005         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
10006   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
10007   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
10008
10009 (define_expand "absdf2"
10010   [(set (match_operand:DF 0 "nonimmediate_operand" "")
10011         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
10012   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
10013   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
10014
10015 (define_insn "*absnegdf2_mixed"
10016   [(set (match_operand:DF 0 "nonimmediate_operand"    "=x,x,f,rm")
10017         (match_operator:DF 3 "absneg_operator"
10018           [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0,0")]))
10019    (use (match_operand:V2DF 2 "nonimmediate_operand"  "xm,0,X,X"))
10020    (clobber (reg:CC FLAGS_REG))]
10021   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
10022    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10023   "#")
10024
10025 (define_insn "*absnegdf2_sse"
10026   [(set (match_operand:DF 0 "nonimmediate_operand"    "=x,x,rm")
10027         (match_operator:DF 3 "absneg_operator"
10028           [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0 ")]))
10029    (use (match_operand:V2DF 2 "nonimmediate_operand"  "xm,0,X "))
10030    (clobber (reg:CC FLAGS_REG))]
10031   "TARGET_SSE2 && TARGET_SSE_MATH
10032    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10033   "#")
10034
10035 (define_insn "*absnegdf2_i387"
10036   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
10037         (match_operator:DF 3 "absneg_operator"
10038           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
10039    (use (match_operand 2 "" ""))
10040    (clobber (reg:CC FLAGS_REG))]
10041   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
10042    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10043   "#")
10044
10045 (define_expand "copysigndf3"
10046   [(match_operand:DF 0 "register_operand" "")
10047    (match_operand:DF 1 "nonmemory_operand" "")
10048    (match_operand:DF 2 "register_operand" "")]
10049   "TARGET_SSE2 && TARGET_SSE_MATH"
10050 {
10051   ix86_expand_copysign (operands);
10052   DONE;
10053 })
10054
10055 (define_insn_and_split "copysigndf3_const"
10056   [(set (match_operand:DF 0 "register_operand"          "=x")
10057         (unspec:DF
10058           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
10059            (match_operand:DF 2 "register_operand"       "0")
10060            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
10061           UNSPEC_COPYSIGN))]
10062   "TARGET_SSE2 && TARGET_SSE_MATH"
10063   "#"
10064   "&& reload_completed"
10065   [(const_int 0)]
10066 {
10067   ix86_split_copysign_const (operands);
10068   DONE;
10069 })
10070
10071 (define_insn "copysigndf3_var"
10072   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
10073         (unspec:DF
10074           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
10075            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
10076            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
10077            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
10078           UNSPEC_COPYSIGN))
10079    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
10080   "TARGET_SSE2 && TARGET_SSE_MATH"
10081   "#")
10082
10083 (define_split
10084   [(set (match_operand:DF 0 "register_operand" "")
10085         (unspec:DF
10086           [(match_operand:DF 2 "register_operand" "")
10087            (match_operand:DF 3 "register_operand" "")
10088            (match_operand:V2DF 4 "" "")
10089            (match_operand:V2DF 5 "" "")]
10090           UNSPEC_COPYSIGN))
10091    (clobber (match_scratch:V2DF 1 ""))]
10092   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
10093   [(const_int 0)]
10094 {
10095   ix86_split_copysign_var (operands);
10096   DONE;
10097 })
10098
10099 (define_expand "negxf2"
10100   [(set (match_operand:XF 0 "nonimmediate_operand" "")
10101         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10102   "TARGET_80387"
10103   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
10104
10105 (define_expand "absxf2"
10106   [(set (match_operand:XF 0 "nonimmediate_operand" "")
10107         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10108   "TARGET_80387"
10109   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
10110
10111 (define_insn "*absnegxf2_i387"
10112   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
10113         (match_operator:XF 3 "absneg_operator"
10114           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
10115    (use (match_operand 2 "" ""))
10116    (clobber (reg:CC FLAGS_REG))]
10117   "TARGET_80387
10118    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
10119   "#")
10120
10121 ;; Splitters for fp abs and neg.
10122
10123 (define_split
10124   [(set (match_operand 0 "fp_register_operand" "")
10125         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10126    (use (match_operand 2 "" ""))
10127    (clobber (reg:CC FLAGS_REG))]
10128   "reload_completed"
10129   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10130
10131 (define_split
10132   [(set (match_operand 0 "register_operand" "")
10133         (match_operator 3 "absneg_operator"
10134           [(match_operand 1 "register_operand" "")]))
10135    (use (match_operand 2 "nonimmediate_operand" ""))
10136    (clobber (reg:CC FLAGS_REG))]
10137   "reload_completed && SSE_REG_P (operands[0])"
10138   [(set (match_dup 0) (match_dup 3))]
10139 {
10140   enum machine_mode mode = GET_MODE (operands[0]);
10141   enum machine_mode vmode = GET_MODE (operands[2]);
10142   rtx tmp;
10143
10144   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10145   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10146   if (operands_match_p (operands[0], operands[2]))
10147     {
10148       tmp = operands[1];
10149       operands[1] = operands[2];
10150       operands[2] = tmp;
10151     }
10152   if (GET_CODE (operands[3]) == ABS)
10153     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10154   else
10155     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10156   operands[3] = tmp;
10157 })
10158
10159 (define_split
10160   [(set (match_operand:SF 0 "register_operand" "")
10161         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10162    (use (match_operand:V4SF 2 "" ""))
10163    (clobber (reg:CC FLAGS_REG))]
10164   "reload_completed"
10165   [(parallel [(set (match_dup 0) (match_dup 1))
10166               (clobber (reg:CC FLAGS_REG))])]
10167 {
10168   rtx tmp;
10169   operands[0] = gen_lowpart (SImode, operands[0]);
10170   if (GET_CODE (operands[1]) == ABS)
10171     {
10172       tmp = gen_int_mode (0x7fffffff, SImode);
10173       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10174     }
10175   else
10176     {
10177       tmp = gen_int_mode (0x80000000, SImode);
10178       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10179     }
10180   operands[1] = tmp;
10181 })
10182
10183 (define_split
10184   [(set (match_operand:DF 0 "register_operand" "")
10185         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10186    (use (match_operand 2 "" ""))
10187    (clobber (reg:CC FLAGS_REG))]
10188   "reload_completed"
10189   [(parallel [(set (match_dup 0) (match_dup 1))
10190               (clobber (reg:CC FLAGS_REG))])]
10191 {
10192   rtx tmp;
10193   if (TARGET_64BIT)
10194     {
10195       tmp = gen_lowpart (DImode, operands[0]);
10196       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10197       operands[0] = tmp;
10198
10199       if (GET_CODE (operands[1]) == ABS)
10200         tmp = const0_rtx;
10201       else
10202         tmp = gen_rtx_NOT (DImode, tmp);
10203     }
10204   else
10205     {
10206       operands[0] = gen_highpart (SImode, operands[0]);
10207       if (GET_CODE (operands[1]) == ABS)
10208         {
10209           tmp = gen_int_mode (0x7fffffff, SImode);
10210           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10211         }
10212       else
10213         {
10214           tmp = gen_int_mode (0x80000000, SImode);
10215           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10216         }
10217     }
10218   operands[1] = tmp;
10219 })
10220
10221 (define_split
10222   [(set (match_operand:XF 0 "register_operand" "")
10223         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10224    (use (match_operand 2 "" ""))
10225    (clobber (reg:CC FLAGS_REG))]
10226   "reload_completed"
10227   [(parallel [(set (match_dup 0) (match_dup 1))
10228               (clobber (reg:CC FLAGS_REG))])]
10229 {
10230   rtx tmp;
10231   operands[0] = gen_rtx_REG (SImode,
10232                              true_regnum (operands[0])
10233                              + (TARGET_64BIT ? 1 : 2));
10234   if (GET_CODE (operands[1]) == ABS)
10235     {
10236       tmp = GEN_INT (0x7fff);
10237       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10238     }
10239   else
10240     {
10241       tmp = GEN_INT (0x8000);
10242       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10243     }
10244   operands[1] = tmp;
10245 })
10246
10247 (define_split
10248   [(set (match_operand 0 "memory_operand" "")
10249         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10250    (use (match_operand 2 "" ""))
10251    (clobber (reg:CC FLAGS_REG))]
10252   "reload_completed"
10253   [(parallel [(set (match_dup 0) (match_dup 1))
10254               (clobber (reg:CC FLAGS_REG))])]
10255 {
10256   enum machine_mode mode = GET_MODE (operands[0]);
10257   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
10258   rtx tmp;
10259
10260   operands[0] = adjust_address (operands[0], QImode, size - 1);
10261   if (GET_CODE (operands[1]) == ABS)
10262     {
10263       tmp = gen_int_mode (0x7f, QImode);
10264       tmp = gen_rtx_AND (QImode, operands[0], tmp);
10265     }
10266   else
10267     {
10268       tmp = gen_int_mode (0x80, QImode);
10269       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
10270     }
10271   operands[1] = tmp;
10272 })
10273
10274 ;; Conditionalize these after reload. If they match before reload, we
10275 ;; lose the clobber and ability to use integer instructions.
10276
10277 (define_insn "*negsf2_1"
10278   [(set (match_operand:SF 0 "register_operand" "=f")
10279         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10280   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10281   "fchs"
10282   [(set_attr "type" "fsgn")
10283    (set_attr "mode" "SF")])
10284
10285 (define_insn "*negdf2_1"
10286   [(set (match_operand:DF 0 "register_operand" "=f")
10287         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10288   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10289   "fchs"
10290   [(set_attr "type" "fsgn")
10291    (set_attr "mode" "DF")])
10292
10293 (define_insn "*negxf2_1"
10294   [(set (match_operand:XF 0 "register_operand" "=f")
10295         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10296   "TARGET_80387"
10297   "fchs"
10298   [(set_attr "type" "fsgn")
10299    (set_attr "mode" "XF")])
10300
10301 (define_insn "*abssf2_1"
10302   [(set (match_operand:SF 0 "register_operand" "=f")
10303         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10304   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10305   "fabs"
10306   [(set_attr "type" "fsgn")
10307    (set_attr "mode" "SF")])
10308
10309 (define_insn "*absdf2_1"
10310   [(set (match_operand:DF 0 "register_operand" "=f")
10311         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10312   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10313   "fabs"
10314   [(set_attr "type" "fsgn")
10315    (set_attr "mode" "DF")])
10316
10317 (define_insn "*absxf2_1"
10318   [(set (match_operand:XF 0 "register_operand" "=f")
10319         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10320   "TARGET_80387"
10321   "fabs"
10322   [(set_attr "type" "fsgn")
10323    (set_attr "mode" "DF")])
10324
10325 (define_insn "*negextendsfdf2"
10326   [(set (match_operand:DF 0 "register_operand" "=f")
10327         (neg:DF (float_extend:DF
10328                   (match_operand:SF 1 "register_operand" "0"))))]
10329   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10330   "fchs"
10331   [(set_attr "type" "fsgn")
10332    (set_attr "mode" "DF")])
10333
10334 (define_insn "*negextenddfxf2"
10335   [(set (match_operand:XF 0 "register_operand" "=f")
10336         (neg:XF (float_extend:XF
10337                   (match_operand:DF 1 "register_operand" "0"))))]
10338   "TARGET_80387"
10339   "fchs"
10340   [(set_attr "type" "fsgn")
10341    (set_attr "mode" "XF")])
10342
10343 (define_insn "*negextendsfxf2"
10344   [(set (match_operand:XF 0 "register_operand" "=f")
10345         (neg:XF (float_extend:XF
10346                   (match_operand:SF 1 "register_operand" "0"))))]
10347   "TARGET_80387"
10348   "fchs"
10349   [(set_attr "type" "fsgn")
10350    (set_attr "mode" "XF")])
10351
10352 (define_insn "*absextendsfdf2"
10353   [(set (match_operand:DF 0 "register_operand" "=f")
10354         (abs:DF (float_extend:DF
10355                   (match_operand:SF 1 "register_operand" "0"))))]
10356   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10357   "fabs"
10358   [(set_attr "type" "fsgn")
10359    (set_attr "mode" "DF")])
10360
10361 (define_insn "*absextenddfxf2"
10362   [(set (match_operand:XF 0 "register_operand" "=f")
10363         (abs:XF (float_extend:XF
10364           (match_operand:DF 1 "register_operand" "0"))))]
10365   "TARGET_80387"
10366   "fabs"
10367   [(set_attr "type" "fsgn")
10368    (set_attr "mode" "XF")])
10369
10370 (define_insn "*absextendsfxf2"
10371   [(set (match_operand:XF 0 "register_operand" "=f")
10372         (abs:XF (float_extend:XF
10373           (match_operand:SF 1 "register_operand" "0"))))]
10374   "TARGET_80387"
10375   "fabs"
10376   [(set_attr "type" "fsgn")
10377    (set_attr "mode" "XF")])
10378 \f
10379 ;; One complement instructions
10380
10381 (define_expand "one_cmpldi2"
10382   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10383         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10384   "TARGET_64BIT"
10385   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10386
10387 (define_insn "*one_cmpldi2_1_rex64"
10388   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10389         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10390   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10391   "not{q}\t%0"
10392   [(set_attr "type" "negnot")
10393    (set_attr "mode" "DI")])
10394
10395 (define_insn "*one_cmpldi2_2_rex64"
10396   [(set (reg FLAGS_REG)
10397         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10398                  (const_int 0)))
10399    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10400         (not:DI (match_dup 1)))]
10401   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10402    && ix86_unary_operator_ok (NOT, DImode, operands)"
10403   "#"
10404   [(set_attr "type" "alu1")
10405    (set_attr "mode" "DI")])
10406
10407 (define_split
10408   [(set (match_operand 0 "flags_reg_operand" "")
10409         (match_operator 2 "compare_operator"
10410           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10411            (const_int 0)]))
10412    (set (match_operand:DI 1 "nonimmediate_operand" "")
10413         (not:DI (match_dup 3)))]
10414   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10415   [(parallel [(set (match_dup 0)
10416                    (match_op_dup 2
10417                      [(xor:DI (match_dup 3) (const_int -1))
10418                       (const_int 0)]))
10419               (set (match_dup 1)
10420                    (xor:DI (match_dup 3) (const_int -1)))])]
10421   "")
10422
10423 (define_expand "one_cmplsi2"
10424   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10425         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10426   ""
10427   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10428
10429 (define_insn "*one_cmplsi2_1"
10430   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10431         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10432   "ix86_unary_operator_ok (NOT, SImode, operands)"
10433   "not{l}\t%0"
10434   [(set_attr "type" "negnot")
10435    (set_attr "mode" "SI")])
10436
10437 ;; ??? Currently never generated - xor is used instead.
10438 (define_insn "*one_cmplsi2_1_zext"
10439   [(set (match_operand:DI 0 "register_operand" "=r")
10440         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10441   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10442   "not{l}\t%k0"
10443   [(set_attr "type" "negnot")
10444    (set_attr "mode" "SI")])
10445
10446 (define_insn "*one_cmplsi2_2"
10447   [(set (reg FLAGS_REG)
10448         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10449                  (const_int 0)))
10450    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10451         (not:SI (match_dup 1)))]
10452   "ix86_match_ccmode (insn, CCNOmode)
10453    && ix86_unary_operator_ok (NOT, SImode, operands)"
10454   "#"
10455   [(set_attr "type" "alu1")
10456    (set_attr "mode" "SI")])
10457
10458 (define_split
10459   [(set (match_operand 0 "flags_reg_operand" "")
10460         (match_operator 2 "compare_operator"
10461           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10462            (const_int 0)]))
10463    (set (match_operand:SI 1 "nonimmediate_operand" "")
10464         (not:SI (match_dup 3)))]
10465   "ix86_match_ccmode (insn, CCNOmode)"
10466   [(parallel [(set (match_dup 0)
10467                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10468                                     (const_int 0)]))
10469               (set (match_dup 1)
10470                    (xor:SI (match_dup 3) (const_int -1)))])]
10471   "")
10472
10473 ;; ??? Currently never generated - xor is used instead.
10474 (define_insn "*one_cmplsi2_2_zext"
10475   [(set (reg FLAGS_REG)
10476         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10477                  (const_int 0)))
10478    (set (match_operand:DI 0 "register_operand" "=r")
10479         (zero_extend:DI (not:SI (match_dup 1))))]
10480   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10481    && ix86_unary_operator_ok (NOT, SImode, operands)"
10482   "#"
10483   [(set_attr "type" "alu1")
10484    (set_attr "mode" "SI")])
10485
10486 (define_split
10487   [(set (match_operand 0 "flags_reg_operand" "")
10488         (match_operator 2 "compare_operator"
10489           [(not:SI (match_operand:SI 3 "register_operand" ""))
10490            (const_int 0)]))
10491    (set (match_operand:DI 1 "register_operand" "")
10492         (zero_extend:DI (not:SI (match_dup 3))))]
10493   "ix86_match_ccmode (insn, CCNOmode)"
10494   [(parallel [(set (match_dup 0)
10495                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10496                                     (const_int 0)]))
10497               (set (match_dup 1)
10498                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10499   "")
10500
10501 (define_expand "one_cmplhi2"
10502   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10503         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10504   "TARGET_HIMODE_MATH"
10505   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10506
10507 (define_insn "*one_cmplhi2_1"
10508   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10509         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10510   "ix86_unary_operator_ok (NOT, HImode, operands)"
10511   "not{w}\t%0"
10512   [(set_attr "type" "negnot")
10513    (set_attr "mode" "HI")])
10514
10515 (define_insn "*one_cmplhi2_2"
10516   [(set (reg FLAGS_REG)
10517         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10518                  (const_int 0)))
10519    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10520         (not:HI (match_dup 1)))]
10521   "ix86_match_ccmode (insn, CCNOmode)
10522    && ix86_unary_operator_ok (NEG, HImode, operands)"
10523   "#"
10524   [(set_attr "type" "alu1")
10525    (set_attr "mode" "HI")])
10526
10527 (define_split
10528   [(set (match_operand 0 "flags_reg_operand" "")
10529         (match_operator 2 "compare_operator"
10530           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10531            (const_int 0)]))
10532    (set (match_operand:HI 1 "nonimmediate_operand" "")
10533         (not:HI (match_dup 3)))]
10534   "ix86_match_ccmode (insn, CCNOmode)"
10535   [(parallel [(set (match_dup 0)
10536                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10537                                     (const_int 0)]))
10538               (set (match_dup 1)
10539                    (xor:HI (match_dup 3) (const_int -1)))])]
10540   "")
10541
10542 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10543 (define_expand "one_cmplqi2"
10544   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10545         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10546   "TARGET_QIMODE_MATH"
10547   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10548
10549 (define_insn "*one_cmplqi2_1"
10550   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10551         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10552   "ix86_unary_operator_ok (NOT, QImode, operands)"
10553   "@
10554    not{b}\t%0
10555    not{l}\t%k0"
10556   [(set_attr "type" "negnot")
10557    (set_attr "mode" "QI,SI")])
10558
10559 (define_insn "*one_cmplqi2_2"
10560   [(set (reg FLAGS_REG)
10561         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10562                  (const_int 0)))
10563    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10564         (not:QI (match_dup 1)))]
10565   "ix86_match_ccmode (insn, CCNOmode)
10566    && ix86_unary_operator_ok (NOT, QImode, operands)"
10567   "#"
10568   [(set_attr "type" "alu1")
10569    (set_attr "mode" "QI")])
10570
10571 (define_split
10572   [(set (match_operand 0 "flags_reg_operand" "")
10573         (match_operator 2 "compare_operator"
10574           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10575            (const_int 0)]))
10576    (set (match_operand:QI 1 "nonimmediate_operand" "")
10577         (not:QI (match_dup 3)))]
10578   "ix86_match_ccmode (insn, CCNOmode)"
10579   [(parallel [(set (match_dup 0)
10580                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10581                                     (const_int 0)]))
10582               (set (match_dup 1)
10583                    (xor:QI (match_dup 3) (const_int -1)))])]
10584   "")
10585 \f
10586 ;; Arithmetic shift instructions
10587
10588 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10589 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10590 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10591 ;; from the assembler input.
10592 ;;
10593 ;; This instruction shifts the target reg/mem as usual, but instead of
10594 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10595 ;; is a left shift double, bits are taken from the high order bits of
10596 ;; reg, else if the insn is a shift right double, bits are taken from the
10597 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10598 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10599 ;;
10600 ;; Since sh[lr]d does not change the `reg' operand, that is done
10601 ;; separately, making all shifts emit pairs of shift double and normal
10602 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10603 ;; support a 63 bit shift, each shift where the count is in a reg expands
10604 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10605 ;;
10606 ;; If the shift count is a constant, we need never emit more than one
10607 ;; shift pair, instead using moves and sign extension for counts greater
10608 ;; than 31.
10609
10610 (define_expand "ashlti3"
10611   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10612                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10613                               (match_operand:QI 2 "nonmemory_operand" "")))
10614               (clobber (reg:CC FLAGS_REG))])]
10615   "TARGET_64BIT"
10616 {
10617   if (! immediate_operand (operands[2], QImode))
10618     {
10619       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10620       DONE;
10621     }
10622   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10623   DONE;
10624 })
10625
10626 (define_insn "ashlti3_1"
10627   [(set (match_operand:TI 0 "register_operand" "=r")
10628         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10629                    (match_operand:QI 2 "register_operand" "c")))
10630    (clobber (match_scratch:DI 3 "=&r"))
10631    (clobber (reg:CC FLAGS_REG))]
10632   "TARGET_64BIT"
10633   "#"
10634   [(set_attr "type" "multi")])
10635
10636 (define_insn "*ashlti3_2"
10637   [(set (match_operand:TI 0 "register_operand" "=r")
10638         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10639                    (match_operand:QI 2 "immediate_operand" "O")))
10640    (clobber (reg:CC FLAGS_REG))]
10641   "TARGET_64BIT"
10642   "#"
10643   [(set_attr "type" "multi")])
10644
10645 (define_split
10646   [(set (match_operand:TI 0 "register_operand" "")
10647         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10648                    (match_operand:QI 2 "register_operand" "")))
10649    (clobber (match_scratch:DI 3 ""))
10650    (clobber (reg:CC FLAGS_REG))]
10651   "TARGET_64BIT && reload_completed"
10652   [(const_int 0)]
10653   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10654
10655 (define_split
10656   [(set (match_operand:TI 0 "register_operand" "")
10657         (ashift:TI (match_operand:TI 1 "register_operand" "")
10658                    (match_operand:QI 2 "immediate_operand" "")))
10659    (clobber (reg:CC FLAGS_REG))]
10660   "TARGET_64BIT && reload_completed"
10661   [(const_int 0)]
10662   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10663
10664 (define_insn "x86_64_shld"
10665   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10666         (ior:DI (ashift:DI (match_dup 0)
10667                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10668                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10669                   (minus:QI (const_int 64) (match_dup 2)))))
10670    (clobber (reg:CC FLAGS_REG))]
10671   "TARGET_64BIT"
10672   "@
10673    shld{q}\t{%2, %1, %0|%0, %1, %2}
10674    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10675   [(set_attr "type" "ishift")
10676    (set_attr "prefix_0f" "1")
10677    (set_attr "mode" "DI")
10678    (set_attr "athlon_decode" "vector")
10679    (set_attr "amdfam10_decode" "vector")])   
10680
10681 (define_expand "x86_64_shift_adj"
10682   [(set (reg:CCZ FLAGS_REG)
10683         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10684                              (const_int 64))
10685                      (const_int 0)))
10686    (set (match_operand:DI 0 "register_operand" "")
10687         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10688                          (match_operand:DI 1 "register_operand" "")
10689                          (match_dup 0)))
10690    (set (match_dup 1)
10691         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10692                          (match_operand:DI 3 "register_operand" "r")
10693                          (match_dup 1)))]
10694   "TARGET_64BIT"
10695   "")
10696
10697 (define_expand "ashldi3"
10698   [(set (match_operand:DI 0 "shiftdi_operand" "")
10699         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10700                    (match_operand:QI 2 "nonmemory_operand" "")))]
10701   ""
10702   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10703
10704 (define_insn "*ashldi3_1_rex64"
10705   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10706         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10707                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10708    (clobber (reg:CC FLAGS_REG))]
10709   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10710 {
10711   switch (get_attr_type (insn))
10712     {
10713     case TYPE_ALU:
10714       gcc_assert (operands[2] == const1_rtx);
10715       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10716       return "add{q}\t%0, %0";
10717
10718     case TYPE_LEA:
10719       gcc_assert (CONST_INT_P (operands[2]));
10720       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10721       operands[1] = gen_rtx_MULT (DImode, operands[1],
10722                                   GEN_INT (1 << INTVAL (operands[2])));
10723       return "lea{q}\t{%a1, %0|%0, %a1}";
10724
10725     default:
10726       if (REG_P (operands[2]))
10727         return "sal{q}\t{%b2, %0|%0, %b2}";
10728       else if (operands[2] == const1_rtx
10729                && (TARGET_SHIFT1 || optimize_size))
10730         return "sal{q}\t%0";
10731       else
10732         return "sal{q}\t{%2, %0|%0, %2}";
10733     }
10734 }
10735   [(set (attr "type")
10736      (cond [(eq_attr "alternative" "1")
10737               (const_string "lea")
10738             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10739                           (const_int 0))
10740                       (match_operand 0 "register_operand" ""))
10741                  (match_operand 2 "const1_operand" ""))
10742               (const_string "alu")
10743            ]
10744            (const_string "ishift")))
10745    (set_attr "mode" "DI")])
10746
10747 ;; Convert lea to the lea pattern to avoid flags dependency.
10748 (define_split
10749   [(set (match_operand:DI 0 "register_operand" "")
10750         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10751                    (match_operand:QI 2 "immediate_operand" "")))
10752    (clobber (reg:CC FLAGS_REG))]
10753   "TARGET_64BIT && reload_completed
10754    && true_regnum (operands[0]) != true_regnum (operands[1])"
10755   [(set (match_dup 0)
10756         (mult:DI (match_dup 1)
10757                  (match_dup 2)))]
10758   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10759
10760 ;; This pattern can't accept a variable shift count, since shifts by
10761 ;; zero don't affect the flags.  We assume that shifts by constant
10762 ;; zero are optimized away.
10763 (define_insn "*ashldi3_cmp_rex64"
10764   [(set (reg FLAGS_REG)
10765         (compare
10766           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10767                      (match_operand:QI 2 "immediate_operand" "e"))
10768           (const_int 0)))
10769    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10770         (ashift:DI (match_dup 1) (match_dup 2)))]
10771   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10772    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10773    && (optimize_size
10774        || !TARGET_PARTIAL_FLAG_REG_STALL
10775        || (operands[2] == const1_rtx
10776            && (TARGET_SHIFT1
10777                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10778 {
10779   switch (get_attr_type (insn))
10780     {
10781     case TYPE_ALU:
10782       gcc_assert (operands[2] == const1_rtx);
10783       return "add{q}\t%0, %0";
10784
10785     default:
10786       if (REG_P (operands[2]))
10787         return "sal{q}\t{%b2, %0|%0, %b2}";
10788       else if (operands[2] == const1_rtx
10789                && (TARGET_SHIFT1 || optimize_size))
10790         return "sal{q}\t%0";
10791       else
10792         return "sal{q}\t{%2, %0|%0, %2}";
10793     }
10794 }
10795   [(set (attr "type")
10796      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10797                           (const_int 0))
10798                       (match_operand 0 "register_operand" ""))
10799                  (match_operand 2 "const1_operand" ""))
10800               (const_string "alu")
10801            ]
10802            (const_string "ishift")))
10803    (set_attr "mode" "DI")])
10804
10805 (define_insn "*ashldi3_cconly_rex64"
10806   [(set (reg FLAGS_REG)
10807         (compare
10808           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10809                      (match_operand:QI 2 "immediate_operand" "e"))
10810           (const_int 0)))
10811    (clobber (match_scratch:DI 0 "=r"))]
10812   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10813    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10814    && (optimize_size
10815        || !TARGET_PARTIAL_FLAG_REG_STALL
10816        || (operands[2] == const1_rtx
10817            && (TARGET_SHIFT1
10818                || TARGET_DOUBLE_WITH_ADD)))"
10819 {
10820   switch (get_attr_type (insn))
10821     {
10822     case TYPE_ALU:
10823       gcc_assert (operands[2] == const1_rtx);
10824       return "add{q}\t%0, %0";
10825
10826     default:
10827       if (REG_P (operands[2]))
10828         return "sal{q}\t{%b2, %0|%0, %b2}";
10829       else if (operands[2] == const1_rtx
10830                && (TARGET_SHIFT1 || optimize_size))
10831         return "sal{q}\t%0";
10832       else
10833         return "sal{q}\t{%2, %0|%0, %2}";
10834     }
10835 }
10836   [(set (attr "type")
10837      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10838                           (const_int 0))
10839                       (match_operand 0 "register_operand" ""))
10840                  (match_operand 2 "const1_operand" ""))
10841               (const_string "alu")
10842            ]
10843            (const_string "ishift")))
10844    (set_attr "mode" "DI")])
10845
10846 (define_insn "*ashldi3_1"
10847   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10848         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10849                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10850    (clobber (reg:CC FLAGS_REG))]
10851   "!TARGET_64BIT"
10852   "#"
10853   [(set_attr "type" "multi")])
10854
10855 ;; By default we don't ask for a scratch register, because when DImode
10856 ;; values are manipulated, registers are already at a premium.  But if
10857 ;; we have one handy, we won't turn it away.
10858 (define_peephole2
10859   [(match_scratch:SI 3 "r")
10860    (parallel [(set (match_operand:DI 0 "register_operand" "")
10861                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10862                               (match_operand:QI 2 "nonmemory_operand" "")))
10863               (clobber (reg:CC FLAGS_REG))])
10864    (match_dup 3)]
10865   "!TARGET_64BIT && TARGET_CMOVE"
10866   [(const_int 0)]
10867   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10868
10869 (define_split
10870   [(set (match_operand:DI 0 "register_operand" "")
10871         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10872                    (match_operand:QI 2 "nonmemory_operand" "")))
10873    (clobber (reg:CC FLAGS_REG))]
10874   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10875                      ? flow2_completed : reload_completed)"
10876   [(const_int 0)]
10877   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10878
10879 (define_insn "x86_shld_1"
10880   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10881         (ior:SI (ashift:SI (match_dup 0)
10882                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10883                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10884                   (minus:QI (const_int 32) (match_dup 2)))))
10885    (clobber (reg:CC FLAGS_REG))]
10886   ""
10887   "@
10888    shld{l}\t{%2, %1, %0|%0, %1, %2}
10889    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10890   [(set_attr "type" "ishift")
10891    (set_attr "prefix_0f" "1")
10892    (set_attr "mode" "SI")
10893    (set_attr "pent_pair" "np")
10894    (set_attr "athlon_decode" "vector")
10895    (set_attr "amdfam10_decode" "vector")])   
10896
10897 (define_expand "x86_shift_adj_1"
10898   [(set (reg:CCZ FLAGS_REG)
10899         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10900                              (const_int 32))
10901                      (const_int 0)))
10902    (set (match_operand:SI 0 "register_operand" "")
10903         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10904                          (match_operand:SI 1 "register_operand" "")
10905                          (match_dup 0)))
10906    (set (match_dup 1)
10907         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10908                          (match_operand:SI 3 "register_operand" "r")
10909                          (match_dup 1)))]
10910   "TARGET_CMOVE"
10911   "")
10912
10913 (define_expand "x86_shift_adj_2"
10914   [(use (match_operand:SI 0 "register_operand" ""))
10915    (use (match_operand:SI 1 "register_operand" ""))
10916    (use (match_operand:QI 2 "register_operand" ""))]
10917   ""
10918 {
10919   rtx label = gen_label_rtx ();
10920   rtx tmp;
10921
10922   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10923
10924   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10925   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10926   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10927                               gen_rtx_LABEL_REF (VOIDmode, label),
10928                               pc_rtx);
10929   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10930   JUMP_LABEL (tmp) = label;
10931
10932   emit_move_insn (operands[0], operands[1]);
10933   ix86_expand_clear (operands[1]);
10934
10935   emit_label (label);
10936   LABEL_NUSES (label) = 1;
10937
10938   DONE;
10939 })
10940
10941 (define_expand "ashlsi3"
10942   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10943         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10944                    (match_operand:QI 2 "nonmemory_operand" "")))
10945    (clobber (reg:CC FLAGS_REG))]
10946   ""
10947   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10948
10949 (define_insn "*ashlsi3_1"
10950   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10951         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10952                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10953    (clobber (reg:CC FLAGS_REG))]
10954   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10955 {
10956   switch (get_attr_type (insn))
10957     {
10958     case TYPE_ALU:
10959       gcc_assert (operands[2] == const1_rtx);
10960       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10961       return "add{l}\t%0, %0";
10962
10963     case TYPE_LEA:
10964       return "#";
10965
10966     default:
10967       if (REG_P (operands[2]))
10968         return "sal{l}\t{%b2, %0|%0, %b2}";
10969       else if (operands[2] == const1_rtx
10970                && (TARGET_SHIFT1 || optimize_size))
10971         return "sal{l}\t%0";
10972       else
10973         return "sal{l}\t{%2, %0|%0, %2}";
10974     }
10975 }
10976   [(set (attr "type")
10977      (cond [(eq_attr "alternative" "1")
10978               (const_string "lea")
10979             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10980                           (const_int 0))
10981                       (match_operand 0 "register_operand" ""))
10982                  (match_operand 2 "const1_operand" ""))
10983               (const_string "alu")
10984            ]
10985            (const_string "ishift")))
10986    (set_attr "mode" "SI")])
10987
10988 ;; Convert lea to the lea pattern to avoid flags dependency.
10989 (define_split
10990   [(set (match_operand 0 "register_operand" "")
10991         (ashift (match_operand 1 "index_register_operand" "")
10992                 (match_operand:QI 2 "const_int_operand" "")))
10993    (clobber (reg:CC FLAGS_REG))]
10994   "reload_completed
10995    && true_regnum (operands[0]) != true_regnum (operands[1])
10996    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10997   [(const_int 0)]
10998 {
10999   rtx pat;
11000   enum machine_mode mode = GET_MODE (operands[0]);
11001
11002   if (GET_MODE_SIZE (mode) < 4)
11003     operands[0] = gen_lowpart (SImode, operands[0]);
11004   if (mode != Pmode)
11005     operands[1] = gen_lowpart (Pmode, operands[1]);
11006   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11007
11008   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11009   if (Pmode != SImode)
11010     pat = gen_rtx_SUBREG (SImode, pat, 0);
11011   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11012   DONE;
11013 })
11014
11015 ;; Rare case of shifting RSP is handled by generating move and shift
11016 (define_split
11017   [(set (match_operand 0 "register_operand" "")
11018         (ashift (match_operand 1 "register_operand" "")
11019                 (match_operand:QI 2 "const_int_operand" "")))
11020    (clobber (reg:CC FLAGS_REG))]
11021   "reload_completed
11022    && true_regnum (operands[0]) != true_regnum (operands[1])"
11023   [(const_int 0)]
11024 {
11025   rtx pat, clob;
11026   emit_move_insn (operands[0], operands[1]);
11027   pat = gen_rtx_SET (VOIDmode, operands[0],
11028                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11029                                      operands[0], operands[2]));
11030   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11031   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11032   DONE;
11033 })
11034
11035 (define_insn "*ashlsi3_1_zext"
11036   [(set (match_operand:DI 0 "register_operand" "=r,r")
11037         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11038                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11039    (clobber (reg:CC FLAGS_REG))]
11040   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11041 {
11042   switch (get_attr_type (insn))
11043     {
11044     case TYPE_ALU:
11045       gcc_assert (operands[2] == const1_rtx);
11046       return "add{l}\t%k0, %k0";
11047
11048     case TYPE_LEA:
11049       return "#";
11050
11051     default:
11052       if (REG_P (operands[2]))
11053         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11054       else if (operands[2] == const1_rtx
11055                && (TARGET_SHIFT1 || optimize_size))
11056         return "sal{l}\t%k0";
11057       else
11058         return "sal{l}\t{%2, %k0|%k0, %2}";
11059     }
11060 }
11061   [(set (attr "type")
11062      (cond [(eq_attr "alternative" "1")
11063               (const_string "lea")
11064             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11065                      (const_int 0))
11066                  (match_operand 2 "const1_operand" ""))
11067               (const_string "alu")
11068            ]
11069            (const_string "ishift")))
11070    (set_attr "mode" "SI")])
11071
11072 ;; Convert lea to the lea pattern to avoid flags dependency.
11073 (define_split
11074   [(set (match_operand:DI 0 "register_operand" "")
11075         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11076                                 (match_operand:QI 2 "const_int_operand" ""))))
11077    (clobber (reg:CC FLAGS_REG))]
11078   "TARGET_64BIT && reload_completed
11079    && true_regnum (operands[0]) != true_regnum (operands[1])"
11080   [(set (match_dup 0) (zero_extend:DI
11081                         (subreg:SI (mult:SI (match_dup 1)
11082                                             (match_dup 2)) 0)))]
11083 {
11084   operands[1] = gen_lowpart (Pmode, operands[1]);
11085   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11086 })
11087
11088 ;; This pattern can't accept a variable shift count, since shifts by
11089 ;; zero don't affect the flags.  We assume that shifts by constant
11090 ;; zero are optimized away.
11091 (define_insn "*ashlsi3_cmp"
11092   [(set (reg FLAGS_REG)
11093         (compare
11094           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11095                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11096           (const_int 0)))
11097    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11098         (ashift:SI (match_dup 1) (match_dup 2)))]
11099   "ix86_match_ccmode (insn, CCGOCmode)
11100    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11101    && (optimize_size
11102        || !TARGET_PARTIAL_FLAG_REG_STALL
11103        || (operands[2] == const1_rtx
11104            && (TARGET_SHIFT1
11105                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11106 {
11107   switch (get_attr_type (insn))
11108     {
11109     case TYPE_ALU:
11110       gcc_assert (operands[2] == const1_rtx);
11111       return "add{l}\t%0, %0";
11112
11113     default:
11114       if (REG_P (operands[2]))
11115         return "sal{l}\t{%b2, %0|%0, %b2}";
11116       else if (operands[2] == const1_rtx
11117                && (TARGET_SHIFT1 || optimize_size))
11118         return "sal{l}\t%0";
11119       else
11120         return "sal{l}\t{%2, %0|%0, %2}";
11121     }
11122 }
11123   [(set (attr "type")
11124      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11125                           (const_int 0))
11126                       (match_operand 0 "register_operand" ""))
11127                  (match_operand 2 "const1_operand" ""))
11128               (const_string "alu")
11129            ]
11130            (const_string "ishift")))
11131    (set_attr "mode" "SI")])
11132
11133 (define_insn "*ashlsi3_cconly"
11134   [(set (reg FLAGS_REG)
11135         (compare
11136           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11137                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11138           (const_int 0)))
11139    (clobber (match_scratch:SI 0 "=r"))]
11140   "ix86_match_ccmode (insn, CCGOCmode)
11141    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11142    && (optimize_size
11143        || !TARGET_PARTIAL_FLAG_REG_STALL
11144        || (operands[2] == const1_rtx
11145            && (TARGET_SHIFT1
11146                || TARGET_DOUBLE_WITH_ADD)))"
11147 {
11148   switch (get_attr_type (insn))
11149     {
11150     case TYPE_ALU:
11151       gcc_assert (operands[2] == const1_rtx);
11152       return "add{l}\t%0, %0";
11153
11154     default:
11155       if (REG_P (operands[2]))
11156         return "sal{l}\t{%b2, %0|%0, %b2}";
11157       else if (operands[2] == const1_rtx
11158                && (TARGET_SHIFT1 || optimize_size))
11159         return "sal{l}\t%0";
11160       else
11161         return "sal{l}\t{%2, %0|%0, %2}";
11162     }
11163 }
11164   [(set (attr "type")
11165      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11166                           (const_int 0))
11167                       (match_operand 0 "register_operand" ""))
11168                  (match_operand 2 "const1_operand" ""))
11169               (const_string "alu")
11170            ]
11171            (const_string "ishift")))
11172    (set_attr "mode" "SI")])
11173
11174 (define_insn "*ashlsi3_cmp_zext"
11175   [(set (reg FLAGS_REG)
11176         (compare
11177           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11178                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11179           (const_int 0)))
11180    (set (match_operand:DI 0 "register_operand" "=r")
11181         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11182   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11183    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11184    && (optimize_size
11185        || !TARGET_PARTIAL_FLAG_REG_STALL
11186        || (operands[2] == const1_rtx
11187            && (TARGET_SHIFT1
11188                || TARGET_DOUBLE_WITH_ADD)))"
11189 {
11190   switch (get_attr_type (insn))
11191     {
11192     case TYPE_ALU:
11193       gcc_assert (operands[2] == const1_rtx);
11194       return "add{l}\t%k0, %k0";
11195
11196     default:
11197       if (REG_P (operands[2]))
11198         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11199       else if (operands[2] == const1_rtx
11200                && (TARGET_SHIFT1 || optimize_size))
11201         return "sal{l}\t%k0";
11202       else
11203         return "sal{l}\t{%2, %k0|%k0, %2}";
11204     }
11205 }
11206   [(set (attr "type")
11207      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11208                      (const_int 0))
11209                  (match_operand 2 "const1_operand" ""))
11210               (const_string "alu")
11211            ]
11212            (const_string "ishift")))
11213    (set_attr "mode" "SI")])
11214
11215 (define_expand "ashlhi3"
11216   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11217         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11218                    (match_operand:QI 2 "nonmemory_operand" "")))
11219    (clobber (reg:CC FLAGS_REG))]
11220   "TARGET_HIMODE_MATH"
11221   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11222
11223 (define_insn "*ashlhi3_1_lea"
11224   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11225         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11226                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11227    (clobber (reg:CC FLAGS_REG))]
11228   "!TARGET_PARTIAL_REG_STALL
11229    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11230 {
11231   switch (get_attr_type (insn))
11232     {
11233     case TYPE_LEA:
11234       return "#";
11235     case TYPE_ALU:
11236       gcc_assert (operands[2] == const1_rtx);
11237       return "add{w}\t%0, %0";
11238
11239     default:
11240       if (REG_P (operands[2]))
11241         return "sal{w}\t{%b2, %0|%0, %b2}";
11242       else if (operands[2] == const1_rtx
11243                && (TARGET_SHIFT1 || optimize_size))
11244         return "sal{w}\t%0";
11245       else
11246         return "sal{w}\t{%2, %0|%0, %2}";
11247     }
11248 }
11249   [(set (attr "type")
11250      (cond [(eq_attr "alternative" "1")
11251               (const_string "lea")
11252             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11253                           (const_int 0))
11254                       (match_operand 0 "register_operand" ""))
11255                  (match_operand 2 "const1_operand" ""))
11256               (const_string "alu")
11257            ]
11258            (const_string "ishift")))
11259    (set_attr "mode" "HI,SI")])
11260
11261 (define_insn "*ashlhi3_1"
11262   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11263         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11264                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11265    (clobber (reg:CC FLAGS_REG))]
11266   "TARGET_PARTIAL_REG_STALL
11267    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11268 {
11269   switch (get_attr_type (insn))
11270     {
11271     case TYPE_ALU:
11272       gcc_assert (operands[2] == const1_rtx);
11273       return "add{w}\t%0, %0";
11274
11275     default:
11276       if (REG_P (operands[2]))
11277         return "sal{w}\t{%b2, %0|%0, %b2}";
11278       else if (operands[2] == const1_rtx
11279                && (TARGET_SHIFT1 || optimize_size))
11280         return "sal{w}\t%0";
11281       else
11282         return "sal{w}\t{%2, %0|%0, %2}";
11283     }
11284 }
11285   [(set (attr "type")
11286      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11287                           (const_int 0))
11288                       (match_operand 0 "register_operand" ""))
11289                  (match_operand 2 "const1_operand" ""))
11290               (const_string "alu")
11291            ]
11292            (const_string "ishift")))
11293    (set_attr "mode" "HI")])
11294
11295 ;; This pattern can't accept a variable shift count, since shifts by
11296 ;; zero don't affect the flags.  We assume that shifts by constant
11297 ;; zero are optimized away.
11298 (define_insn "*ashlhi3_cmp"
11299   [(set (reg FLAGS_REG)
11300         (compare
11301           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11302                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11303           (const_int 0)))
11304    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11305         (ashift:HI (match_dup 1) (match_dup 2)))]
11306   "ix86_match_ccmode (insn, CCGOCmode)
11307    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11308    && (optimize_size
11309        || !TARGET_PARTIAL_FLAG_REG_STALL
11310        || (operands[2] == const1_rtx
11311            && (TARGET_SHIFT1
11312                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11313 {
11314   switch (get_attr_type (insn))
11315     {
11316     case TYPE_ALU:
11317       gcc_assert (operands[2] == const1_rtx);
11318       return "add{w}\t%0, %0";
11319
11320     default:
11321       if (REG_P (operands[2]))
11322         return "sal{w}\t{%b2, %0|%0, %b2}";
11323       else if (operands[2] == const1_rtx
11324                && (TARGET_SHIFT1 || optimize_size))
11325         return "sal{w}\t%0";
11326       else
11327         return "sal{w}\t{%2, %0|%0, %2}";
11328     }
11329 }
11330   [(set (attr "type")
11331      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11332                           (const_int 0))
11333                       (match_operand 0 "register_operand" ""))
11334                  (match_operand 2 "const1_operand" ""))
11335               (const_string "alu")
11336            ]
11337            (const_string "ishift")))
11338    (set_attr "mode" "HI")])
11339
11340 (define_insn "*ashlhi3_cconly"
11341   [(set (reg FLAGS_REG)
11342         (compare
11343           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11344                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11345           (const_int 0)))
11346    (clobber (match_scratch:HI 0 "=r"))]
11347   "ix86_match_ccmode (insn, CCGOCmode)
11348    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11349    && (optimize_size
11350        || !TARGET_PARTIAL_FLAG_REG_STALL
11351        || (operands[2] == const1_rtx
11352            && (TARGET_SHIFT1
11353                || TARGET_DOUBLE_WITH_ADD)))"
11354 {
11355   switch (get_attr_type (insn))
11356     {
11357     case TYPE_ALU:
11358       gcc_assert (operands[2] == const1_rtx);
11359       return "add{w}\t%0, %0";
11360
11361     default:
11362       if (REG_P (operands[2]))
11363         return "sal{w}\t{%b2, %0|%0, %b2}";
11364       else if (operands[2] == const1_rtx
11365                && (TARGET_SHIFT1 || optimize_size))
11366         return "sal{w}\t%0";
11367       else
11368         return "sal{w}\t{%2, %0|%0, %2}";
11369     }
11370 }
11371   [(set (attr "type")
11372      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11373                           (const_int 0))
11374                       (match_operand 0 "register_operand" ""))
11375                  (match_operand 2 "const1_operand" ""))
11376               (const_string "alu")
11377            ]
11378            (const_string "ishift")))
11379    (set_attr "mode" "HI")])
11380
11381 (define_expand "ashlqi3"
11382   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11383         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11384                    (match_operand:QI 2 "nonmemory_operand" "")))
11385    (clobber (reg:CC FLAGS_REG))]
11386   "TARGET_QIMODE_MATH"
11387   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11388
11389 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11390
11391 (define_insn "*ashlqi3_1_lea"
11392   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11393         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11394                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11395    (clobber (reg:CC FLAGS_REG))]
11396   "!TARGET_PARTIAL_REG_STALL
11397    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11398 {
11399   switch (get_attr_type (insn))
11400     {
11401     case TYPE_LEA:
11402       return "#";
11403     case TYPE_ALU:
11404       gcc_assert (operands[2] == const1_rtx);
11405       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11406         return "add{l}\t%k0, %k0";
11407       else
11408         return "add{b}\t%0, %0";
11409
11410     default:
11411       if (REG_P (operands[2]))
11412         {
11413           if (get_attr_mode (insn) == MODE_SI)
11414             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11415           else
11416             return "sal{b}\t{%b2, %0|%0, %b2}";
11417         }
11418       else if (operands[2] == const1_rtx
11419                && (TARGET_SHIFT1 || optimize_size))
11420         {
11421           if (get_attr_mode (insn) == MODE_SI)
11422             return "sal{l}\t%0";
11423           else
11424             return "sal{b}\t%0";
11425         }
11426       else
11427         {
11428           if (get_attr_mode (insn) == MODE_SI)
11429             return "sal{l}\t{%2, %k0|%k0, %2}";
11430           else
11431             return "sal{b}\t{%2, %0|%0, %2}";
11432         }
11433     }
11434 }
11435   [(set (attr "type")
11436      (cond [(eq_attr "alternative" "2")
11437               (const_string "lea")
11438             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11439                           (const_int 0))
11440                       (match_operand 0 "register_operand" ""))
11441                  (match_operand 2 "const1_operand" ""))
11442               (const_string "alu")
11443            ]
11444            (const_string "ishift")))
11445    (set_attr "mode" "QI,SI,SI")])
11446
11447 (define_insn "*ashlqi3_1"
11448   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11449         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11450                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11451    (clobber (reg:CC FLAGS_REG))]
11452   "TARGET_PARTIAL_REG_STALL
11453    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11454 {
11455   switch (get_attr_type (insn))
11456     {
11457     case TYPE_ALU:
11458       gcc_assert (operands[2] == const1_rtx);
11459       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11460         return "add{l}\t%k0, %k0";
11461       else
11462         return "add{b}\t%0, %0";
11463
11464     default:
11465       if (REG_P (operands[2]))
11466         {
11467           if (get_attr_mode (insn) == MODE_SI)
11468             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11469           else
11470             return "sal{b}\t{%b2, %0|%0, %b2}";
11471         }
11472       else if (operands[2] == const1_rtx
11473                && (TARGET_SHIFT1 || optimize_size))
11474         {
11475           if (get_attr_mode (insn) == MODE_SI)
11476             return "sal{l}\t%0";
11477           else
11478             return "sal{b}\t%0";
11479         }
11480       else
11481         {
11482           if (get_attr_mode (insn) == MODE_SI)
11483             return "sal{l}\t{%2, %k0|%k0, %2}";
11484           else
11485             return "sal{b}\t{%2, %0|%0, %2}";
11486         }
11487     }
11488 }
11489   [(set (attr "type")
11490      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11491                           (const_int 0))
11492                       (match_operand 0 "register_operand" ""))
11493                  (match_operand 2 "const1_operand" ""))
11494               (const_string "alu")
11495            ]
11496            (const_string "ishift")))
11497    (set_attr "mode" "QI,SI")])
11498
11499 ;; This pattern can't accept a variable shift count, since shifts by
11500 ;; zero don't affect the flags.  We assume that shifts by constant
11501 ;; zero are optimized away.
11502 (define_insn "*ashlqi3_cmp"
11503   [(set (reg FLAGS_REG)
11504         (compare
11505           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11506                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11507           (const_int 0)))
11508    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11509         (ashift:QI (match_dup 1) (match_dup 2)))]
11510   "ix86_match_ccmode (insn, CCGOCmode)
11511    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11512    && (optimize_size
11513        || !TARGET_PARTIAL_FLAG_REG_STALL
11514        || (operands[2] == const1_rtx
11515            && (TARGET_SHIFT1
11516                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11517 {
11518   switch (get_attr_type (insn))
11519     {
11520     case TYPE_ALU:
11521       gcc_assert (operands[2] == const1_rtx);
11522       return "add{b}\t%0, %0";
11523
11524     default:
11525       if (REG_P (operands[2]))
11526         return "sal{b}\t{%b2, %0|%0, %b2}";
11527       else if (operands[2] == const1_rtx
11528                && (TARGET_SHIFT1 || optimize_size))
11529         return "sal{b}\t%0";
11530       else
11531         return "sal{b}\t{%2, %0|%0, %2}";
11532     }
11533 }
11534   [(set (attr "type")
11535      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11536                           (const_int 0))
11537                       (match_operand 0 "register_operand" ""))
11538                  (match_operand 2 "const1_operand" ""))
11539               (const_string "alu")
11540            ]
11541            (const_string "ishift")))
11542    (set_attr "mode" "QI")])
11543
11544 (define_insn "*ashlqi3_cconly"
11545   [(set (reg FLAGS_REG)
11546         (compare
11547           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11548                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11549           (const_int 0)))
11550    (clobber (match_scratch:QI 0 "=q"))]
11551   "ix86_match_ccmode (insn, CCGOCmode)
11552    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11553    && (optimize_size
11554        || !TARGET_PARTIAL_FLAG_REG_STALL
11555        || (operands[2] == const1_rtx
11556            && (TARGET_SHIFT1
11557                || TARGET_DOUBLE_WITH_ADD)))"
11558 {
11559   switch (get_attr_type (insn))
11560     {
11561     case TYPE_ALU:
11562       gcc_assert (operands[2] == const1_rtx);
11563       return "add{b}\t%0, %0";
11564
11565     default:
11566       if (REG_P (operands[2]))
11567         return "sal{b}\t{%b2, %0|%0, %b2}";
11568       else if (operands[2] == const1_rtx
11569                && (TARGET_SHIFT1 || optimize_size))
11570         return "sal{b}\t%0";
11571       else
11572         return "sal{b}\t{%2, %0|%0, %2}";
11573     }
11574 }
11575   [(set (attr "type")
11576      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11577                           (const_int 0))
11578                       (match_operand 0 "register_operand" ""))
11579                  (match_operand 2 "const1_operand" ""))
11580               (const_string "alu")
11581            ]
11582            (const_string "ishift")))
11583    (set_attr "mode" "QI")])
11584
11585 ;; See comment above `ashldi3' about how this works.
11586
11587 (define_expand "ashrti3"
11588   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11589                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11590                                 (match_operand:QI 2 "nonmemory_operand" "")))
11591               (clobber (reg:CC FLAGS_REG))])]
11592   "TARGET_64BIT"
11593 {
11594   if (! immediate_operand (operands[2], QImode))
11595     {
11596       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11597       DONE;
11598     }
11599   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11600   DONE;
11601 })
11602
11603 (define_insn "ashrti3_1"
11604   [(set (match_operand:TI 0 "register_operand" "=r")
11605         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11606                      (match_operand:QI 2 "register_operand" "c")))
11607    (clobber (match_scratch:DI 3 "=&r"))
11608    (clobber (reg:CC FLAGS_REG))]
11609   "TARGET_64BIT"
11610   "#"
11611   [(set_attr "type" "multi")])
11612
11613 (define_insn "*ashrti3_2"
11614   [(set (match_operand:TI 0 "register_operand" "=r")
11615         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11616                      (match_operand:QI 2 "immediate_operand" "O")))
11617    (clobber (reg:CC FLAGS_REG))]
11618   "TARGET_64BIT"
11619   "#"
11620   [(set_attr "type" "multi")])
11621
11622 (define_split
11623   [(set (match_operand:TI 0 "register_operand" "")
11624         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11625                      (match_operand:QI 2 "register_operand" "")))
11626    (clobber (match_scratch:DI 3 ""))
11627    (clobber (reg:CC FLAGS_REG))]
11628   "TARGET_64BIT && reload_completed"
11629   [(const_int 0)]
11630   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11631
11632 (define_split
11633   [(set (match_operand:TI 0 "register_operand" "")
11634         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11635                      (match_operand:QI 2 "immediate_operand" "")))
11636    (clobber (reg:CC FLAGS_REG))]
11637   "TARGET_64BIT && reload_completed"
11638   [(const_int 0)]
11639   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11640
11641 (define_insn "x86_64_shrd"
11642   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11643         (ior:DI (ashiftrt:DI (match_dup 0)
11644                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11645                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11646                   (minus:QI (const_int 64) (match_dup 2)))))
11647    (clobber (reg:CC FLAGS_REG))]
11648   "TARGET_64BIT"
11649   "@
11650    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11651    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11652   [(set_attr "type" "ishift")
11653    (set_attr "prefix_0f" "1")
11654    (set_attr "mode" "DI")
11655    (set_attr "athlon_decode" "vector")
11656    (set_attr "amdfam10_decode" "vector")])   
11657
11658 (define_expand "ashrdi3"
11659   [(set (match_operand:DI 0 "shiftdi_operand" "")
11660         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11661                      (match_operand:QI 2 "nonmemory_operand" "")))]
11662   ""
11663   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11664
11665 (define_insn "*ashrdi3_63_rex64"
11666   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11667         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11668                      (match_operand:DI 2 "const_int_operand" "i,i")))
11669    (clobber (reg:CC FLAGS_REG))]
11670   "TARGET_64BIT && INTVAL (operands[2]) == 63
11671    && (TARGET_USE_CLTD || optimize_size)
11672    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11673   "@
11674    {cqto|cqo}
11675    sar{q}\t{%2, %0|%0, %2}"
11676   [(set_attr "type" "imovx,ishift")
11677    (set_attr "prefix_0f" "0,*")
11678    (set_attr "length_immediate" "0,*")
11679    (set_attr "modrm" "0,1")
11680    (set_attr "mode" "DI")])
11681
11682 (define_insn "*ashrdi3_1_one_bit_rex64"
11683   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11684         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11685                      (match_operand:QI 2 "const1_operand" "")))
11686    (clobber (reg:CC FLAGS_REG))]
11687   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11688    && (TARGET_SHIFT1 || optimize_size)"
11689   "sar{q}\t%0"
11690   [(set_attr "type" "ishift")
11691    (set (attr "length")
11692      (if_then_else (match_operand:DI 0 "register_operand" "")
11693         (const_string "2")
11694         (const_string "*")))])
11695
11696 (define_insn "*ashrdi3_1_rex64"
11697   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11698         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11699                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11700    (clobber (reg:CC FLAGS_REG))]
11701   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11702   "@
11703    sar{q}\t{%2, %0|%0, %2}
11704    sar{q}\t{%b2, %0|%0, %b2}"
11705   [(set_attr "type" "ishift")
11706    (set_attr "mode" "DI")])
11707
11708 ;; This pattern can't accept a variable shift count, since shifts by
11709 ;; zero don't affect the flags.  We assume that shifts by constant
11710 ;; zero are optimized away.
11711 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11712   [(set (reg FLAGS_REG)
11713         (compare
11714           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11715                        (match_operand:QI 2 "const1_operand" ""))
11716           (const_int 0)))
11717    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11718         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11719   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11720    && (TARGET_SHIFT1 || optimize_size)
11721    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11722   "sar{q}\t%0"
11723   [(set_attr "type" "ishift")
11724    (set (attr "length")
11725      (if_then_else (match_operand:DI 0 "register_operand" "")
11726         (const_string "2")
11727         (const_string "*")))])
11728
11729 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11730   [(set (reg FLAGS_REG)
11731         (compare
11732           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11733                        (match_operand:QI 2 "const1_operand" ""))
11734           (const_int 0)))
11735    (clobber (match_scratch:DI 0 "=r"))]
11736   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11737    && (TARGET_SHIFT1 || optimize_size)
11738    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11739   "sar{q}\t%0"
11740   [(set_attr "type" "ishift")
11741    (set_attr "length" "2")])
11742
11743 ;; This pattern can't accept a variable shift count, since shifts by
11744 ;; zero don't affect the flags.  We assume that shifts by constant
11745 ;; zero are optimized away.
11746 (define_insn "*ashrdi3_cmp_rex64"
11747   [(set (reg FLAGS_REG)
11748         (compare
11749           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11750                        (match_operand:QI 2 "const_int_operand" "n"))
11751           (const_int 0)))
11752    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11753         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11754   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11755    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11756    && (optimize_size
11757        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11758   "sar{q}\t{%2, %0|%0, %2}"
11759   [(set_attr "type" "ishift")
11760    (set_attr "mode" "DI")])
11761
11762 (define_insn "*ashrdi3_cconly_rex64"
11763   [(set (reg FLAGS_REG)
11764         (compare
11765           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11766                        (match_operand:QI 2 "const_int_operand" "n"))
11767           (const_int 0)))
11768    (clobber (match_scratch:DI 0 "=r"))]
11769   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11770    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11771    && (optimize_size
11772        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11773   "sar{q}\t{%2, %0|%0, %2}"
11774   [(set_attr "type" "ishift")
11775    (set_attr "mode" "DI")])
11776
11777 (define_insn "*ashrdi3_1"
11778   [(set (match_operand:DI 0 "register_operand" "=r")
11779         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11780                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11781    (clobber (reg:CC FLAGS_REG))]
11782   "!TARGET_64BIT"
11783   "#"
11784   [(set_attr "type" "multi")])
11785
11786 ;; By default we don't ask for a scratch register, because when DImode
11787 ;; values are manipulated, registers are already at a premium.  But if
11788 ;; we have one handy, we won't turn it away.
11789 (define_peephole2
11790   [(match_scratch:SI 3 "r")
11791    (parallel [(set (match_operand:DI 0 "register_operand" "")
11792                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11793                                 (match_operand:QI 2 "nonmemory_operand" "")))
11794               (clobber (reg:CC FLAGS_REG))])
11795    (match_dup 3)]
11796   "!TARGET_64BIT && TARGET_CMOVE"
11797   [(const_int 0)]
11798   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11799
11800 (define_split
11801   [(set (match_operand:DI 0 "register_operand" "")
11802         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11803                      (match_operand:QI 2 "nonmemory_operand" "")))
11804    (clobber (reg:CC FLAGS_REG))]
11805   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11806                      ? flow2_completed : reload_completed)"
11807   [(const_int 0)]
11808   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11809
11810 (define_insn "x86_shrd_1"
11811   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11812         (ior:SI (ashiftrt:SI (match_dup 0)
11813                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11814                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11815                   (minus:QI (const_int 32) (match_dup 2)))))
11816    (clobber (reg:CC FLAGS_REG))]
11817   ""
11818   "@
11819    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11820    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11821   [(set_attr "type" "ishift")
11822    (set_attr "prefix_0f" "1")
11823    (set_attr "pent_pair" "np")
11824    (set_attr "mode" "SI")])
11825
11826 (define_expand "x86_shift_adj_3"
11827   [(use (match_operand:SI 0 "register_operand" ""))
11828    (use (match_operand:SI 1 "register_operand" ""))
11829    (use (match_operand:QI 2 "register_operand" ""))]
11830   ""
11831 {
11832   rtx label = gen_label_rtx ();
11833   rtx tmp;
11834
11835   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11836
11837   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11838   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11839   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11840                               gen_rtx_LABEL_REF (VOIDmode, label),
11841                               pc_rtx);
11842   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11843   JUMP_LABEL (tmp) = label;
11844
11845   emit_move_insn (operands[0], operands[1]);
11846   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11847
11848   emit_label (label);
11849   LABEL_NUSES (label) = 1;
11850
11851   DONE;
11852 })
11853
11854 (define_insn "ashrsi3_31"
11855   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11856         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11857                      (match_operand:SI 2 "const_int_operand" "i,i")))
11858    (clobber (reg:CC FLAGS_REG))]
11859   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11860    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11861   "@
11862    {cltd|cdq}
11863    sar{l}\t{%2, %0|%0, %2}"
11864   [(set_attr "type" "imovx,ishift")
11865    (set_attr "prefix_0f" "0,*")
11866    (set_attr "length_immediate" "0,*")
11867    (set_attr "modrm" "0,1")
11868    (set_attr "mode" "SI")])
11869
11870 (define_insn "*ashrsi3_31_zext"
11871   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11872         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11873                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11874    (clobber (reg:CC FLAGS_REG))]
11875   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11876    && INTVAL (operands[2]) == 31
11877    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11878   "@
11879    {cltd|cdq}
11880    sar{l}\t{%2, %k0|%k0, %2}"
11881   [(set_attr "type" "imovx,ishift")
11882    (set_attr "prefix_0f" "0,*")
11883    (set_attr "length_immediate" "0,*")
11884    (set_attr "modrm" "0,1")
11885    (set_attr "mode" "SI")])
11886
11887 (define_expand "ashrsi3"
11888   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11889         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11890                      (match_operand:QI 2 "nonmemory_operand" "")))
11891    (clobber (reg:CC FLAGS_REG))]
11892   ""
11893   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11894
11895 (define_insn "*ashrsi3_1_one_bit"
11896   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11897         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11898                      (match_operand:QI 2 "const1_operand" "")))
11899    (clobber (reg:CC FLAGS_REG))]
11900   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11901    && (TARGET_SHIFT1 || optimize_size)"
11902   "sar{l}\t%0"
11903   [(set_attr "type" "ishift")
11904    (set (attr "length")
11905      (if_then_else (match_operand:SI 0 "register_operand" "")
11906         (const_string "2")
11907         (const_string "*")))])
11908
11909 (define_insn "*ashrsi3_1_one_bit_zext"
11910   [(set (match_operand:DI 0 "register_operand" "=r")
11911         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11912                                      (match_operand:QI 2 "const1_operand" ""))))
11913    (clobber (reg:CC FLAGS_REG))]
11914   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11915    && (TARGET_SHIFT1 || optimize_size)"
11916   "sar{l}\t%k0"
11917   [(set_attr "type" "ishift")
11918    (set_attr "length" "2")])
11919
11920 (define_insn "*ashrsi3_1"
11921   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11922         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11923                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11924    (clobber (reg:CC FLAGS_REG))]
11925   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11926   "@
11927    sar{l}\t{%2, %0|%0, %2}
11928    sar{l}\t{%b2, %0|%0, %b2}"
11929   [(set_attr "type" "ishift")
11930    (set_attr "mode" "SI")])
11931
11932 (define_insn "*ashrsi3_1_zext"
11933   [(set (match_operand:DI 0 "register_operand" "=r,r")
11934         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11935                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11936    (clobber (reg:CC FLAGS_REG))]
11937   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11938   "@
11939    sar{l}\t{%2, %k0|%k0, %2}
11940    sar{l}\t{%b2, %k0|%k0, %b2}"
11941   [(set_attr "type" "ishift")
11942    (set_attr "mode" "SI")])
11943
11944 ;; This pattern can't accept a variable shift count, since shifts by
11945 ;; zero don't affect the flags.  We assume that shifts by constant
11946 ;; zero are optimized away.
11947 (define_insn "*ashrsi3_one_bit_cmp"
11948   [(set (reg FLAGS_REG)
11949         (compare
11950           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11951                        (match_operand:QI 2 "const1_operand" ""))
11952           (const_int 0)))
11953    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11954         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11955   "ix86_match_ccmode (insn, CCGOCmode)
11956    && (TARGET_SHIFT1 || optimize_size)
11957    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11958   "sar{l}\t%0"
11959   [(set_attr "type" "ishift")
11960    (set (attr "length")
11961      (if_then_else (match_operand:SI 0 "register_operand" "")
11962         (const_string "2")
11963         (const_string "*")))])
11964
11965 (define_insn "*ashrsi3_one_bit_cconly"
11966   [(set (reg FLAGS_REG)
11967         (compare
11968           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11969                        (match_operand:QI 2 "const1_operand" ""))
11970           (const_int 0)))
11971    (clobber (match_scratch:SI 0 "=r"))]
11972   "ix86_match_ccmode (insn, CCGOCmode)
11973    && (TARGET_SHIFT1 || optimize_size)
11974    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11975   "sar{l}\t%0"
11976   [(set_attr "type" "ishift")
11977    (set_attr "length" "2")])
11978
11979 (define_insn "*ashrsi3_one_bit_cmp_zext"
11980   [(set (reg FLAGS_REG)
11981         (compare
11982           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11983                        (match_operand:QI 2 "const1_operand" ""))
11984           (const_int 0)))
11985    (set (match_operand:DI 0 "register_operand" "=r")
11986         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11987   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11988    && (TARGET_SHIFT1 || optimize_size)
11989    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11990   "sar{l}\t%k0"
11991   [(set_attr "type" "ishift")
11992    (set_attr "length" "2")])
11993
11994 ;; This pattern can't accept a variable shift count, since shifts by
11995 ;; zero don't affect the flags.  We assume that shifts by constant
11996 ;; zero are optimized away.
11997 (define_insn "*ashrsi3_cmp"
11998   [(set (reg FLAGS_REG)
11999         (compare
12000           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12001                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12002           (const_int 0)))
12003    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12004         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12005   "ix86_match_ccmode (insn, CCGOCmode)
12006    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
12007    && (optimize_size
12008        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12009   "sar{l}\t{%2, %0|%0, %2}"
12010   [(set_attr "type" "ishift")
12011    (set_attr "mode" "SI")])
12012
12013 (define_insn "*ashrsi3_cconly"
12014   [(set (reg FLAGS_REG)
12015         (compare
12016           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12017                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12018           (const_int 0)))
12019    (clobber (match_scratch:SI 0 "=r"))]
12020   "ix86_match_ccmode (insn, CCGOCmode)
12021    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
12022    && (optimize_size
12023        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12024   "sar{l}\t{%2, %0|%0, %2}"
12025   [(set_attr "type" "ishift")
12026    (set_attr "mode" "SI")])
12027
12028 (define_insn "*ashrsi3_cmp_zext"
12029   [(set (reg FLAGS_REG)
12030         (compare
12031           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12032                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12033           (const_int 0)))
12034    (set (match_operand:DI 0 "register_operand" "=r")
12035         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12036   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12037    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
12038    && (optimize_size
12039        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12040   "sar{l}\t{%2, %k0|%k0, %2}"
12041   [(set_attr "type" "ishift")
12042    (set_attr "mode" "SI")])
12043
12044 (define_expand "ashrhi3"
12045   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12046         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12047                      (match_operand:QI 2 "nonmemory_operand" "")))
12048    (clobber (reg:CC FLAGS_REG))]
12049   "TARGET_HIMODE_MATH"
12050   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12051
12052 (define_insn "*ashrhi3_1_one_bit"
12053   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12054         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12055                      (match_operand:QI 2 "const1_operand" "")))
12056    (clobber (reg:CC FLAGS_REG))]
12057   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12058    && (TARGET_SHIFT1 || optimize_size)"
12059   "sar{w}\t%0"
12060   [(set_attr "type" "ishift")
12061    (set (attr "length")
12062      (if_then_else (match_operand 0 "register_operand" "")
12063         (const_string "2")
12064         (const_string "*")))])
12065
12066 (define_insn "*ashrhi3_1"
12067   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12068         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12069                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12070    (clobber (reg:CC FLAGS_REG))]
12071   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12072   "@
12073    sar{w}\t{%2, %0|%0, %2}
12074    sar{w}\t{%b2, %0|%0, %b2}"
12075   [(set_attr "type" "ishift")
12076    (set_attr "mode" "HI")])
12077
12078 ;; This pattern can't accept a variable shift count, since shifts by
12079 ;; zero don't affect the flags.  We assume that shifts by constant
12080 ;; zero are optimized away.
12081 (define_insn "*ashrhi3_one_bit_cmp"
12082   [(set (reg FLAGS_REG)
12083         (compare
12084           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12085                        (match_operand:QI 2 "const1_operand" ""))
12086           (const_int 0)))
12087    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12088         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12089   "ix86_match_ccmode (insn, CCGOCmode)
12090    && (TARGET_SHIFT1 || optimize_size)
12091    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12092   "sar{w}\t%0"
12093   [(set_attr "type" "ishift")
12094    (set (attr "length")
12095      (if_then_else (match_operand 0 "register_operand" "")
12096         (const_string "2")
12097         (const_string "*")))])
12098
12099 (define_insn "*ashrhi3_one_bit_cconly"
12100   [(set (reg FLAGS_REG)
12101         (compare
12102           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12103                        (match_operand:QI 2 "const1_operand" ""))
12104           (const_int 0)))
12105    (clobber (match_scratch:HI 0 "=r"))]
12106   "ix86_match_ccmode (insn, CCGOCmode)
12107    && (TARGET_SHIFT1 || optimize_size)
12108    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12109   "sar{w}\t%0"
12110   [(set_attr "type" "ishift")
12111    (set_attr "length" "2")])
12112
12113 ;; This pattern can't accept a variable shift count, since shifts by
12114 ;; zero don't affect the flags.  We assume that shifts by constant
12115 ;; zero are optimized away.
12116 (define_insn "*ashrhi3_cmp"
12117   [(set (reg FLAGS_REG)
12118         (compare
12119           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12120                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12121           (const_int 0)))
12122    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12123         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12124   "ix86_match_ccmode (insn, CCGOCmode)
12125    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12126    && (optimize_size
12127        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12128   "sar{w}\t{%2, %0|%0, %2}"
12129   [(set_attr "type" "ishift")
12130    (set_attr "mode" "HI")])
12131
12132 (define_insn "*ashrhi3_cconly"
12133   [(set (reg FLAGS_REG)
12134         (compare
12135           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12136                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12137           (const_int 0)))
12138    (clobber (match_scratch:HI 0 "=r"))]
12139   "ix86_match_ccmode (insn, CCGOCmode)
12140    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12141    && (optimize_size
12142        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12143   "sar{w}\t{%2, %0|%0, %2}"
12144   [(set_attr "type" "ishift")
12145    (set_attr "mode" "HI")])
12146
12147 (define_expand "ashrqi3"
12148   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12149         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12150                      (match_operand:QI 2 "nonmemory_operand" "")))
12151    (clobber (reg:CC FLAGS_REG))]
12152   "TARGET_QIMODE_MATH"
12153   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12154
12155 (define_insn "*ashrqi3_1_one_bit"
12156   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12157         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12158                      (match_operand:QI 2 "const1_operand" "")))
12159    (clobber (reg:CC FLAGS_REG))]
12160   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12161    && (TARGET_SHIFT1 || optimize_size)"
12162   "sar{b}\t%0"
12163   [(set_attr "type" "ishift")
12164    (set (attr "length")
12165      (if_then_else (match_operand 0 "register_operand" "")
12166         (const_string "2")
12167         (const_string "*")))])
12168
12169 (define_insn "*ashrqi3_1_one_bit_slp"
12170   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12171         (ashiftrt:QI (match_dup 0)
12172                      (match_operand:QI 1 "const1_operand" "")))
12173    (clobber (reg:CC FLAGS_REG))]
12174   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12175    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
12176    && (TARGET_SHIFT1 || optimize_size)"
12177   "sar{b}\t%0"
12178   [(set_attr "type" "ishift1")
12179    (set (attr "length")
12180      (if_then_else (match_operand 0 "register_operand" "")
12181         (const_string "2")
12182         (const_string "*")))])
12183
12184 (define_insn "*ashrqi3_1"
12185   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12186         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12187                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12188    (clobber (reg:CC FLAGS_REG))]
12189   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12190   "@
12191    sar{b}\t{%2, %0|%0, %2}
12192    sar{b}\t{%b2, %0|%0, %b2}"
12193   [(set_attr "type" "ishift")
12194    (set_attr "mode" "QI")])
12195
12196 (define_insn "*ashrqi3_1_slp"
12197   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12198         (ashiftrt:QI (match_dup 0)
12199                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12200    (clobber (reg:CC FLAGS_REG))]
12201   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12202    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12203   "@
12204    sar{b}\t{%1, %0|%0, %1}
12205    sar{b}\t{%b1, %0|%0, %b1}"
12206   [(set_attr "type" "ishift1")
12207    (set_attr "mode" "QI")])
12208
12209 ;; This pattern can't accept a variable shift count, since shifts by
12210 ;; zero don't affect the flags.  We assume that shifts by constant
12211 ;; zero are optimized away.
12212 (define_insn "*ashrqi3_one_bit_cmp"
12213   [(set (reg FLAGS_REG)
12214         (compare
12215           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12216                        (match_operand:QI 2 "const1_operand" "I"))
12217           (const_int 0)))
12218    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12219         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12220   "ix86_match_ccmode (insn, CCGOCmode)
12221    && (TARGET_SHIFT1 || optimize_size)
12222    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12223   "sar{b}\t%0"
12224   [(set_attr "type" "ishift")
12225    (set (attr "length")
12226      (if_then_else (match_operand 0 "register_operand" "")
12227         (const_string "2")
12228         (const_string "*")))])
12229
12230 (define_insn "*ashrqi3_one_bit_cconly"
12231   [(set (reg FLAGS_REG)
12232         (compare
12233           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12234                        (match_operand:QI 2 "const1_operand" "I"))
12235           (const_int 0)))
12236    (clobber (match_scratch:QI 0 "=q"))]
12237   "ix86_match_ccmode (insn, CCGOCmode)
12238    && (TARGET_SHIFT1 || optimize_size)
12239    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12240   "sar{b}\t%0"
12241   [(set_attr "type" "ishift")
12242    (set_attr "length" "2")])
12243
12244 ;; This pattern can't accept a variable shift count, since shifts by
12245 ;; zero don't affect the flags.  We assume that shifts by constant
12246 ;; zero are optimized away.
12247 (define_insn "*ashrqi3_cmp"
12248   [(set (reg FLAGS_REG)
12249         (compare
12250           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12251                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12252           (const_int 0)))
12253    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12254         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12255   "ix86_match_ccmode (insn, CCGOCmode)
12256    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12257    && (optimize_size
12258        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12259   "sar{b}\t{%2, %0|%0, %2}"
12260   [(set_attr "type" "ishift")
12261    (set_attr "mode" "QI")])
12262
12263 (define_insn "*ashrqi3_cconly"
12264   [(set (reg FLAGS_REG)
12265         (compare
12266           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12267                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12268           (const_int 0)))
12269    (clobber (match_scratch:QI 0 "=q"))]
12270   "ix86_match_ccmode (insn, CCGOCmode)
12271    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12272    && (optimize_size
12273        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12274   "sar{b}\t{%2, %0|%0, %2}"
12275   [(set_attr "type" "ishift")
12276    (set_attr "mode" "QI")])
12277
12278 \f
12279 ;; Logical shift instructions
12280
12281 ;; See comment above `ashldi3' about how this works.
12282
12283 (define_expand "lshrti3"
12284   [(parallel [(set (match_operand:TI 0 "register_operand" "")
12285                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12286                                 (match_operand:QI 2 "nonmemory_operand" "")))
12287               (clobber (reg:CC FLAGS_REG))])]
12288   "TARGET_64BIT"
12289 {
12290   if (! immediate_operand (operands[2], QImode))
12291     {
12292       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12293       DONE;
12294     }
12295   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12296   DONE;
12297 })
12298
12299 (define_insn "lshrti3_1"
12300   [(set (match_operand:TI 0 "register_operand" "=r")
12301         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12302                      (match_operand:QI 2 "register_operand" "c")))
12303    (clobber (match_scratch:DI 3 "=&r"))
12304    (clobber (reg:CC FLAGS_REG))]
12305   "TARGET_64BIT"
12306   "#"
12307   [(set_attr "type" "multi")])
12308
12309 (define_insn "*lshrti3_2"
12310   [(set (match_operand:TI 0 "register_operand" "=r")
12311         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12312                      (match_operand:QI 2 "immediate_operand" "O")))
12313    (clobber (reg:CC FLAGS_REG))]
12314   "TARGET_64BIT"
12315   "#"
12316   [(set_attr "type" "multi")])
12317
12318 (define_split
12319   [(set (match_operand:TI 0 "register_operand" "")
12320         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12321                      (match_operand:QI 2 "register_operand" "")))
12322    (clobber (match_scratch:DI 3 ""))
12323    (clobber (reg:CC FLAGS_REG))]
12324   "TARGET_64BIT && reload_completed"
12325   [(const_int 0)]
12326   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12327
12328 (define_split
12329   [(set (match_operand:TI 0 "register_operand" "")
12330         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12331                      (match_operand:QI 2 "immediate_operand" "")))
12332    (clobber (reg:CC FLAGS_REG))]
12333   "TARGET_64BIT && reload_completed"
12334   [(const_int 0)]
12335   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12336
12337 (define_expand "lshrdi3"
12338   [(set (match_operand:DI 0 "shiftdi_operand" "")
12339         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12340                      (match_operand:QI 2 "nonmemory_operand" "")))]
12341   ""
12342   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12343
12344 (define_insn "*lshrdi3_1_one_bit_rex64"
12345   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12346         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12347                      (match_operand:QI 2 "const1_operand" "")))
12348    (clobber (reg:CC FLAGS_REG))]
12349   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12350    && (TARGET_SHIFT1 || optimize_size)"
12351   "shr{q}\t%0"
12352   [(set_attr "type" "ishift")
12353    (set (attr "length")
12354      (if_then_else (match_operand:DI 0 "register_operand" "")
12355         (const_string "2")
12356         (const_string "*")))])
12357
12358 (define_insn "*lshrdi3_1_rex64"
12359   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12360         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12361                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12362    (clobber (reg:CC FLAGS_REG))]
12363   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12364   "@
12365    shr{q}\t{%2, %0|%0, %2}
12366    shr{q}\t{%b2, %0|%0, %b2}"
12367   [(set_attr "type" "ishift")
12368    (set_attr "mode" "DI")])
12369
12370 ;; This pattern can't accept a variable shift count, since shifts by
12371 ;; zero don't affect the flags.  We assume that shifts by constant
12372 ;; zero are optimized away.
12373 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12374   [(set (reg FLAGS_REG)
12375         (compare
12376           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12377                        (match_operand:QI 2 "const1_operand" ""))
12378           (const_int 0)))
12379    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12380         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12381   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12382    && (TARGET_SHIFT1 || optimize_size)
12383    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12384   "shr{q}\t%0"
12385   [(set_attr "type" "ishift")
12386    (set (attr "length")
12387      (if_then_else (match_operand:DI 0 "register_operand" "")
12388         (const_string "2")
12389         (const_string "*")))])
12390
12391 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12392   [(set (reg FLAGS_REG)
12393         (compare
12394           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12395                        (match_operand:QI 2 "const1_operand" ""))
12396           (const_int 0)))
12397    (clobber (match_scratch:DI 0 "=r"))]
12398   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12399    && (TARGET_SHIFT1 || optimize_size)
12400    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12401   "shr{q}\t%0"
12402   [(set_attr "type" "ishift")
12403    (set_attr "length" "2")])
12404
12405 ;; This pattern can't accept a variable shift count, since shifts by
12406 ;; zero don't affect the flags.  We assume that shifts by constant
12407 ;; zero are optimized away.
12408 (define_insn "*lshrdi3_cmp_rex64"
12409   [(set (reg FLAGS_REG)
12410         (compare
12411           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12412                        (match_operand:QI 2 "const_int_operand" "e"))
12413           (const_int 0)))
12414    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12415         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12416   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12417    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12418    && (optimize_size
12419        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12420   "shr{q}\t{%2, %0|%0, %2}"
12421   [(set_attr "type" "ishift")
12422    (set_attr "mode" "DI")])
12423
12424 (define_insn "*lshrdi3_cconly_rex64"
12425   [(set (reg FLAGS_REG)
12426         (compare
12427           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12428                        (match_operand:QI 2 "const_int_operand" "e"))
12429           (const_int 0)))
12430    (clobber (match_scratch:DI 0 "=r"))]
12431   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12432    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12433    && (optimize_size
12434        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12435   "shr{q}\t{%2, %0|%0, %2}"
12436   [(set_attr "type" "ishift")
12437    (set_attr "mode" "DI")])
12438
12439 (define_insn "*lshrdi3_1"
12440   [(set (match_operand:DI 0 "register_operand" "=r")
12441         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12442                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12443    (clobber (reg:CC FLAGS_REG))]
12444   "!TARGET_64BIT"
12445   "#"
12446   [(set_attr "type" "multi")])
12447
12448 ;; By default we don't ask for a scratch register, because when DImode
12449 ;; values are manipulated, registers are already at a premium.  But if
12450 ;; we have one handy, we won't turn it away.
12451 (define_peephole2
12452   [(match_scratch:SI 3 "r")
12453    (parallel [(set (match_operand:DI 0 "register_operand" "")
12454                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12455                                 (match_operand:QI 2 "nonmemory_operand" "")))
12456               (clobber (reg:CC FLAGS_REG))])
12457    (match_dup 3)]
12458   "!TARGET_64BIT && TARGET_CMOVE"
12459   [(const_int 0)]
12460   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12461
12462 (define_split
12463   [(set (match_operand:DI 0 "register_operand" "")
12464         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12465                      (match_operand:QI 2 "nonmemory_operand" "")))
12466    (clobber (reg:CC FLAGS_REG))]
12467   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12468                      ? flow2_completed : reload_completed)"
12469   [(const_int 0)]
12470   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12471
12472 (define_expand "lshrsi3"
12473   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12474         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12475                      (match_operand:QI 2 "nonmemory_operand" "")))
12476    (clobber (reg:CC FLAGS_REG))]
12477   ""
12478   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12479
12480 (define_insn "*lshrsi3_1_one_bit"
12481   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12482         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12483                      (match_operand:QI 2 "const1_operand" "")))
12484    (clobber (reg:CC FLAGS_REG))]
12485   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12486    && (TARGET_SHIFT1 || optimize_size)"
12487   "shr{l}\t%0"
12488   [(set_attr "type" "ishift")
12489    (set (attr "length")
12490      (if_then_else (match_operand:SI 0 "register_operand" "")
12491         (const_string "2")
12492         (const_string "*")))])
12493
12494 (define_insn "*lshrsi3_1_one_bit_zext"
12495   [(set (match_operand:DI 0 "register_operand" "=r")
12496         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12497                      (match_operand:QI 2 "const1_operand" "")))
12498    (clobber (reg:CC FLAGS_REG))]
12499   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12500    && (TARGET_SHIFT1 || optimize_size)"
12501   "shr{l}\t%k0"
12502   [(set_attr "type" "ishift")
12503    (set_attr "length" "2")])
12504
12505 (define_insn "*lshrsi3_1"
12506   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12507         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12508                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12509    (clobber (reg:CC FLAGS_REG))]
12510   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12511   "@
12512    shr{l}\t{%2, %0|%0, %2}
12513    shr{l}\t{%b2, %0|%0, %b2}"
12514   [(set_attr "type" "ishift")
12515    (set_attr "mode" "SI")])
12516
12517 (define_insn "*lshrsi3_1_zext"
12518   [(set (match_operand:DI 0 "register_operand" "=r,r")
12519         (zero_extend:DI
12520           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12521                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12522    (clobber (reg:CC FLAGS_REG))]
12523   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12524   "@
12525    shr{l}\t{%2, %k0|%k0, %2}
12526    shr{l}\t{%b2, %k0|%k0, %b2}"
12527   [(set_attr "type" "ishift")
12528    (set_attr "mode" "SI")])
12529
12530 ;; This pattern can't accept a variable shift count, since shifts by
12531 ;; zero don't affect the flags.  We assume that shifts by constant
12532 ;; zero are optimized away.
12533 (define_insn "*lshrsi3_one_bit_cmp"
12534   [(set (reg FLAGS_REG)
12535         (compare
12536           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12537                        (match_operand:QI 2 "const1_operand" ""))
12538           (const_int 0)))
12539    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12540         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12541   "ix86_match_ccmode (insn, CCGOCmode)
12542    && (TARGET_SHIFT1 || optimize_size)
12543    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12544   "shr{l}\t%0"
12545   [(set_attr "type" "ishift")
12546    (set (attr "length")
12547      (if_then_else (match_operand:SI 0 "register_operand" "")
12548         (const_string "2")
12549         (const_string "*")))])
12550
12551 (define_insn "*lshrsi3_one_bit_cconly"
12552   [(set (reg FLAGS_REG)
12553         (compare
12554           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12555                        (match_operand:QI 2 "const1_operand" ""))
12556           (const_int 0)))
12557    (clobber (match_scratch:SI 0 "=r"))]
12558   "ix86_match_ccmode (insn, CCGOCmode)
12559    && (TARGET_SHIFT1 || optimize_size)
12560    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12561   "shr{l}\t%0"
12562   [(set_attr "type" "ishift")
12563    (set_attr "length" "2")])
12564
12565 (define_insn "*lshrsi3_cmp_one_bit_zext"
12566   [(set (reg FLAGS_REG)
12567         (compare
12568           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12569                        (match_operand:QI 2 "const1_operand" ""))
12570           (const_int 0)))
12571    (set (match_operand:DI 0 "register_operand" "=r")
12572         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12573   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12574    && (TARGET_SHIFT1 || optimize_size)
12575    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12576   "shr{l}\t%k0"
12577   [(set_attr "type" "ishift")
12578    (set_attr "length" "2")])
12579
12580 ;; This pattern can't accept a variable shift count, since shifts by
12581 ;; zero don't affect the flags.  We assume that shifts by constant
12582 ;; zero are optimized away.
12583 (define_insn "*lshrsi3_cmp"
12584   [(set (reg FLAGS_REG)
12585         (compare
12586           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12587                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12588           (const_int 0)))
12589    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12590         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12591   "ix86_match_ccmode (insn, CCGOCmode)
12592    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12593    && (optimize_size
12594        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12595   "shr{l}\t{%2, %0|%0, %2}"
12596   [(set_attr "type" "ishift")
12597    (set_attr "mode" "SI")])
12598
12599 (define_insn "*lshrsi3_cconly"
12600   [(set (reg FLAGS_REG)
12601       (compare
12602         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12603                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12604         (const_int 0)))
12605    (clobber (match_scratch:SI 0 "=r"))]
12606   "ix86_match_ccmode (insn, CCGOCmode)
12607    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12608    && (optimize_size
12609        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12610   "shr{l}\t{%2, %0|%0, %2}"
12611   [(set_attr "type" "ishift")
12612    (set_attr "mode" "SI")])
12613
12614 (define_insn "*lshrsi3_cmp_zext"
12615   [(set (reg FLAGS_REG)
12616         (compare
12617           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12618                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12619           (const_int 0)))
12620    (set (match_operand:DI 0 "register_operand" "=r")
12621         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12622   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12623    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12624    && (optimize_size
12625        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12626   "shr{l}\t{%2, %k0|%k0, %2}"
12627   [(set_attr "type" "ishift")
12628    (set_attr "mode" "SI")])
12629
12630 (define_expand "lshrhi3"
12631   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12632         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12633                      (match_operand:QI 2 "nonmemory_operand" "")))
12634    (clobber (reg:CC FLAGS_REG))]
12635   "TARGET_HIMODE_MATH"
12636   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12637
12638 (define_insn "*lshrhi3_1_one_bit"
12639   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12640         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12641                      (match_operand:QI 2 "const1_operand" "")))
12642    (clobber (reg:CC FLAGS_REG))]
12643   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12644    && (TARGET_SHIFT1 || optimize_size)"
12645   "shr{w}\t%0"
12646   [(set_attr "type" "ishift")
12647    (set (attr "length")
12648      (if_then_else (match_operand 0 "register_operand" "")
12649         (const_string "2")
12650         (const_string "*")))])
12651
12652 (define_insn "*lshrhi3_1"
12653   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12654         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12655                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12656    (clobber (reg:CC FLAGS_REG))]
12657   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12658   "@
12659    shr{w}\t{%2, %0|%0, %2}
12660    shr{w}\t{%b2, %0|%0, %b2}"
12661   [(set_attr "type" "ishift")
12662    (set_attr "mode" "HI")])
12663
12664 ;; This pattern can't accept a variable shift count, since shifts by
12665 ;; zero don't affect the flags.  We assume that shifts by constant
12666 ;; zero are optimized away.
12667 (define_insn "*lshrhi3_one_bit_cmp"
12668   [(set (reg FLAGS_REG)
12669         (compare
12670           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12671                        (match_operand:QI 2 "const1_operand" ""))
12672           (const_int 0)))
12673    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12674         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12675   "ix86_match_ccmode (insn, CCGOCmode)
12676    && (TARGET_SHIFT1 || optimize_size)
12677    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12678   "shr{w}\t%0"
12679   [(set_attr "type" "ishift")
12680    (set (attr "length")
12681      (if_then_else (match_operand:SI 0 "register_operand" "")
12682         (const_string "2")
12683         (const_string "*")))])
12684
12685 (define_insn "*lshrhi3_one_bit_cconly"
12686   [(set (reg FLAGS_REG)
12687         (compare
12688           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12689                        (match_operand:QI 2 "const1_operand" ""))
12690           (const_int 0)))
12691    (clobber (match_scratch:HI 0 "=r"))]
12692   "ix86_match_ccmode (insn, CCGOCmode)
12693    && (TARGET_SHIFT1 || optimize_size)
12694    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12695   "shr{w}\t%0"
12696   [(set_attr "type" "ishift")
12697    (set_attr "length" "2")])
12698
12699 ;; This pattern can't accept a variable shift count, since shifts by
12700 ;; zero don't affect the flags.  We assume that shifts by constant
12701 ;; zero are optimized away.
12702 (define_insn "*lshrhi3_cmp"
12703   [(set (reg FLAGS_REG)
12704         (compare
12705           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12706                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12707           (const_int 0)))
12708    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12709         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12710   "ix86_match_ccmode (insn, CCGOCmode)
12711    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12712    && (optimize_size
12713        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12714   "shr{w}\t{%2, %0|%0, %2}"
12715   [(set_attr "type" "ishift")
12716    (set_attr "mode" "HI")])
12717
12718 (define_insn "*lshrhi3_cconly"
12719   [(set (reg FLAGS_REG)
12720         (compare
12721           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12722                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12723           (const_int 0)))
12724    (clobber (match_scratch:HI 0 "=r"))]
12725   "ix86_match_ccmode (insn, CCGOCmode)
12726    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12727    && (optimize_size
12728        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12729   "shr{w}\t{%2, %0|%0, %2}"
12730   [(set_attr "type" "ishift")
12731    (set_attr "mode" "HI")])
12732
12733 (define_expand "lshrqi3"
12734   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12735         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12736                      (match_operand:QI 2 "nonmemory_operand" "")))
12737    (clobber (reg:CC FLAGS_REG))]
12738   "TARGET_QIMODE_MATH"
12739   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12740
12741 (define_insn "*lshrqi3_1_one_bit"
12742   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12743         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12744                      (match_operand:QI 2 "const1_operand" "")))
12745    (clobber (reg:CC FLAGS_REG))]
12746   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12747    && (TARGET_SHIFT1 || optimize_size)"
12748   "shr{b}\t%0"
12749   [(set_attr "type" "ishift")
12750    (set (attr "length")
12751      (if_then_else (match_operand 0 "register_operand" "")
12752         (const_string "2")
12753         (const_string "*")))])
12754
12755 (define_insn "*lshrqi3_1_one_bit_slp"
12756   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12757         (lshiftrt:QI (match_dup 0)
12758                      (match_operand:QI 1 "const1_operand" "")))
12759    (clobber (reg:CC FLAGS_REG))]
12760   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12761    && (TARGET_SHIFT1 || optimize_size)"
12762   "shr{b}\t%0"
12763   [(set_attr "type" "ishift1")
12764    (set (attr "length")
12765      (if_then_else (match_operand 0 "register_operand" "")
12766         (const_string "2")
12767         (const_string "*")))])
12768
12769 (define_insn "*lshrqi3_1"
12770   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12771         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12772                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12773    (clobber (reg:CC FLAGS_REG))]
12774   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12775   "@
12776    shr{b}\t{%2, %0|%0, %2}
12777    shr{b}\t{%b2, %0|%0, %b2}"
12778   [(set_attr "type" "ishift")
12779    (set_attr "mode" "QI")])
12780
12781 (define_insn "*lshrqi3_1_slp"
12782   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12783         (lshiftrt:QI (match_dup 0)
12784                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12785    (clobber (reg:CC FLAGS_REG))]
12786   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12787    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12788   "@
12789    shr{b}\t{%1, %0|%0, %1}
12790    shr{b}\t{%b1, %0|%0, %b1}"
12791   [(set_attr "type" "ishift1")
12792    (set_attr "mode" "QI")])
12793
12794 ;; This pattern can't accept a variable shift count, since shifts by
12795 ;; zero don't affect the flags.  We assume that shifts by constant
12796 ;; zero are optimized away.
12797 (define_insn "*lshrqi2_one_bit_cmp"
12798   [(set (reg FLAGS_REG)
12799         (compare
12800           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12801                        (match_operand:QI 2 "const1_operand" ""))
12802           (const_int 0)))
12803    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12804         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12805   "ix86_match_ccmode (insn, CCGOCmode)
12806    && (TARGET_SHIFT1 || optimize_size)
12807    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12808   "shr{b}\t%0"
12809   [(set_attr "type" "ishift")
12810    (set (attr "length")
12811      (if_then_else (match_operand:SI 0 "register_operand" "")
12812         (const_string "2")
12813         (const_string "*")))])
12814
12815 (define_insn "*lshrqi2_one_bit_cconly"
12816   [(set (reg FLAGS_REG)
12817         (compare
12818           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12819                        (match_operand:QI 2 "const1_operand" ""))
12820           (const_int 0)))
12821    (clobber (match_scratch:QI 0 "=q"))]
12822   "ix86_match_ccmode (insn, CCGOCmode)
12823    && (TARGET_SHIFT1 || optimize_size)
12824    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12825   "shr{b}\t%0"
12826   [(set_attr "type" "ishift")
12827    (set_attr "length" "2")])
12828
12829 ;; This pattern can't accept a variable shift count, since shifts by
12830 ;; zero don't affect the flags.  We assume that shifts by constant
12831 ;; zero are optimized away.
12832 (define_insn "*lshrqi2_cmp"
12833   [(set (reg FLAGS_REG)
12834         (compare
12835           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12836                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12837           (const_int 0)))
12838    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12839         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12840   "ix86_match_ccmode (insn, CCGOCmode)
12841    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12842    && (optimize_size
12843        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12844   "shr{b}\t{%2, %0|%0, %2}"
12845   [(set_attr "type" "ishift")
12846    (set_attr "mode" "QI")])
12847
12848 (define_insn "*lshrqi2_cconly"
12849   [(set (reg FLAGS_REG)
12850         (compare
12851           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12852                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12853           (const_int 0)))
12854    (clobber (match_scratch:QI 0 "=q"))]
12855   "ix86_match_ccmode (insn, CCGOCmode)
12856    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12857    && (optimize_size
12858        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12859   "shr{b}\t{%2, %0|%0, %2}"
12860   [(set_attr "type" "ishift")
12861    (set_attr "mode" "QI")])
12862 \f
12863 ;; Rotate instructions
12864
12865 (define_expand "rotldi3"
12866   [(set (match_operand:DI 0 "shiftdi_operand" "")
12867         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12868                    (match_operand:QI 2 "nonmemory_operand" "")))
12869    (clobber (reg:CC FLAGS_REG))]
12870  ""
12871 {
12872   if (TARGET_64BIT)
12873     {
12874       ix86_expand_binary_operator (ROTATE, DImode, operands);
12875       DONE;
12876     }
12877   if (!const_1_to_31_operand (operands[2], VOIDmode))
12878     FAIL;
12879   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12880   DONE;
12881 })
12882
12883 ;; Implement rotation using two double-precision shift instructions
12884 ;; and a scratch register.
12885 (define_insn_and_split "ix86_rotldi3"
12886  [(set (match_operand:DI 0 "register_operand" "=r")
12887        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12888                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12889   (clobber (reg:CC FLAGS_REG))
12890   (clobber (match_scratch:SI 3 "=&r"))]
12891  "!TARGET_64BIT"
12892  ""
12893  "&& reload_completed"
12894  [(set (match_dup 3) (match_dup 4))
12895   (parallel
12896    [(set (match_dup 4)
12897          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12898                  (lshiftrt:SI (match_dup 5)
12899                               (minus:QI (const_int 32) (match_dup 2)))))
12900     (clobber (reg:CC FLAGS_REG))])
12901   (parallel
12902    [(set (match_dup 5)
12903          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12904                  (lshiftrt:SI (match_dup 3)
12905                               (minus:QI (const_int 32) (match_dup 2)))))
12906     (clobber (reg:CC FLAGS_REG))])]
12907  "split_di (operands, 1, operands + 4, operands + 5);")
12908
12909 (define_insn "*rotlsi3_1_one_bit_rex64"
12910   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12911         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12912                    (match_operand:QI 2 "const1_operand" "")))
12913    (clobber (reg:CC FLAGS_REG))]
12914   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12915    && (TARGET_SHIFT1 || optimize_size)"
12916   "rol{q}\t%0"
12917   [(set_attr "type" "rotate")
12918    (set (attr "length")
12919      (if_then_else (match_operand:DI 0 "register_operand" "")
12920         (const_string "2")
12921         (const_string "*")))])
12922
12923 (define_insn "*rotldi3_1_rex64"
12924   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12925         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12926                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12927    (clobber (reg:CC FLAGS_REG))]
12928   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12929   "@
12930    rol{q}\t{%2, %0|%0, %2}
12931    rol{q}\t{%b2, %0|%0, %b2}"
12932   [(set_attr "type" "rotate")
12933    (set_attr "mode" "DI")])
12934
12935 (define_expand "rotlsi3"
12936   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12937         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12938                    (match_operand:QI 2 "nonmemory_operand" "")))
12939    (clobber (reg:CC FLAGS_REG))]
12940   ""
12941   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12942
12943 (define_insn "*rotlsi3_1_one_bit"
12944   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12945         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12946                    (match_operand:QI 2 "const1_operand" "")))
12947    (clobber (reg:CC FLAGS_REG))]
12948   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12949    && (TARGET_SHIFT1 || optimize_size)"
12950   "rol{l}\t%0"
12951   [(set_attr "type" "rotate")
12952    (set (attr "length")
12953      (if_then_else (match_operand:SI 0 "register_operand" "")
12954         (const_string "2")
12955         (const_string "*")))])
12956
12957 (define_insn "*rotlsi3_1_one_bit_zext"
12958   [(set (match_operand:DI 0 "register_operand" "=r")
12959         (zero_extend:DI
12960           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12961                      (match_operand:QI 2 "const1_operand" ""))))
12962    (clobber (reg:CC FLAGS_REG))]
12963   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12964    && (TARGET_SHIFT1 || optimize_size)"
12965   "rol{l}\t%k0"
12966   [(set_attr "type" "rotate")
12967    (set_attr "length" "2")])
12968
12969 (define_insn "*rotlsi3_1"
12970   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12971         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12972                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12973    (clobber (reg:CC FLAGS_REG))]
12974   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12975   "@
12976    rol{l}\t{%2, %0|%0, %2}
12977    rol{l}\t{%b2, %0|%0, %b2}"
12978   [(set_attr "type" "rotate")
12979    (set_attr "mode" "SI")])
12980
12981 (define_insn "*rotlsi3_1_zext"
12982   [(set (match_operand:DI 0 "register_operand" "=r,r")
12983         (zero_extend:DI
12984           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12985                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12986    (clobber (reg:CC FLAGS_REG))]
12987   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12988   "@
12989    rol{l}\t{%2, %k0|%k0, %2}
12990    rol{l}\t{%b2, %k0|%k0, %b2}"
12991   [(set_attr "type" "rotate")
12992    (set_attr "mode" "SI")])
12993
12994 (define_expand "rotlhi3"
12995   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12996         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12997                    (match_operand:QI 2 "nonmemory_operand" "")))
12998    (clobber (reg:CC FLAGS_REG))]
12999   "TARGET_HIMODE_MATH"
13000   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13001
13002 (define_insn "*rotlhi3_1_one_bit"
13003   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13004         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13005                    (match_operand:QI 2 "const1_operand" "")))
13006    (clobber (reg:CC FLAGS_REG))]
13007   "ix86_binary_operator_ok (ROTATE, HImode, operands)
13008    && (TARGET_SHIFT1 || optimize_size)"
13009   "rol{w}\t%0"
13010   [(set_attr "type" "rotate")
13011    (set (attr "length")
13012      (if_then_else (match_operand 0 "register_operand" "")
13013         (const_string "2")
13014         (const_string "*")))])
13015
13016 (define_insn "*rotlhi3_1"
13017   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13018         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13019                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13020    (clobber (reg:CC FLAGS_REG))]
13021   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13022   "@
13023    rol{w}\t{%2, %0|%0, %2}
13024    rol{w}\t{%b2, %0|%0, %b2}"
13025   [(set_attr "type" "rotate")
13026    (set_attr "mode" "HI")])
13027
13028 (define_split
13029  [(set (match_operand:HI 0 "register_operand" "")
13030        (rotate:HI (match_dup 0) (const_int 8)))
13031   (clobber (reg:CC FLAGS_REG))]
13032  "reload_completed"
13033  [(parallel [(set (strict_low_part (match_dup 0))
13034                   (bswap:HI (match_dup 0)))
13035              (clobber (reg:CC FLAGS_REG))])]
13036  "")
13037
13038 (define_expand "rotlqi3"
13039   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13040         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13041                    (match_operand:QI 2 "nonmemory_operand" "")))
13042    (clobber (reg:CC FLAGS_REG))]
13043   "TARGET_QIMODE_MATH"
13044   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13045
13046 (define_insn "*rotlqi3_1_one_bit_slp"
13047   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13048         (rotate:QI (match_dup 0)
13049                    (match_operand:QI 1 "const1_operand" "")))
13050    (clobber (reg:CC FLAGS_REG))]
13051   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13052    && (TARGET_SHIFT1 || optimize_size)"
13053   "rol{b}\t%0"
13054   [(set_attr "type" "rotate1")
13055    (set (attr "length")
13056      (if_then_else (match_operand 0 "register_operand" "")
13057         (const_string "2")
13058         (const_string "*")))])
13059
13060 (define_insn "*rotlqi3_1_one_bit"
13061   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13062         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13063                    (match_operand:QI 2 "const1_operand" "")))
13064    (clobber (reg:CC FLAGS_REG))]
13065   "ix86_binary_operator_ok (ROTATE, QImode, operands)
13066    && (TARGET_SHIFT1 || optimize_size)"
13067   "rol{b}\t%0"
13068   [(set_attr "type" "rotate")
13069    (set (attr "length")
13070      (if_then_else (match_operand 0 "register_operand" "")
13071         (const_string "2")
13072         (const_string "*")))])
13073
13074 (define_insn "*rotlqi3_1_slp"
13075   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13076         (rotate:QI (match_dup 0)
13077                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13078    (clobber (reg:CC FLAGS_REG))]
13079   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13080    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13081   "@
13082    rol{b}\t{%1, %0|%0, %1}
13083    rol{b}\t{%b1, %0|%0, %b1}"
13084   [(set_attr "type" "rotate1")
13085    (set_attr "mode" "QI")])
13086
13087 (define_insn "*rotlqi3_1"
13088   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13089         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13090                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13091    (clobber (reg:CC FLAGS_REG))]
13092   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13093   "@
13094    rol{b}\t{%2, %0|%0, %2}
13095    rol{b}\t{%b2, %0|%0, %b2}"
13096   [(set_attr "type" "rotate")
13097    (set_attr "mode" "QI")])
13098
13099 (define_expand "rotrdi3"
13100   [(set (match_operand:DI 0 "shiftdi_operand" "")
13101         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13102                    (match_operand:QI 2 "nonmemory_operand" "")))
13103    (clobber (reg:CC FLAGS_REG))]
13104  ""
13105 {
13106   if (TARGET_64BIT)
13107     {
13108       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13109       DONE;
13110     }
13111   if (!const_1_to_31_operand (operands[2], VOIDmode))
13112     FAIL;
13113   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13114   DONE;
13115 })
13116
13117 ;; Implement rotation using two double-precision shift instructions
13118 ;; and a scratch register.
13119 (define_insn_and_split "ix86_rotrdi3"
13120  [(set (match_operand:DI 0 "register_operand" "=r")
13121        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13122                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13123   (clobber (reg:CC FLAGS_REG))
13124   (clobber (match_scratch:SI 3 "=&r"))]
13125  "!TARGET_64BIT"
13126  ""
13127  "&& reload_completed"
13128  [(set (match_dup 3) (match_dup 4))
13129   (parallel
13130    [(set (match_dup 4)
13131          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13132                  (ashift:SI (match_dup 5)
13133                             (minus:QI (const_int 32) (match_dup 2)))))
13134     (clobber (reg:CC FLAGS_REG))])
13135   (parallel
13136    [(set (match_dup 5)
13137          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13138                  (ashift:SI (match_dup 3)
13139                             (minus:QI (const_int 32) (match_dup 2)))))
13140     (clobber (reg:CC FLAGS_REG))])]
13141  "split_di (operands, 1, operands + 4, operands + 5);")
13142
13143 (define_insn "*rotrdi3_1_one_bit_rex64"
13144   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13145         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13146                      (match_operand:QI 2 "const1_operand" "")))
13147    (clobber (reg:CC FLAGS_REG))]
13148   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
13149    && (TARGET_SHIFT1 || optimize_size)"
13150   "ror{q}\t%0"
13151   [(set_attr "type" "rotate")
13152    (set (attr "length")
13153      (if_then_else (match_operand:DI 0 "register_operand" "")
13154         (const_string "2")
13155         (const_string "*")))])
13156
13157 (define_insn "*rotrdi3_1_rex64"
13158   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13159         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13160                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13161    (clobber (reg:CC FLAGS_REG))]
13162   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13163   "@
13164    ror{q}\t{%2, %0|%0, %2}
13165    ror{q}\t{%b2, %0|%0, %b2}"
13166   [(set_attr "type" "rotate")
13167    (set_attr "mode" "DI")])
13168
13169 (define_expand "rotrsi3"
13170   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13171         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13172                      (match_operand:QI 2 "nonmemory_operand" "")))
13173    (clobber (reg:CC FLAGS_REG))]
13174   ""
13175   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13176
13177 (define_insn "*rotrsi3_1_one_bit"
13178   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13179         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13180                      (match_operand:QI 2 "const1_operand" "")))
13181    (clobber (reg:CC FLAGS_REG))]
13182   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
13183    && (TARGET_SHIFT1 || optimize_size)"
13184   "ror{l}\t%0"
13185   [(set_attr "type" "rotate")
13186    (set (attr "length")
13187      (if_then_else (match_operand:SI 0 "register_operand" "")
13188         (const_string "2")
13189         (const_string "*")))])
13190
13191 (define_insn "*rotrsi3_1_one_bit_zext"
13192   [(set (match_operand:DI 0 "register_operand" "=r")
13193         (zero_extend:DI
13194           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13195                        (match_operand:QI 2 "const1_operand" ""))))
13196    (clobber (reg:CC FLAGS_REG))]
13197   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
13198    && (TARGET_SHIFT1 || optimize_size)"
13199   "ror{l}\t%k0"
13200   [(set_attr "type" "rotate")
13201    (set (attr "length")
13202      (if_then_else (match_operand:SI 0 "register_operand" "")
13203         (const_string "2")
13204         (const_string "*")))])
13205
13206 (define_insn "*rotrsi3_1"
13207   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13208         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13209                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13210    (clobber (reg:CC FLAGS_REG))]
13211   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13212   "@
13213    ror{l}\t{%2, %0|%0, %2}
13214    ror{l}\t{%b2, %0|%0, %b2}"
13215   [(set_attr "type" "rotate")
13216    (set_attr "mode" "SI")])
13217
13218 (define_insn "*rotrsi3_1_zext"
13219   [(set (match_operand:DI 0 "register_operand" "=r,r")
13220         (zero_extend:DI
13221           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13222                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13223    (clobber (reg:CC FLAGS_REG))]
13224   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13225   "@
13226    ror{l}\t{%2, %k0|%k0, %2}
13227    ror{l}\t{%b2, %k0|%k0, %b2}"
13228   [(set_attr "type" "rotate")
13229    (set_attr "mode" "SI")])
13230
13231 (define_expand "rotrhi3"
13232   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13233         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13234                      (match_operand:QI 2 "nonmemory_operand" "")))
13235    (clobber (reg:CC FLAGS_REG))]
13236   "TARGET_HIMODE_MATH"
13237   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13238
13239 (define_insn "*rotrhi3_one_bit"
13240   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13241         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13242                      (match_operand:QI 2 "const1_operand" "")))
13243    (clobber (reg:CC FLAGS_REG))]
13244   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
13245    && (TARGET_SHIFT1 || optimize_size)"
13246   "ror{w}\t%0"
13247   [(set_attr "type" "rotate")
13248    (set (attr "length")
13249      (if_then_else (match_operand 0 "register_operand" "")
13250         (const_string "2")
13251         (const_string "*")))])
13252
13253 (define_insn "*rotrhi3_1"
13254   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13255         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13256                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13257    (clobber (reg:CC FLAGS_REG))]
13258   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13259   "@
13260    ror{w}\t{%2, %0|%0, %2}
13261    ror{w}\t{%b2, %0|%0, %b2}"
13262   [(set_attr "type" "rotate")
13263    (set_attr "mode" "HI")])
13264
13265 (define_split
13266  [(set (match_operand:HI 0 "register_operand" "")
13267        (rotatert:HI (match_dup 0) (const_int 8)))
13268   (clobber (reg:CC FLAGS_REG))]
13269  "reload_completed"
13270  [(parallel [(set (strict_low_part (match_dup 0))
13271                   (bswap:HI (match_dup 0)))
13272              (clobber (reg:CC FLAGS_REG))])]
13273  "")
13274
13275 (define_expand "rotrqi3"
13276   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13277         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13278                      (match_operand:QI 2 "nonmemory_operand" "")))
13279    (clobber (reg:CC FLAGS_REG))]
13280   "TARGET_QIMODE_MATH"
13281   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13282
13283 (define_insn "*rotrqi3_1_one_bit"
13284   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13285         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13286                      (match_operand:QI 2 "const1_operand" "")))
13287    (clobber (reg:CC FLAGS_REG))]
13288   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
13289    && (TARGET_SHIFT1 || optimize_size)"
13290   "ror{b}\t%0"
13291   [(set_attr "type" "rotate")
13292    (set (attr "length")
13293      (if_then_else (match_operand 0 "register_operand" "")
13294         (const_string "2")
13295         (const_string "*")))])
13296
13297 (define_insn "*rotrqi3_1_one_bit_slp"
13298   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13299         (rotatert:QI (match_dup 0)
13300                      (match_operand:QI 1 "const1_operand" "")))
13301    (clobber (reg:CC FLAGS_REG))]
13302   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13303    && (TARGET_SHIFT1 || optimize_size)"
13304   "ror{b}\t%0"
13305   [(set_attr "type" "rotate1")
13306    (set (attr "length")
13307      (if_then_else (match_operand 0 "register_operand" "")
13308         (const_string "2")
13309         (const_string "*")))])
13310
13311 (define_insn "*rotrqi3_1"
13312   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13313         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13314                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13315    (clobber (reg:CC FLAGS_REG))]
13316   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13317   "@
13318    ror{b}\t{%2, %0|%0, %2}
13319    ror{b}\t{%b2, %0|%0, %b2}"
13320   [(set_attr "type" "rotate")
13321    (set_attr "mode" "QI")])
13322
13323 (define_insn "*rotrqi3_1_slp"
13324   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13325         (rotatert:QI (match_dup 0)
13326                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13327    (clobber (reg:CC FLAGS_REG))]
13328   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13329    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13330   "@
13331    ror{b}\t{%1, %0|%0, %1}
13332    ror{b}\t{%b1, %0|%0, %b1}"
13333   [(set_attr "type" "rotate1")
13334    (set_attr "mode" "QI")])
13335 \f
13336 ;; Bit set / bit test instructions
13337
13338 (define_expand "extv"
13339   [(set (match_operand:SI 0 "register_operand" "")
13340         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13341                          (match_operand:SI 2 "const8_operand" "")
13342                          (match_operand:SI 3 "const8_operand" "")))]
13343   ""
13344 {
13345   /* Handle extractions from %ah et al.  */
13346   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13347     FAIL;
13348
13349   /* From mips.md: extract_bit_field doesn't verify that our source
13350      matches the predicate, so check it again here.  */
13351   if (! ext_register_operand (operands[1], VOIDmode))
13352     FAIL;
13353 })
13354
13355 (define_expand "extzv"
13356   [(set (match_operand:SI 0 "register_operand" "")
13357         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13358                          (match_operand:SI 2 "const8_operand" "")
13359                          (match_operand:SI 3 "const8_operand" "")))]
13360   ""
13361 {
13362   /* Handle extractions from %ah et al.  */
13363   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13364     FAIL;
13365
13366   /* From mips.md: extract_bit_field doesn't verify that our source
13367      matches the predicate, so check it again here.  */
13368   if (! ext_register_operand (operands[1], VOIDmode))
13369     FAIL;
13370 })
13371
13372 (define_expand "insv"
13373   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13374                       (match_operand 1 "const8_operand" "")
13375                       (match_operand 2 "const8_operand" ""))
13376         (match_operand 3 "register_operand" ""))]
13377   ""
13378 {
13379   /* Handle insertions to %ah et al.  */
13380   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13381     FAIL;
13382
13383   /* From mips.md: insert_bit_field doesn't verify that our source
13384      matches the predicate, so check it again here.  */
13385   if (! ext_register_operand (operands[0], VOIDmode))
13386     FAIL;
13387
13388   if (TARGET_64BIT)
13389     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13390   else
13391     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13392
13393   DONE;
13394 })
13395
13396 ;; %%% bts, btr, btc, bt.
13397 ;; In general these instructions are *slow* when applied to memory,
13398 ;; since they enforce atomic operation.  When applied to registers,
13399 ;; it depends on the cpu implementation.  They're never faster than
13400 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13401 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13402 ;; within the instruction itself, so operating on bits in the high
13403 ;; 32-bits of a register becomes easier.
13404 ;;
13405 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13406 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13407 ;; negdf respectively, so they can never be disabled entirely.
13408
13409 (define_insn "*btsq"
13410   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13411                          (const_int 1)
13412                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13413         (const_int 1))
13414    (clobber (reg:CC FLAGS_REG))]
13415   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13416   "bts{q} %1,%0"
13417   [(set_attr "type" "alu1")])
13418
13419 (define_insn "*btrq"
13420   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13421                          (const_int 1)
13422                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13423         (const_int 0))
13424    (clobber (reg:CC FLAGS_REG))]
13425   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13426   "btr{q} %1,%0"
13427   [(set_attr "type" "alu1")])
13428
13429 (define_insn "*btcq"
13430   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13431                          (const_int 1)
13432                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13433         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13434    (clobber (reg:CC FLAGS_REG))]
13435   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13436   "btc{q} %1,%0"
13437   [(set_attr "type" "alu1")])
13438
13439 ;; Allow Nocona to avoid these instructions if a register is available.
13440
13441 (define_peephole2
13442   [(match_scratch:DI 2 "r")
13443    (parallel [(set (zero_extract:DI
13444                      (match_operand:DI 0 "register_operand" "")
13445                      (const_int 1)
13446                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13447                    (const_int 1))
13448               (clobber (reg:CC FLAGS_REG))])]
13449   "TARGET_64BIT && !TARGET_USE_BT"
13450   [(const_int 0)]
13451 {
13452   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13453   rtx op1;
13454
13455   if (HOST_BITS_PER_WIDE_INT >= 64)
13456     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13457   else if (i < HOST_BITS_PER_WIDE_INT)
13458     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13459   else
13460     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13461
13462   op1 = immed_double_const (lo, hi, DImode);
13463   if (i >= 31)
13464     {
13465       emit_move_insn (operands[2], op1);
13466       op1 = operands[2];
13467     }
13468
13469   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13470   DONE;
13471 })
13472
13473 (define_peephole2
13474   [(match_scratch:DI 2 "r")
13475    (parallel [(set (zero_extract:DI
13476                      (match_operand:DI 0 "register_operand" "")
13477                      (const_int 1)
13478                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13479                    (const_int 0))
13480               (clobber (reg:CC FLAGS_REG))])]
13481   "TARGET_64BIT && !TARGET_USE_BT"
13482   [(const_int 0)]
13483 {
13484   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13485   rtx op1;
13486
13487   if (HOST_BITS_PER_WIDE_INT >= 64)
13488     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13489   else if (i < HOST_BITS_PER_WIDE_INT)
13490     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13491   else
13492     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13493
13494   op1 = immed_double_const (~lo, ~hi, DImode);
13495   if (i >= 32)
13496     {
13497       emit_move_insn (operands[2], op1);
13498       op1 = operands[2];
13499     }
13500
13501   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13502   DONE;
13503 })
13504
13505 (define_peephole2
13506   [(match_scratch:DI 2 "r")
13507    (parallel [(set (zero_extract:DI
13508                      (match_operand:DI 0 "register_operand" "")
13509                      (const_int 1)
13510                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13511               (not:DI (zero_extract:DI
13512                         (match_dup 0) (const_int 1) (match_dup 1))))
13513               (clobber (reg:CC FLAGS_REG))])]
13514   "TARGET_64BIT && !TARGET_USE_BT"
13515   [(const_int 0)]
13516 {
13517   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13518   rtx op1;
13519
13520   if (HOST_BITS_PER_WIDE_INT >= 64)
13521     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13522   else if (i < HOST_BITS_PER_WIDE_INT)
13523     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13524   else
13525     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13526
13527   op1 = immed_double_const (lo, hi, DImode);
13528   if (i >= 31)
13529     {
13530       emit_move_insn (operands[2], op1);
13531       op1 = operands[2];
13532     }
13533
13534   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13535   DONE;
13536 })
13537 \f
13538 ;; Store-flag instructions.
13539
13540 ;; For all sCOND expanders, also expand the compare or test insn that
13541 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13542
13543 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13544 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13545 ;; way, which can later delete the movzx if only QImode is needed.
13546
13547 (define_expand "seq"
13548   [(set (match_operand:QI 0 "register_operand" "")
13549         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13550   ""
13551   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13552
13553 (define_expand "sne"
13554   [(set (match_operand:QI 0 "register_operand" "")
13555         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13556   ""
13557   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13558
13559 (define_expand "sgt"
13560   [(set (match_operand:QI 0 "register_operand" "")
13561         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13562   ""
13563   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13564
13565 (define_expand "sgtu"
13566   [(set (match_operand:QI 0 "register_operand" "")
13567         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13568   ""
13569   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13570
13571 (define_expand "slt"
13572   [(set (match_operand:QI 0 "register_operand" "")
13573         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13574   ""
13575   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13576
13577 (define_expand "sltu"
13578   [(set (match_operand:QI 0 "register_operand" "")
13579         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13580   ""
13581   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13582
13583 (define_expand "sge"
13584   [(set (match_operand:QI 0 "register_operand" "")
13585         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13586   ""
13587   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13588
13589 (define_expand "sgeu"
13590   [(set (match_operand:QI 0 "register_operand" "")
13591         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13592   ""
13593   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13594
13595 (define_expand "sle"
13596   [(set (match_operand:QI 0 "register_operand" "")
13597         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13598   ""
13599   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13600
13601 (define_expand "sleu"
13602   [(set (match_operand:QI 0 "register_operand" "")
13603         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13604   ""
13605   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13606
13607 (define_expand "sunordered"
13608   [(set (match_operand:QI 0 "register_operand" "")
13609         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13610   "TARGET_80387 || TARGET_SSE"
13611   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13612
13613 (define_expand "sordered"
13614   [(set (match_operand:QI 0 "register_operand" "")
13615         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13616   "TARGET_80387"
13617   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13618
13619 (define_expand "suneq"
13620   [(set (match_operand:QI 0 "register_operand" "")
13621         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13622   "TARGET_80387 || TARGET_SSE"
13623   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13624
13625 (define_expand "sunge"
13626   [(set (match_operand:QI 0 "register_operand" "")
13627         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13628   "TARGET_80387 || TARGET_SSE"
13629   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13630
13631 (define_expand "sungt"
13632   [(set (match_operand:QI 0 "register_operand" "")
13633         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13634   "TARGET_80387 || TARGET_SSE"
13635   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13636
13637 (define_expand "sunle"
13638   [(set (match_operand:QI 0 "register_operand" "")
13639         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13640   "TARGET_80387 || TARGET_SSE"
13641   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13642
13643 (define_expand "sunlt"
13644   [(set (match_operand:QI 0 "register_operand" "")
13645         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13646   "TARGET_80387 || TARGET_SSE"
13647   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13648
13649 (define_expand "sltgt"
13650   [(set (match_operand:QI 0 "register_operand" "")
13651         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13652   "TARGET_80387 || TARGET_SSE"
13653   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13654
13655 (define_insn "*setcc_1"
13656   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13657         (match_operator:QI 1 "ix86_comparison_operator"
13658           [(reg FLAGS_REG) (const_int 0)]))]
13659   ""
13660   "set%C1\t%0"
13661   [(set_attr "type" "setcc")
13662    (set_attr "mode" "QI")])
13663
13664 (define_insn "*setcc_2"
13665   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13666         (match_operator:QI 1 "ix86_comparison_operator"
13667           [(reg FLAGS_REG) (const_int 0)]))]
13668   ""
13669   "set%C1\t%0"
13670   [(set_attr "type" "setcc")
13671    (set_attr "mode" "QI")])
13672
13673 ;; In general it is not safe to assume too much about CCmode registers,
13674 ;; so simplify-rtx stops when it sees a second one.  Under certain
13675 ;; conditions this is safe on x86, so help combine not create
13676 ;;
13677 ;;      seta    %al
13678 ;;      testb   %al, %al
13679 ;;      sete    %al
13680
13681 (define_split
13682   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13683         (ne:QI (match_operator 1 "ix86_comparison_operator"
13684                  [(reg FLAGS_REG) (const_int 0)])
13685             (const_int 0)))]
13686   ""
13687   [(set (match_dup 0) (match_dup 1))]
13688 {
13689   PUT_MODE (operands[1], QImode);
13690 })
13691
13692 (define_split
13693   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13694         (ne:QI (match_operator 1 "ix86_comparison_operator"
13695                  [(reg FLAGS_REG) (const_int 0)])
13696             (const_int 0)))]
13697   ""
13698   [(set (match_dup 0) (match_dup 1))]
13699 {
13700   PUT_MODE (operands[1], QImode);
13701 })
13702
13703 (define_split
13704   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13705         (eq:QI (match_operator 1 "ix86_comparison_operator"
13706                  [(reg FLAGS_REG) (const_int 0)])
13707             (const_int 0)))]
13708   ""
13709   [(set (match_dup 0) (match_dup 1))]
13710 {
13711   rtx new_op1 = copy_rtx (operands[1]);
13712   operands[1] = new_op1;
13713   PUT_MODE (new_op1, QImode);
13714   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13715                                              GET_MODE (XEXP (new_op1, 0))));
13716
13717   /* Make sure that (a) the CCmode we have for the flags is strong
13718      enough for the reversed compare or (b) we have a valid FP compare.  */
13719   if (! ix86_comparison_operator (new_op1, VOIDmode))
13720     FAIL;
13721 })
13722
13723 (define_split
13724   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13725         (eq:QI (match_operator 1 "ix86_comparison_operator"
13726                  [(reg FLAGS_REG) (const_int 0)])
13727             (const_int 0)))]
13728   ""
13729   [(set (match_dup 0) (match_dup 1))]
13730 {
13731   rtx new_op1 = copy_rtx (operands[1]);
13732   operands[1] = new_op1;
13733   PUT_MODE (new_op1, QImode);
13734   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13735                                              GET_MODE (XEXP (new_op1, 0))));
13736
13737   /* Make sure that (a) the CCmode we have for the flags is strong
13738      enough for the reversed compare or (b) we have a valid FP compare.  */
13739   if (! ix86_comparison_operator (new_op1, VOIDmode))
13740     FAIL;
13741 })
13742
13743 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13744 ;; subsequent logical operations are used to imitate conditional moves.
13745 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13746 ;; it directly.
13747
13748 (define_insn "*sse_setccsf"
13749   [(set (match_operand:SF 0 "register_operand" "=x")
13750         (match_operator:SF 1 "sse_comparison_operator"
13751           [(match_operand:SF 2 "register_operand" "0")
13752            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13753   "TARGET_SSE"
13754   "cmp%D1ss\t{%3, %0|%0, %3}"
13755   [(set_attr "type" "ssecmp")
13756    (set_attr "mode" "SF")])
13757
13758 (define_insn "*sse_setccdf"
13759   [(set (match_operand:DF 0 "register_operand" "=x")
13760         (match_operator:DF 1 "sse_comparison_operator"
13761           [(match_operand:DF 2 "register_operand" "0")
13762            (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
13763   "TARGET_SSE2"
13764   "cmp%D1sd\t{%3, %0|%0, %3}"
13765   [(set_attr "type" "ssecmp")
13766    (set_attr "mode" "DF")])
13767 \f
13768 ;; Basic conditional jump instructions.
13769 ;; We ignore the overflow flag for signed branch instructions.
13770
13771 ;; For all bCOND expanders, also expand the compare or test insn that
13772 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13773
13774 (define_expand "beq"
13775   [(set (pc)
13776         (if_then_else (match_dup 1)
13777                       (label_ref (match_operand 0 "" ""))
13778                       (pc)))]
13779   ""
13780   "ix86_expand_branch (EQ, operands[0]); DONE;")
13781
13782 (define_expand "bne"
13783   [(set (pc)
13784         (if_then_else (match_dup 1)
13785                       (label_ref (match_operand 0 "" ""))
13786                       (pc)))]
13787   ""
13788   "ix86_expand_branch (NE, operands[0]); DONE;")
13789
13790 (define_expand "bgt"
13791   [(set (pc)
13792         (if_then_else (match_dup 1)
13793                       (label_ref (match_operand 0 "" ""))
13794                       (pc)))]
13795   ""
13796   "ix86_expand_branch (GT, operands[0]); DONE;")
13797
13798 (define_expand "bgtu"
13799   [(set (pc)
13800         (if_then_else (match_dup 1)
13801                       (label_ref (match_operand 0 "" ""))
13802                       (pc)))]
13803   ""
13804   "ix86_expand_branch (GTU, operands[0]); DONE;")
13805
13806 (define_expand "blt"
13807   [(set (pc)
13808         (if_then_else (match_dup 1)
13809                       (label_ref (match_operand 0 "" ""))
13810                       (pc)))]
13811   ""
13812   "ix86_expand_branch (LT, operands[0]); DONE;")
13813
13814 (define_expand "bltu"
13815   [(set (pc)
13816         (if_then_else (match_dup 1)
13817                       (label_ref (match_operand 0 "" ""))
13818                       (pc)))]
13819   ""
13820   "ix86_expand_branch (LTU, operands[0]); DONE;")
13821
13822 (define_expand "bge"
13823   [(set (pc)
13824         (if_then_else (match_dup 1)
13825                       (label_ref (match_operand 0 "" ""))
13826                       (pc)))]
13827   ""
13828   "ix86_expand_branch (GE, operands[0]); DONE;")
13829
13830 (define_expand "bgeu"
13831   [(set (pc)
13832         (if_then_else (match_dup 1)
13833                       (label_ref (match_operand 0 "" ""))
13834                       (pc)))]
13835   ""
13836   "ix86_expand_branch (GEU, operands[0]); DONE;")
13837
13838 (define_expand "ble"
13839   [(set (pc)
13840         (if_then_else (match_dup 1)
13841                       (label_ref (match_operand 0 "" ""))
13842                       (pc)))]
13843   ""
13844   "ix86_expand_branch (LE, operands[0]); DONE;")
13845
13846 (define_expand "bleu"
13847   [(set (pc)
13848         (if_then_else (match_dup 1)
13849                       (label_ref (match_operand 0 "" ""))
13850                       (pc)))]
13851   ""
13852   "ix86_expand_branch (LEU, operands[0]); DONE;")
13853
13854 (define_expand "bunordered"
13855   [(set (pc)
13856         (if_then_else (match_dup 1)
13857                       (label_ref (match_operand 0 "" ""))
13858                       (pc)))]
13859   "TARGET_80387 || TARGET_SSE_MATH"
13860   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13861
13862 (define_expand "bordered"
13863   [(set (pc)
13864         (if_then_else (match_dup 1)
13865                       (label_ref (match_operand 0 "" ""))
13866                       (pc)))]
13867   "TARGET_80387 || TARGET_SSE_MATH"
13868   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13869
13870 (define_expand "buneq"
13871   [(set (pc)
13872         (if_then_else (match_dup 1)
13873                       (label_ref (match_operand 0 "" ""))
13874                       (pc)))]
13875   "TARGET_80387 || TARGET_SSE_MATH"
13876   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13877
13878 (define_expand "bunge"
13879   [(set (pc)
13880         (if_then_else (match_dup 1)
13881                       (label_ref (match_operand 0 "" ""))
13882                       (pc)))]
13883   "TARGET_80387 || TARGET_SSE_MATH"
13884   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13885
13886 (define_expand "bungt"
13887   [(set (pc)
13888         (if_then_else (match_dup 1)
13889                       (label_ref (match_operand 0 "" ""))
13890                       (pc)))]
13891   "TARGET_80387 || TARGET_SSE_MATH"
13892   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13893
13894 (define_expand "bunle"
13895   [(set (pc)
13896         (if_then_else (match_dup 1)
13897                       (label_ref (match_operand 0 "" ""))
13898                       (pc)))]
13899   "TARGET_80387 || TARGET_SSE_MATH"
13900   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13901
13902 (define_expand "bunlt"
13903   [(set (pc)
13904         (if_then_else (match_dup 1)
13905                       (label_ref (match_operand 0 "" ""))
13906                       (pc)))]
13907   "TARGET_80387 || TARGET_SSE_MATH"
13908   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13909
13910 (define_expand "bltgt"
13911   [(set (pc)
13912         (if_then_else (match_dup 1)
13913                       (label_ref (match_operand 0 "" ""))
13914                       (pc)))]
13915   "TARGET_80387 || TARGET_SSE_MATH"
13916   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13917
13918 (define_insn "*jcc_1"
13919   [(set (pc)
13920         (if_then_else (match_operator 1 "ix86_comparison_operator"
13921                                       [(reg FLAGS_REG) (const_int 0)])
13922                       (label_ref (match_operand 0 "" ""))
13923                       (pc)))]
13924   ""
13925   "%+j%C1\t%l0"
13926   [(set_attr "type" "ibr")
13927    (set_attr "modrm" "0")
13928    (set (attr "length")
13929            (if_then_else (and (ge (minus (match_dup 0) (pc))
13930                                   (const_int -126))
13931                               (lt (minus (match_dup 0) (pc))
13932                                   (const_int 128)))
13933              (const_int 2)
13934              (const_int 6)))])
13935
13936 (define_insn "*jcc_2"
13937   [(set (pc)
13938         (if_then_else (match_operator 1 "ix86_comparison_operator"
13939                                       [(reg FLAGS_REG) (const_int 0)])
13940                       (pc)
13941                       (label_ref (match_operand 0 "" ""))))]
13942   ""
13943   "%+j%c1\t%l0"
13944   [(set_attr "type" "ibr")
13945    (set_attr "modrm" "0")
13946    (set (attr "length")
13947            (if_then_else (and (ge (minus (match_dup 0) (pc))
13948                                   (const_int -126))
13949                               (lt (minus (match_dup 0) (pc))
13950                                   (const_int 128)))
13951              (const_int 2)
13952              (const_int 6)))])
13953
13954 ;; In general it is not safe to assume too much about CCmode registers,
13955 ;; so simplify-rtx stops when it sees a second one.  Under certain
13956 ;; conditions this is safe on x86, so help combine not create
13957 ;;
13958 ;;      seta    %al
13959 ;;      testb   %al, %al
13960 ;;      je      Lfoo
13961
13962 (define_split
13963   [(set (pc)
13964         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13965                                       [(reg FLAGS_REG) (const_int 0)])
13966                           (const_int 0))
13967                       (label_ref (match_operand 1 "" ""))
13968                       (pc)))]
13969   ""
13970   [(set (pc)
13971         (if_then_else (match_dup 0)
13972                       (label_ref (match_dup 1))
13973                       (pc)))]
13974 {
13975   PUT_MODE (operands[0], VOIDmode);
13976 })
13977
13978 (define_split
13979   [(set (pc)
13980         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13981                                       [(reg FLAGS_REG) (const_int 0)])
13982                           (const_int 0))
13983                       (label_ref (match_operand 1 "" ""))
13984                       (pc)))]
13985   ""
13986   [(set (pc)
13987         (if_then_else (match_dup 0)
13988                       (label_ref (match_dup 1))
13989                       (pc)))]
13990 {
13991   rtx new_op0 = copy_rtx (operands[0]);
13992   operands[0] = new_op0;
13993   PUT_MODE (new_op0, VOIDmode);
13994   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13995                                              GET_MODE (XEXP (new_op0, 0))));
13996
13997   /* Make sure that (a) the CCmode we have for the flags is strong
13998      enough for the reversed compare or (b) we have a valid FP compare.  */
13999   if (! ix86_comparison_operator (new_op0, VOIDmode))
14000     FAIL;
14001 })
14002
14003 ;; Define combination compare-and-branch fp compare instructions to use
14004 ;; during early optimization.  Splitting the operation apart early makes
14005 ;; for bad code when we want to reverse the operation.
14006
14007 (define_insn "*fp_jcc_1_mixed"
14008   [(set (pc)
14009         (if_then_else (match_operator 0 "comparison_operator"
14010                         [(match_operand 1 "register_operand" "f,x")
14011                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14012           (label_ref (match_operand 3 "" ""))
14013           (pc)))
14014    (clobber (reg:CCFP FPSR_REG))
14015    (clobber (reg:CCFP FLAGS_REG))]
14016   "TARGET_MIX_SSE_I387
14017    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14018    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14019    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14020   "#")
14021
14022 (define_insn "*fp_jcc_1_sse"
14023   [(set (pc)
14024         (if_then_else (match_operator 0 "comparison_operator"
14025                         [(match_operand 1 "register_operand" "x")
14026                          (match_operand 2 "nonimmediate_operand" "xm")])
14027           (label_ref (match_operand 3 "" ""))
14028           (pc)))
14029    (clobber (reg:CCFP FPSR_REG))
14030    (clobber (reg:CCFP FLAGS_REG))]
14031   "TARGET_SSE_MATH
14032    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14033    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14034    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14035   "#")
14036
14037 (define_insn "*fp_jcc_1_387"
14038   [(set (pc)
14039         (if_then_else (match_operator 0 "comparison_operator"
14040                         [(match_operand 1 "register_operand" "f")
14041                          (match_operand 2 "register_operand" "f")])
14042           (label_ref (match_operand 3 "" ""))
14043           (pc)))
14044    (clobber (reg:CCFP FPSR_REG))
14045    (clobber (reg:CCFP FLAGS_REG))]
14046   "TARGET_CMOVE && TARGET_80387
14047    && FLOAT_MODE_P (GET_MODE (operands[1]))
14048    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14049    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14050   "#")
14051
14052 (define_insn "*fp_jcc_2_mixed"
14053   [(set (pc)
14054         (if_then_else (match_operator 0 "comparison_operator"
14055                         [(match_operand 1 "register_operand" "f,x")
14056                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14057           (pc)
14058           (label_ref (match_operand 3 "" ""))))
14059    (clobber (reg:CCFP FPSR_REG))
14060    (clobber (reg:CCFP FLAGS_REG))]
14061   "TARGET_MIX_SSE_I387
14062    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14063    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14064    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14065   "#")
14066
14067 (define_insn "*fp_jcc_2_sse"
14068   [(set (pc)
14069         (if_then_else (match_operator 0 "comparison_operator"
14070                         [(match_operand 1 "register_operand" "x")
14071                          (match_operand 2 "nonimmediate_operand" "xm")])
14072           (pc)
14073           (label_ref (match_operand 3 "" ""))))
14074    (clobber (reg:CCFP FPSR_REG))
14075    (clobber (reg:CCFP FLAGS_REG))]
14076   "TARGET_SSE_MATH
14077    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14078    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14079    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14080   "#")
14081
14082 (define_insn "*fp_jcc_2_387"
14083   [(set (pc)
14084         (if_then_else (match_operator 0 "comparison_operator"
14085                         [(match_operand 1 "register_operand" "f")
14086                          (match_operand 2 "register_operand" "f")])
14087           (pc)
14088           (label_ref (match_operand 3 "" ""))))
14089    (clobber (reg:CCFP FPSR_REG))
14090    (clobber (reg:CCFP FLAGS_REG))]
14091   "TARGET_CMOVE && TARGET_80387
14092    && FLOAT_MODE_P (GET_MODE (operands[1]))
14093    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14094    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14095   "#")
14096
14097 (define_insn "*fp_jcc_3_387"
14098   [(set (pc)
14099         (if_then_else (match_operator 0 "comparison_operator"
14100                         [(match_operand 1 "register_operand" "f")
14101                          (match_operand 2 "nonimmediate_operand" "fm")])
14102           (label_ref (match_operand 3 "" ""))
14103           (pc)))
14104    (clobber (reg:CCFP FPSR_REG))
14105    (clobber (reg:CCFP FLAGS_REG))
14106    (clobber (match_scratch:HI 4 "=a"))]
14107   "TARGET_80387
14108    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14109    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14110    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14111    && SELECT_CC_MODE (GET_CODE (operands[0]),
14112                       operands[1], operands[2]) == CCFPmode
14113    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14114   "#")
14115
14116 (define_insn "*fp_jcc_4_387"
14117   [(set (pc)
14118         (if_then_else (match_operator 0 "comparison_operator"
14119                         [(match_operand 1 "register_operand" "f")
14120                          (match_operand 2 "nonimmediate_operand" "fm")])
14121           (pc)
14122           (label_ref (match_operand 3 "" ""))))
14123    (clobber (reg:CCFP FPSR_REG))
14124    (clobber (reg:CCFP FLAGS_REG))
14125    (clobber (match_scratch:HI 4 "=a"))]
14126   "TARGET_80387
14127    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14128    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14129    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14130    && SELECT_CC_MODE (GET_CODE (operands[0]),
14131                       operands[1], operands[2]) == CCFPmode
14132    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14133   "#")
14134
14135 (define_insn "*fp_jcc_5_387"
14136   [(set (pc)
14137         (if_then_else (match_operator 0 "comparison_operator"
14138                         [(match_operand 1 "register_operand" "f")
14139                          (match_operand 2 "register_operand" "f")])
14140           (label_ref (match_operand 3 "" ""))
14141           (pc)))
14142    (clobber (reg:CCFP FPSR_REG))
14143    (clobber (reg:CCFP FLAGS_REG))
14144    (clobber (match_scratch:HI 4 "=a"))]
14145   "TARGET_80387
14146    && FLOAT_MODE_P (GET_MODE (operands[1]))
14147    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14148    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14149   "#")
14150
14151 (define_insn "*fp_jcc_6_387"
14152   [(set (pc)
14153         (if_then_else (match_operator 0 "comparison_operator"
14154                         [(match_operand 1 "register_operand" "f")
14155                          (match_operand 2 "register_operand" "f")])
14156           (pc)
14157           (label_ref (match_operand 3 "" ""))))
14158    (clobber (reg:CCFP FPSR_REG))
14159    (clobber (reg:CCFP FLAGS_REG))
14160    (clobber (match_scratch:HI 4 "=a"))]
14161   "TARGET_80387
14162    && FLOAT_MODE_P (GET_MODE (operands[1]))
14163    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14164    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14165   "#")
14166
14167 (define_insn "*fp_jcc_7_387"
14168   [(set (pc)
14169         (if_then_else (match_operator 0 "comparison_operator"
14170                         [(match_operand 1 "register_operand" "f")
14171                          (match_operand 2 "const0_operand" "X")])
14172           (label_ref (match_operand 3 "" ""))
14173           (pc)))
14174    (clobber (reg:CCFP FPSR_REG))
14175    (clobber (reg:CCFP FLAGS_REG))
14176    (clobber (match_scratch:HI 4 "=a"))]
14177   "TARGET_80387
14178    && FLOAT_MODE_P (GET_MODE (operands[1]))
14179    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14180    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14181    && SELECT_CC_MODE (GET_CODE (operands[0]),
14182                       operands[1], operands[2]) == CCFPmode
14183    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14184   "#")
14185
14186 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14187 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14188 ;; with a precedence over other operators and is always put in the first
14189 ;; place. Swap condition and operands to match ficom instruction.
14190
14191 (define_insn "*fp_jcc_8<mode>_387"
14192   [(set (pc)
14193         (if_then_else (match_operator 0 "comparison_operator"
14194                         [(match_operator 1 "float_operator"
14195                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14196                            (match_operand 3 "register_operand" "f,f")])
14197           (label_ref (match_operand 4 "" ""))
14198           (pc)))
14199    (clobber (reg:CCFP FPSR_REG))
14200    (clobber (reg:CCFP FLAGS_REG))
14201    (clobber (match_scratch:HI 5 "=a,a"))]
14202   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14203    && FLOAT_MODE_P (GET_MODE (operands[3]))
14204    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14205    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14206    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14207    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14208   "#")
14209
14210 (define_split
14211   [(set (pc)
14212         (if_then_else (match_operator 0 "comparison_operator"
14213                         [(match_operand 1 "register_operand" "")
14214                          (match_operand 2 "nonimmediate_operand" "")])
14215           (match_operand 3 "" "")
14216           (match_operand 4 "" "")))
14217    (clobber (reg:CCFP FPSR_REG))
14218    (clobber (reg:CCFP FLAGS_REG))]
14219   "reload_completed"
14220   [(const_int 0)]
14221 {
14222   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14223                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14224   DONE;
14225 })
14226
14227 (define_split
14228   [(set (pc)
14229         (if_then_else (match_operator 0 "comparison_operator"
14230                         [(match_operand 1 "register_operand" "")
14231                          (match_operand 2 "general_operand" "")])
14232           (match_operand 3 "" "")
14233           (match_operand 4 "" "")))
14234    (clobber (reg:CCFP FPSR_REG))
14235    (clobber (reg:CCFP FLAGS_REG))
14236    (clobber (match_scratch:HI 5 "=a"))]
14237   "reload_completed"
14238   [(const_int 0)]
14239 {
14240   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14241                         operands[3], operands[4], operands[5], NULL_RTX);
14242   DONE;
14243 })
14244
14245 (define_split
14246   [(set (pc)
14247         (if_then_else (match_operator 0 "comparison_operator"
14248                         [(match_operator 1 "float_operator"
14249                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14250                            (match_operand 3 "register_operand" "")])
14251           (match_operand 4 "" "")
14252           (match_operand 5 "" "")))
14253    (clobber (reg:CCFP FPSR_REG))
14254    (clobber (reg:CCFP FLAGS_REG))
14255    (clobber (match_scratch:HI 6 "=a"))]
14256   "reload_completed"
14257   [(const_int 0)]
14258 {
14259   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14260   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14261                         operands[3], operands[7],
14262                         operands[4], operands[5], operands[6], NULL_RTX);
14263   DONE;
14264 })
14265
14266 ;; %%% Kill this when reload knows how to do it.
14267 (define_split
14268   [(set (pc)
14269         (if_then_else (match_operator 0 "comparison_operator"
14270                         [(match_operator 1 "float_operator"
14271                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14272                            (match_operand 3 "register_operand" "")])
14273           (match_operand 4 "" "")
14274           (match_operand 5 "" "")))
14275    (clobber (reg:CCFP FPSR_REG))
14276    (clobber (reg:CCFP FLAGS_REG))
14277    (clobber (match_scratch:HI 6 "=a"))]
14278   "reload_completed"
14279   [(const_int 0)]
14280 {
14281   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14282   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14283   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14284                         operands[3], operands[7],
14285                         operands[4], operands[5], operands[6], operands[2]);
14286   DONE;
14287 })
14288 \f
14289 ;; Unconditional and other jump instructions
14290
14291 (define_insn "jump"
14292   [(set (pc)
14293         (label_ref (match_operand 0 "" "")))]
14294   ""
14295   "jmp\t%l0"
14296   [(set_attr "type" "ibr")
14297    (set (attr "length")
14298            (if_then_else (and (ge (minus (match_dup 0) (pc))
14299                                   (const_int -126))
14300                               (lt (minus (match_dup 0) (pc))
14301                                   (const_int 128)))
14302              (const_int 2)
14303              (const_int 5)))
14304    (set_attr "modrm" "0")])
14305
14306 (define_expand "indirect_jump"
14307   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
14308   ""
14309   "")
14310
14311 (define_insn "*indirect_jump"
14312   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14313   "!TARGET_64BIT"
14314   "jmp\t%A0"
14315   [(set_attr "type" "ibr")
14316    (set_attr "length_immediate" "0")])
14317
14318 (define_insn "*indirect_jump_rtx64"
14319   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14320   "TARGET_64BIT"
14321   "jmp\t%A0"
14322   [(set_attr "type" "ibr")
14323    (set_attr "length_immediate" "0")])
14324
14325 (define_expand "tablejump"
14326   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14327               (use (label_ref (match_operand 1 "" "")))])]
14328   ""
14329 {
14330   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14331      relative.  Convert the relative address to an absolute address.  */
14332   if (flag_pic)
14333     {
14334       rtx op0, op1;
14335       enum rtx_code code;
14336
14337       if (TARGET_64BIT)
14338         {
14339           code = PLUS;
14340           op0 = operands[0];
14341           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14342         }
14343       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14344         {
14345           code = PLUS;
14346           op0 = operands[0];
14347           op1 = pic_offset_table_rtx;
14348         }
14349       else
14350         {
14351           code = MINUS;
14352           op0 = pic_offset_table_rtx;
14353           op1 = operands[0];
14354         }
14355
14356       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14357                                          OPTAB_DIRECT);
14358     }
14359 })
14360
14361 (define_insn "*tablejump_1"
14362   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14363    (use (label_ref (match_operand 1 "" "")))]
14364   "!TARGET_64BIT"
14365   "jmp\t%A0"
14366   [(set_attr "type" "ibr")
14367    (set_attr "length_immediate" "0")])
14368
14369 (define_insn "*tablejump_1_rtx64"
14370   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14371    (use (label_ref (match_operand 1 "" "")))]
14372   "TARGET_64BIT"
14373   "jmp\t%A0"
14374   [(set_attr "type" "ibr")
14375    (set_attr "length_immediate" "0")])
14376 \f
14377 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14378
14379 (define_peephole2
14380   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14381    (set (match_operand:QI 1 "register_operand" "")
14382         (match_operator:QI 2 "ix86_comparison_operator"
14383           [(reg FLAGS_REG) (const_int 0)]))
14384    (set (match_operand 3 "q_regs_operand" "")
14385         (zero_extend (match_dup 1)))]
14386   "(peep2_reg_dead_p (3, operands[1])
14387     || operands_match_p (operands[1], operands[3]))
14388    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14389   [(set (match_dup 4) (match_dup 0))
14390    (set (strict_low_part (match_dup 5))
14391         (match_dup 2))]
14392 {
14393   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14394   operands[5] = gen_lowpart (QImode, operands[3]);
14395   ix86_expand_clear (operands[3]);
14396 })
14397
14398 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14399
14400 (define_peephole2
14401   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14402    (set (match_operand:QI 1 "register_operand" "")
14403         (match_operator:QI 2 "ix86_comparison_operator"
14404           [(reg FLAGS_REG) (const_int 0)]))
14405    (parallel [(set (match_operand 3 "q_regs_operand" "")
14406                    (zero_extend (match_dup 1)))
14407               (clobber (reg:CC FLAGS_REG))])]
14408   "(peep2_reg_dead_p (3, operands[1])
14409     || operands_match_p (operands[1], operands[3]))
14410    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14411   [(set (match_dup 4) (match_dup 0))
14412    (set (strict_low_part (match_dup 5))
14413         (match_dup 2))]
14414 {
14415   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14416   operands[5] = gen_lowpart (QImode, operands[3]);
14417   ix86_expand_clear (operands[3]);
14418 })
14419 \f
14420 ;; Call instructions.
14421
14422 ;; The predicates normally associated with named expanders are not properly
14423 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14424 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14425
14426 ;; Call subroutine returning no value.
14427
14428 (define_expand "call_pop"
14429   [(parallel [(call (match_operand:QI 0 "" "")
14430                     (match_operand:SI 1 "" ""))
14431               (set (reg:SI SP_REG)
14432                    (plus:SI (reg:SI SP_REG)
14433                             (match_operand:SI 3 "" "")))])]
14434   "!TARGET_64BIT"
14435 {
14436   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14437   DONE;
14438 })
14439
14440 (define_insn "*call_pop_0"
14441   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14442          (match_operand:SI 1 "" ""))
14443    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14444                             (match_operand:SI 2 "immediate_operand" "")))]
14445   "!TARGET_64BIT"
14446 {
14447   if (SIBLING_CALL_P (insn))
14448     return "jmp\t%P0";
14449   else
14450     return "call\t%P0";
14451 }
14452   [(set_attr "type" "call")])
14453
14454 (define_insn "*call_pop_1"
14455   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14456          (match_operand:SI 1 "" ""))
14457    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14458                             (match_operand:SI 2 "immediate_operand" "i")))]
14459   "!TARGET_64BIT"
14460 {
14461   if (constant_call_address_operand (operands[0], Pmode))
14462     {
14463       if (SIBLING_CALL_P (insn))
14464         return "jmp\t%P0";
14465       else
14466         return "call\t%P0";
14467     }
14468   if (SIBLING_CALL_P (insn))
14469     return "jmp\t%A0";
14470   else
14471     return "call\t%A0";
14472 }
14473   [(set_attr "type" "call")])
14474
14475 (define_expand "call"
14476   [(call (match_operand:QI 0 "" "")
14477          (match_operand 1 "" ""))
14478    (use (match_operand 2 "" ""))]
14479   ""
14480 {
14481   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14482   DONE;
14483 })
14484
14485 (define_expand "sibcall"
14486   [(call (match_operand:QI 0 "" "")
14487          (match_operand 1 "" ""))
14488    (use (match_operand 2 "" ""))]
14489   ""
14490 {
14491   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14492   DONE;
14493 })
14494
14495 (define_insn "*call_0"
14496   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14497          (match_operand 1 "" ""))]
14498   ""
14499 {
14500   if (SIBLING_CALL_P (insn))
14501     return "jmp\t%P0";
14502   else
14503     return "call\t%P0";
14504 }
14505   [(set_attr "type" "call")])
14506
14507 (define_insn "*call_1"
14508   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14509          (match_operand 1 "" ""))]
14510   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14511 {
14512   if (constant_call_address_operand (operands[0], Pmode))
14513     return "call\t%P0";
14514   return "call\t%A0";
14515 }
14516   [(set_attr "type" "call")])
14517
14518 (define_insn "*sibcall_1"
14519   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14520          (match_operand 1 "" ""))]
14521   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14522 {
14523   if (constant_call_address_operand (operands[0], Pmode))
14524     return "jmp\t%P0";
14525   return "jmp\t%A0";
14526 }
14527   [(set_attr "type" "call")])
14528
14529 (define_insn "*call_1_rex64"
14530   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14531          (match_operand 1 "" ""))]
14532   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14533 {
14534   if (constant_call_address_operand (operands[0], Pmode))
14535     return "call\t%P0";
14536   return "call\t%A0";
14537 }
14538   [(set_attr "type" "call")])
14539
14540 (define_insn "*sibcall_1_rex64"
14541   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14542          (match_operand 1 "" ""))]
14543   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14544   "jmp\t%P0"
14545   [(set_attr "type" "call")])
14546
14547 (define_insn "*sibcall_1_rex64_v"
14548   [(call (mem:QI (reg:DI R11_REG))
14549          (match_operand 0 "" ""))]
14550   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14551   "jmp\t*%%r11"
14552   [(set_attr "type" "call")])
14553
14554
14555 ;; Call subroutine, returning value in operand 0
14556
14557 (define_expand "call_value_pop"
14558   [(parallel [(set (match_operand 0 "" "")
14559                    (call (match_operand:QI 1 "" "")
14560                          (match_operand:SI 2 "" "")))
14561               (set (reg:SI SP_REG)
14562                    (plus:SI (reg:SI SP_REG)
14563                             (match_operand:SI 4 "" "")))])]
14564   "!TARGET_64BIT"
14565 {
14566   ix86_expand_call (operands[0], operands[1], operands[2],
14567                     operands[3], operands[4], 0);
14568   DONE;
14569 })
14570
14571 (define_expand "call_value"
14572   [(set (match_operand 0 "" "")
14573         (call (match_operand:QI 1 "" "")
14574               (match_operand:SI 2 "" "")))
14575    (use (match_operand:SI 3 "" ""))]
14576   ;; Operand 2 not used on the i386.
14577   ""
14578 {
14579   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14580   DONE;
14581 })
14582
14583 (define_expand "sibcall_value"
14584   [(set (match_operand 0 "" "")
14585         (call (match_operand:QI 1 "" "")
14586               (match_operand:SI 2 "" "")))
14587    (use (match_operand:SI 3 "" ""))]
14588   ;; Operand 2 not used on the i386.
14589   ""
14590 {
14591   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14592   DONE;
14593 })
14594
14595 ;; Call subroutine returning any type.
14596
14597 (define_expand "untyped_call"
14598   [(parallel [(call (match_operand 0 "" "")
14599                     (const_int 0))
14600               (match_operand 1 "" "")
14601               (match_operand 2 "" "")])]
14602   ""
14603 {
14604   int i;
14605
14606   /* In order to give reg-stack an easier job in validating two
14607      coprocessor registers as containing a possible return value,
14608      simply pretend the untyped call returns a complex long double
14609      value.  */
14610
14611   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14612                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14613                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14614                     NULL, 0);
14615
14616   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14617     {
14618       rtx set = XVECEXP (operands[2], 0, i);
14619       emit_move_insn (SET_DEST (set), SET_SRC (set));
14620     }
14621
14622   /* The optimizer does not know that the call sets the function value
14623      registers we stored in the result block.  We avoid problems by
14624      claiming that all hard registers are used and clobbered at this
14625      point.  */
14626   emit_insn (gen_blockage (const0_rtx));
14627
14628   DONE;
14629 })
14630 \f
14631 ;; Prologue and epilogue instructions
14632
14633 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14634 ;; all of memory.  This blocks insns from being moved across this point.
14635
14636 (define_insn "blockage"
14637   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14638   ""
14639   ""
14640   [(set_attr "length" "0")])
14641
14642 ;; Insn emitted into the body of a function to return from a function.
14643 ;; This is only done if the function's epilogue is known to be simple.
14644 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14645
14646 (define_expand "return"
14647   [(return)]
14648   "ix86_can_use_return_insn_p ()"
14649 {
14650   if (current_function_pops_args)
14651     {
14652       rtx popc = GEN_INT (current_function_pops_args);
14653       emit_jump_insn (gen_return_pop_internal (popc));
14654       DONE;
14655     }
14656 })
14657
14658 (define_insn "return_internal"
14659   [(return)]
14660   "reload_completed"
14661   "ret"
14662   [(set_attr "length" "1")
14663    (set_attr "length_immediate" "0")
14664    (set_attr "modrm" "0")])
14665
14666 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14667 ;; instruction Athlon and K8 have.
14668
14669 (define_insn "return_internal_long"
14670   [(return)
14671    (unspec [(const_int 0)] UNSPEC_REP)]
14672   "reload_completed"
14673   "rep {;} ret"
14674   [(set_attr "length" "1")
14675    (set_attr "length_immediate" "0")
14676    (set_attr "prefix_rep" "1")
14677    (set_attr "modrm" "0")])
14678
14679 (define_insn "return_pop_internal"
14680   [(return)
14681    (use (match_operand:SI 0 "const_int_operand" ""))]
14682   "reload_completed"
14683   "ret\t%0"
14684   [(set_attr "length" "3")
14685    (set_attr "length_immediate" "2")
14686    (set_attr "modrm" "0")])
14687
14688 (define_insn "return_indirect_internal"
14689   [(return)
14690    (use (match_operand:SI 0 "register_operand" "r"))]
14691   "reload_completed"
14692   "jmp\t%A0"
14693   [(set_attr "type" "ibr")
14694    (set_attr "length_immediate" "0")])
14695
14696 (define_insn "nop"
14697   [(const_int 0)]
14698   ""
14699   "nop"
14700   [(set_attr "length" "1")
14701    (set_attr "length_immediate" "0")
14702    (set_attr "modrm" "0")])
14703
14704 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14705 ;; branch prediction penalty for the third jump in a 16-byte
14706 ;; block on K8.
14707
14708 (define_insn "align"
14709   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14710   ""
14711 {
14712 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14713   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14714 #else
14715   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14716      The align insn is used to avoid 3 jump instructions in the row to improve
14717      branch prediction and the benefits hardly outweigh the cost of extra 8
14718      nops on the average inserted by full alignment pseudo operation.  */
14719 #endif
14720   return "";
14721 }
14722   [(set_attr "length" "16")])
14723
14724 (define_expand "prologue"
14725   [(const_int 1)]
14726   ""
14727   "ix86_expand_prologue (); DONE;")
14728
14729 (define_insn "set_got"
14730   [(set (match_operand:SI 0 "register_operand" "=r")
14731         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14732    (clobber (reg:CC FLAGS_REG))]
14733   "!TARGET_64BIT"
14734   { return output_set_got (operands[0], NULL_RTX); }
14735   [(set_attr "type" "multi")
14736    (set_attr "length" "12")])
14737
14738 (define_insn "set_got_labelled"
14739   [(set (match_operand:SI 0 "register_operand" "=r")
14740         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14741          UNSPEC_SET_GOT))
14742    (clobber (reg:CC FLAGS_REG))]
14743   "!TARGET_64BIT"
14744   { return output_set_got (operands[0], operands[1]); }
14745   [(set_attr "type" "multi")
14746    (set_attr "length" "12")])
14747
14748 (define_insn "set_got_rex64"
14749   [(set (match_operand:DI 0 "register_operand" "=r")
14750         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14751   "TARGET_64BIT"
14752   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14753   [(set_attr "type" "lea")
14754    (set_attr "length" "6")])
14755
14756 (define_expand "epilogue"
14757   [(const_int 1)]
14758   ""
14759   "ix86_expand_epilogue (1); DONE;")
14760
14761 (define_expand "sibcall_epilogue"
14762   [(const_int 1)]
14763   ""
14764   "ix86_expand_epilogue (0); DONE;")
14765
14766 (define_expand "eh_return"
14767   [(use (match_operand 0 "register_operand" ""))]
14768   ""
14769 {
14770   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14771
14772   /* Tricky bit: we write the address of the handler to which we will
14773      be returning into someone else's stack frame, one word below the
14774      stack address we wish to restore.  */
14775   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14776   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14777   tmp = gen_rtx_MEM (Pmode, tmp);
14778   emit_move_insn (tmp, ra);
14779
14780   if (Pmode == SImode)
14781     emit_jump_insn (gen_eh_return_si (sa));
14782   else
14783     emit_jump_insn (gen_eh_return_di (sa));
14784   emit_barrier ();
14785   DONE;
14786 })
14787
14788 (define_insn_and_split "eh_return_si"
14789   [(set (pc)
14790         (unspec [(match_operand:SI 0 "register_operand" "c")]
14791                  UNSPEC_EH_RETURN))]
14792   "!TARGET_64BIT"
14793   "#"
14794   "reload_completed"
14795   [(const_int 1)]
14796   "ix86_expand_epilogue (2); DONE;")
14797
14798 (define_insn_and_split "eh_return_di"
14799   [(set (pc)
14800         (unspec [(match_operand:DI 0 "register_operand" "c")]
14801                  UNSPEC_EH_RETURN))]
14802   "TARGET_64BIT"
14803   "#"
14804   "reload_completed"
14805   [(const_int 1)]
14806   "ix86_expand_epilogue (2); DONE;")
14807
14808 (define_insn "leave"
14809   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14810    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14811    (clobber (mem:BLK (scratch)))]
14812   "!TARGET_64BIT"
14813   "leave"
14814   [(set_attr "type" "leave")])
14815
14816 (define_insn "leave_rex64"
14817   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14818    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14819    (clobber (mem:BLK (scratch)))]
14820   "TARGET_64BIT"
14821   "leave"
14822   [(set_attr "type" "leave")])
14823 \f
14824 (define_expand "ffssi2"
14825   [(parallel
14826      [(set (match_operand:SI 0 "register_operand" "")
14827            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14828       (clobber (match_scratch:SI 2 ""))
14829       (clobber (reg:CC FLAGS_REG))])]
14830   ""
14831   "")
14832
14833 (define_insn_and_split "*ffs_cmove"
14834   [(set (match_operand:SI 0 "register_operand" "=r")
14835         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14836    (clobber (match_scratch:SI 2 "=&r"))
14837    (clobber (reg:CC FLAGS_REG))]
14838   "TARGET_CMOVE"
14839   "#"
14840   "&& reload_completed"
14841   [(set (match_dup 2) (const_int -1))
14842    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14843               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14844    (set (match_dup 0) (if_then_else:SI
14845                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14846                         (match_dup 2)
14847                         (match_dup 0)))
14848    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14849               (clobber (reg:CC FLAGS_REG))])]
14850   "")
14851
14852 (define_insn_and_split "*ffs_no_cmove"
14853   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14854         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14855    (clobber (match_scratch:SI 2 "=&q"))
14856    (clobber (reg:CC FLAGS_REG))]
14857   ""
14858   "#"
14859   "reload_completed"
14860   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14861               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14862    (set (strict_low_part (match_dup 3))
14863         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14864    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14865               (clobber (reg:CC FLAGS_REG))])
14866    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14867               (clobber (reg:CC FLAGS_REG))])
14868    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14869               (clobber (reg:CC FLAGS_REG))])]
14870 {
14871   operands[3] = gen_lowpart (QImode, operands[2]);
14872   ix86_expand_clear (operands[2]);
14873 })
14874
14875 (define_insn "*ffssi_1"
14876   [(set (reg:CCZ FLAGS_REG)
14877         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14878                      (const_int 0)))
14879    (set (match_operand:SI 0 "register_operand" "=r")
14880         (ctz:SI (match_dup 1)))]
14881   ""
14882   "bsf{l}\t{%1, %0|%0, %1}"
14883   [(set_attr "prefix_0f" "1")])
14884
14885 (define_expand "ffsdi2"
14886   [(parallel
14887      [(set (match_operand:DI 0 "register_operand" "")
14888            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14889       (clobber (match_scratch:DI 2 ""))
14890       (clobber (reg:CC FLAGS_REG))])]
14891   "TARGET_64BIT && TARGET_CMOVE"
14892   "")
14893
14894 (define_insn_and_split "*ffs_rex64"
14895   [(set (match_operand:DI 0 "register_operand" "=r")
14896         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14897    (clobber (match_scratch:DI 2 "=&r"))
14898    (clobber (reg:CC FLAGS_REG))]
14899   "TARGET_64BIT && TARGET_CMOVE"
14900   "#"
14901   "&& reload_completed"
14902   [(set (match_dup 2) (const_int -1))
14903    (parallel [(set (reg:CCZ FLAGS_REG)
14904                    (compare:CCZ (match_dup 1) (const_int 0)))
14905               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14906    (set (match_dup 0) (if_then_else:DI
14907                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14908                         (match_dup 2)
14909                         (match_dup 0)))
14910    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14911               (clobber (reg:CC FLAGS_REG))])]
14912   "")
14913
14914 (define_insn "*ffsdi_1"
14915   [(set (reg:CCZ FLAGS_REG)
14916         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14917                      (const_int 0)))
14918    (set (match_operand:DI 0 "register_operand" "=r")
14919         (ctz:DI (match_dup 1)))]
14920   "TARGET_64BIT"
14921   "bsf{q}\t{%1, %0|%0, %1}"
14922   [(set_attr "prefix_0f" "1")])
14923
14924 (define_insn "ctzsi2"
14925   [(set (match_operand:SI 0 "register_operand" "=r")
14926         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14927    (clobber (reg:CC FLAGS_REG))]
14928   ""
14929   "bsf{l}\t{%1, %0|%0, %1}"
14930   [(set_attr "prefix_0f" "1")])
14931
14932 (define_insn "ctzdi2"
14933   [(set (match_operand:DI 0 "register_operand" "=r")
14934         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14935    (clobber (reg:CC FLAGS_REG))]
14936   "TARGET_64BIT"
14937   "bsf{q}\t{%1, %0|%0, %1}"
14938   [(set_attr "prefix_0f" "1")])
14939
14940 (define_expand "clzsi2"
14941   [(parallel
14942      [(set (match_operand:SI 0 "register_operand" "")
14943            (minus:SI (const_int 31)
14944                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14945       (clobber (reg:CC FLAGS_REG))])
14946    (parallel
14947      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14948       (clobber (reg:CC FLAGS_REG))])]
14949   ""
14950 {
14951   if (TARGET_ABM)
14952     {
14953       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14954       DONE;
14955     }
14956 })
14957
14958 (define_insn "clzsi2_abm"
14959   [(set (match_operand:SI 0 "register_operand" "=r")
14960         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14961    (clobber (reg:CC FLAGS_REG))]
14962   "TARGET_ABM"
14963   "lzcnt{l}\t{%1, %0|%0, %1}"
14964   [(set_attr "prefix_rep" "1")
14965    (set_attr "type" "bitmanip")
14966    (set_attr "mode" "SI")])
14967
14968 (define_insn "*bsr"
14969   [(set (match_operand:SI 0 "register_operand" "=r")
14970         (minus:SI (const_int 31)
14971                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14972    (clobber (reg:CC FLAGS_REG))]
14973   ""
14974   "bsr{l}\t{%1, %0|%0, %1}"
14975   [(set_attr "prefix_0f" "1")
14976    (set_attr "mode" "SI")])
14977
14978 (define_insn "popcountsi2"
14979   [(set (match_operand:SI 0 "register_operand" "=r")
14980         (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14981    (clobber (reg:CC FLAGS_REG))]
14982   "TARGET_POPCNT"
14983   "popcnt{l}\t{%1, %0|%0, %1}"
14984   [(set_attr "prefix_rep" "1")
14985    (set_attr "type" "bitmanip")
14986    (set_attr "mode" "SI")])
14987
14988 (define_insn "*popcountsi2_cmp"
14989   [(set (reg FLAGS_REG)
14990         (compare
14991           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14992           (const_int 0)))
14993    (set (match_operand:SI 0 "register_operand" "=r")
14994         (popcount:SI (match_dup 1)))]
14995   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14996   "popcnt{l}\t{%1, %0|%0, %1}"
14997   [(set_attr "prefix_rep" "1")
14998    (set_attr "type" "bitmanip")
14999    (set_attr "mode" "SI")])
15000
15001 (define_insn "*popcountsi2_cmp_zext"
15002   [(set (reg FLAGS_REG)
15003         (compare
15004           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15005           (const_int 0)))
15006    (set (match_operand:DI 0 "register_operand" "=r")
15007         (zero_extend:DI(popcount:SI (match_dup 1))))]
15008   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15009   "popcnt{l}\t{%1, %0|%0, %1}"
15010   [(set_attr "prefix_rep" "1")
15011    (set_attr "type" "bitmanip")
15012    (set_attr "mode" "SI")])
15013
15014 (define_expand "bswapsi2"
15015   [(set (match_operand:SI 0 "register_operand" "")
15016         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15017   ""
15018 {
15019   if (!TARGET_BSWAP)
15020     {
15021       rtx x = operands[0];
15022
15023       emit_move_insn (x, operands[1]);
15024       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15025       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15026       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15027       DONE;
15028     }
15029 })
15030
15031 (define_insn "*bswapsi_1"
15032   [(set (match_operand:SI 0 "register_operand" "=r")
15033         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15034   "TARGET_BSWAP"
15035   "bswap\t%0"
15036   [(set_attr "prefix_0f" "1")
15037    (set_attr "length" "2")])
15038
15039 (define_insn "*bswaphi_lowpart_1"
15040   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15041         (bswap:HI (match_dup 0)))
15042    (clobber (reg:CC FLAGS_REG))]
15043   "TARGET_USE_XCHGB || optimize_size"
15044   "@
15045     xchg{b}\t{%h0, %b0|%b0, %h0}
15046     rol{w}\t{$8, %0|%0, 8}"
15047   [(set_attr "length" "2,4")
15048    (set_attr "mode" "QI,HI")])
15049
15050 (define_insn "bswaphi_lowpart"
15051   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15052         (bswap:HI (match_dup 0)))
15053    (clobber (reg:CC FLAGS_REG))]
15054   ""
15055   "rol{w}\t{$8, %0|%0, 8}"
15056   [(set_attr "length" "4")
15057    (set_attr "mode" "HI")])
15058
15059 (define_insn "bswapdi2"
15060   [(set (match_operand:DI 0 "register_operand" "=r")
15061         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15062   "TARGET_64BIT"
15063   "bswap\t%0"
15064   [(set_attr "prefix_0f" "1")
15065    (set_attr "length" "3")])
15066
15067 (define_expand "clzdi2"
15068   [(parallel
15069      [(set (match_operand:DI 0 "register_operand" "")
15070            (minus:DI (const_int 63)
15071                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15072       (clobber (reg:CC FLAGS_REG))])
15073    (parallel
15074      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15075       (clobber (reg:CC FLAGS_REG))])]
15076   "TARGET_64BIT"
15077 {
15078   if (TARGET_ABM)
15079     {
15080       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15081       DONE;
15082     }
15083 })
15084
15085 (define_insn "clzdi2_abm"
15086   [(set (match_operand:DI 0 "register_operand" "=r")
15087         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15088    (clobber (reg:CC FLAGS_REG))]
15089   "TARGET_64BIT && TARGET_ABM"
15090   "lzcnt{q}\t{%1, %0|%0, %1}"
15091   [(set_attr "prefix_rep" "1")
15092    (set_attr "type" "bitmanip")
15093    (set_attr "mode" "DI")])
15094
15095 (define_insn "*bsr_rex64"
15096   [(set (match_operand:DI 0 "register_operand" "=r")
15097         (minus:DI (const_int 63)
15098                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15099    (clobber (reg:CC FLAGS_REG))]
15100   "TARGET_64BIT"
15101   "bsr{q}\t{%1, %0|%0, %1}"
15102   [(set_attr "prefix_0f" "1")
15103    (set_attr "mode" "DI")])
15104
15105 (define_insn "popcountdi2"
15106   [(set (match_operand:DI 0 "register_operand" "=r")
15107         (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15108    (clobber (reg:CC FLAGS_REG))]
15109   "TARGET_64BIT && TARGET_POPCNT"
15110   "popcnt{q}\t{%1, %0|%0, %1}"
15111   [(set_attr "prefix_rep" "1")
15112    (set_attr "type" "bitmanip")
15113    (set_attr "mode" "DI")])
15114
15115 (define_insn "*popcountdi2_cmp"
15116   [(set (reg FLAGS_REG)
15117         (compare
15118           (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15119           (const_int 0)))
15120    (set (match_operand:DI 0 "register_operand" "=r")
15121         (popcount:DI (match_dup 1)))]
15122   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15123   "popcnt{q}\t{%1, %0|%0, %1}"
15124   [(set_attr "prefix_rep" "1")
15125    (set_attr "type" "bitmanip")
15126    (set_attr "mode" "DI")])
15127
15128 (define_expand "clzhi2"
15129   [(parallel
15130      [(set (match_operand:HI 0 "register_operand" "")
15131            (minus:HI (const_int 15)
15132                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15133       (clobber (reg:CC FLAGS_REG))])
15134    (parallel
15135      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15136       (clobber (reg:CC FLAGS_REG))])]
15137   ""
15138 {
15139   if (TARGET_ABM)
15140     {
15141       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15142       DONE;
15143     }
15144 })
15145
15146 (define_insn "clzhi2_abm"
15147   [(set (match_operand:HI 0 "register_operand" "=r")
15148         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15149    (clobber (reg:CC FLAGS_REG))]
15150   "TARGET_ABM"
15151   "lzcnt{w}\t{%1, %0|%0, %1}"
15152   [(set_attr "prefix_rep" "1")
15153    (set_attr "type" "bitmanip")
15154    (set_attr "mode" "HI")])
15155
15156 (define_insn "*bsrhi"
15157   [(set (match_operand:HI 0 "register_operand" "=r")
15158         (minus:HI (const_int 15)
15159                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15160    (clobber (reg:CC FLAGS_REG))]
15161   ""
15162   "bsr{w}\t{%1, %0|%0, %1}"
15163   [(set_attr "prefix_0f" "1")
15164    (set_attr "mode" "HI")])
15165
15166 (define_insn "popcounthi2"
15167   [(set (match_operand:HI 0 "register_operand" "=r")
15168         (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15169    (clobber (reg:CC FLAGS_REG))]
15170   "TARGET_POPCNT"
15171   "popcnt{w}\t{%1, %0|%0, %1}"
15172   [(set_attr "prefix_rep" "1")
15173    (set_attr "type" "bitmanip")
15174    (set_attr "mode" "HI")])
15175
15176 (define_insn "*popcounthi2_cmp"
15177   [(set (reg FLAGS_REG)
15178         (compare
15179           (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15180           (const_int 0)))
15181    (set (match_operand:HI 0 "register_operand" "=r")
15182         (popcount:HI (match_dup 1)))]
15183   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15184   "popcnt{w}\t{%1, %0|%0, %1}"
15185   [(set_attr "prefix_rep" "1")
15186    (set_attr "type" "bitmanip")
15187    (set_attr "mode" "HI")])
15188
15189 (define_expand "paritydi2"
15190   [(set (match_operand:DI 0 "register_operand" "")
15191         (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
15192   "! TARGET_POPCNT"
15193 {
15194   rtx scratch = gen_reg_rtx (QImode);
15195   rtx cond;
15196
15197   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15198                                 NULL_RTX, operands[1]));
15199
15200   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15201                          gen_rtx_REG (CCmode, FLAGS_REG),
15202                          const0_rtx);
15203   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15204
15205   if (TARGET_64BIT)
15206     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15207   else
15208     {
15209       rtx tmp = gen_reg_rtx (SImode);
15210
15211       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15212       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15213     }
15214   DONE;
15215 })
15216
15217 (define_insn_and_split "paritydi2_cmp"
15218   [(set (reg:CC FLAGS_REG)
15219         (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m")))
15220    (clobber (match_scratch:DI 0 "=r,X"))
15221    (clobber (match_scratch:SI 1 "=r,r"))
15222    (clobber (match_scratch:HI 2 "=Q,Q"))]
15223   "! TARGET_POPCNT"
15224   "#"
15225   "&& reload_completed"
15226   [(parallel
15227      [(set (match_dup 1)
15228            (xor:SI (match_dup 1) (match_dup 4)))
15229       (clobber (reg:CC FLAGS_REG))])
15230    (parallel
15231      [(set (reg:CC FLAGS_REG)
15232            (parity:CC (match_dup 1)))
15233       (clobber (match_dup 1))
15234       (clobber (match_dup 2))])]
15235 {
15236   operands[4] = gen_lowpart (SImode, operands[3]);
15237
15238   if (MEM_P (operands[3]))
15239     emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
15240   else if (! TARGET_64BIT)
15241     operands[1] = gen_highpart (SImode, operands[3]);
15242   else
15243     {
15244       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15245       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15246     }
15247 })
15248
15249 (define_expand "paritysi2"
15250   [(set (match_operand:SI 0 "register_operand" "")
15251         (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
15252   "! TARGET_POPCNT"
15253 {
15254   rtx scratch = gen_reg_rtx (QImode);
15255   rtx cond;
15256
15257   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15258
15259   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15260                          gen_rtx_REG (CCmode, FLAGS_REG),
15261                          const0_rtx);
15262   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15263
15264   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15265   DONE;
15266 })
15267
15268 (define_insn_and_split "paritysi2_cmp"
15269   [(set (reg:CC FLAGS_REG)
15270         (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
15271    (clobber (match_scratch:SI 0 "=r,X"))
15272    (clobber (match_scratch:HI 1 "=Q,Q"))]
15273   "! TARGET_POPCNT"
15274   "#"
15275   "&& reload_completed"
15276   [(parallel
15277      [(set (match_dup 1)
15278            (xor:HI (match_dup 1) (match_dup 3)))
15279       (clobber (reg:CC FLAGS_REG))])
15280    (parallel
15281      [(set (reg:CC FLAGS_REG)
15282            (parity:CC (match_dup 1)))
15283       (clobber (match_dup 1))])]
15284 {
15285   operands[3] = gen_lowpart (HImode, operands[2]);
15286
15287   if (MEM_P (operands[2]))
15288     emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
15289   else
15290     {
15291       emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15292       emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15293     }
15294 })
15295
15296 (define_insn "*parityhi2_cmp"
15297   [(set (reg:CC FLAGS_REG)
15298         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15299    (clobber (match_scratch:HI 0 "=Q"))]
15300   "! TARGET_POPCNT"
15301   "xor{b}\t{%h0, %b0|%b0, %h0}"
15302   [(set_attr "length" "2")
15303    (set_attr "mode" "HI")])
15304
15305 (define_insn "*parityqi2_cmp"
15306   [(set (reg:CC FLAGS_REG)
15307         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15308   "! TARGET_POPCNT"
15309   "test{b}\t%0, %0"
15310   [(set_attr "length" "2")
15311    (set_attr "mode" "QI")])
15312 \f
15313 ;; Thread-local storage patterns for ELF.
15314 ;;
15315 ;; Note that these code sequences must appear exactly as shown
15316 ;; in order to allow linker relaxation.
15317
15318 (define_insn "*tls_global_dynamic_32_gnu"
15319   [(set (match_operand:SI 0 "register_operand" "=a")
15320         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15321                     (match_operand:SI 2 "tls_symbolic_operand" "")
15322                     (match_operand:SI 3 "call_insn_operand" "")]
15323                     UNSPEC_TLS_GD))
15324    (clobber (match_scratch:SI 4 "=d"))
15325    (clobber (match_scratch:SI 5 "=c"))
15326    (clobber (reg:CC FLAGS_REG))]
15327   "!TARGET_64BIT && TARGET_GNU_TLS"
15328   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15329   [(set_attr "type" "multi")
15330    (set_attr "length" "12")])
15331
15332 (define_insn "*tls_global_dynamic_32_sun"
15333   [(set (match_operand:SI 0 "register_operand" "=a")
15334         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15335                     (match_operand:SI 2 "tls_symbolic_operand" "")
15336                     (match_operand:SI 3 "call_insn_operand" "")]
15337                     UNSPEC_TLS_GD))
15338    (clobber (match_scratch:SI 4 "=d"))
15339    (clobber (match_scratch:SI 5 "=c"))
15340    (clobber (reg:CC FLAGS_REG))]
15341   "!TARGET_64BIT && TARGET_SUN_TLS"
15342   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15343         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15344   [(set_attr "type" "multi")
15345    (set_attr "length" "14")])
15346
15347 (define_expand "tls_global_dynamic_32"
15348   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15349                    (unspec:SI
15350                     [(match_dup 2)
15351                      (match_operand:SI 1 "tls_symbolic_operand" "")
15352                      (match_dup 3)]
15353                     UNSPEC_TLS_GD))
15354               (clobber (match_scratch:SI 4 ""))
15355               (clobber (match_scratch:SI 5 ""))
15356               (clobber (reg:CC FLAGS_REG))])]
15357   ""
15358 {
15359   if (flag_pic)
15360     operands[2] = pic_offset_table_rtx;
15361   else
15362     {
15363       operands[2] = gen_reg_rtx (Pmode);
15364       emit_insn (gen_set_got (operands[2]));
15365     }
15366   if (TARGET_GNU2_TLS)
15367     {
15368        emit_insn (gen_tls_dynamic_gnu2_32
15369                   (operands[0], operands[1], operands[2]));
15370        DONE;
15371     }
15372   operands[3] = ix86_tls_get_addr ();
15373 })
15374
15375 (define_insn "*tls_global_dynamic_64"
15376   [(set (match_operand:DI 0 "register_operand" "=a")
15377         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15378                  (match_operand:DI 3 "" "")))
15379    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15380               UNSPEC_TLS_GD)]
15381   "TARGET_64BIT"
15382   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15383   [(set_attr "type" "multi")
15384    (set_attr "length" "16")])
15385
15386 (define_expand "tls_global_dynamic_64"
15387   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15388                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15389               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15390                          UNSPEC_TLS_GD)])]
15391   ""
15392 {
15393   if (TARGET_GNU2_TLS)
15394     {
15395        emit_insn (gen_tls_dynamic_gnu2_64
15396                   (operands[0], operands[1]));
15397        DONE;
15398     }
15399   operands[2] = ix86_tls_get_addr ();
15400 })
15401
15402 (define_insn "*tls_local_dynamic_base_32_gnu"
15403   [(set (match_operand:SI 0 "register_operand" "=a")
15404         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15405                     (match_operand:SI 2 "call_insn_operand" "")]
15406                    UNSPEC_TLS_LD_BASE))
15407    (clobber (match_scratch:SI 3 "=d"))
15408    (clobber (match_scratch:SI 4 "=c"))
15409    (clobber (reg:CC FLAGS_REG))]
15410   "!TARGET_64BIT && TARGET_GNU_TLS"
15411   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15412   [(set_attr "type" "multi")
15413    (set_attr "length" "11")])
15414
15415 (define_insn "*tls_local_dynamic_base_32_sun"
15416   [(set (match_operand:SI 0 "register_operand" "=a")
15417         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15418                     (match_operand:SI 2 "call_insn_operand" "")]
15419                    UNSPEC_TLS_LD_BASE))
15420    (clobber (match_scratch:SI 3 "=d"))
15421    (clobber (match_scratch:SI 4 "=c"))
15422    (clobber (reg:CC FLAGS_REG))]
15423   "!TARGET_64BIT && TARGET_SUN_TLS"
15424   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15425         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15426   [(set_attr "type" "multi")
15427    (set_attr "length" "13")])
15428
15429 (define_expand "tls_local_dynamic_base_32"
15430   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15431                    (unspec:SI [(match_dup 1) (match_dup 2)]
15432                               UNSPEC_TLS_LD_BASE))
15433               (clobber (match_scratch:SI 3 ""))
15434               (clobber (match_scratch:SI 4 ""))
15435               (clobber (reg:CC FLAGS_REG))])]
15436   ""
15437 {
15438   if (flag_pic)
15439     operands[1] = pic_offset_table_rtx;
15440   else
15441     {
15442       operands[1] = gen_reg_rtx (Pmode);
15443       emit_insn (gen_set_got (operands[1]));
15444     }
15445   if (TARGET_GNU2_TLS)
15446     {
15447        emit_insn (gen_tls_dynamic_gnu2_32
15448                   (operands[0], ix86_tls_module_base (), operands[1]));
15449        DONE;
15450     }
15451   operands[2] = ix86_tls_get_addr ();
15452 })
15453
15454 (define_insn "*tls_local_dynamic_base_64"
15455   [(set (match_operand:DI 0 "register_operand" "=a")
15456         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15457                  (match_operand:DI 2 "" "")))
15458    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15459   "TARGET_64BIT"
15460   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15461   [(set_attr "type" "multi")
15462    (set_attr "length" "12")])
15463
15464 (define_expand "tls_local_dynamic_base_64"
15465   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15466                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15467               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15468   ""
15469 {
15470   if (TARGET_GNU2_TLS)
15471     {
15472        emit_insn (gen_tls_dynamic_gnu2_64
15473                   (operands[0], ix86_tls_module_base ()));
15474        DONE;
15475     }
15476   operands[1] = ix86_tls_get_addr ();
15477 })
15478
15479 ;; Local dynamic of a single variable is a lose.  Show combine how
15480 ;; to convert that back to global dynamic.
15481
15482 (define_insn_and_split "*tls_local_dynamic_32_once"
15483   [(set (match_operand:SI 0 "register_operand" "=a")
15484         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15485                              (match_operand:SI 2 "call_insn_operand" "")]
15486                             UNSPEC_TLS_LD_BASE)
15487                  (const:SI (unspec:SI
15488                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15489                             UNSPEC_DTPOFF))))
15490    (clobber (match_scratch:SI 4 "=d"))
15491    (clobber (match_scratch:SI 5 "=c"))
15492    (clobber (reg:CC FLAGS_REG))]
15493   ""
15494   "#"
15495   ""
15496   [(parallel [(set (match_dup 0)
15497                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15498                               UNSPEC_TLS_GD))
15499               (clobber (match_dup 4))
15500               (clobber (match_dup 5))
15501               (clobber (reg:CC FLAGS_REG))])]
15502   "")
15503
15504 ;; Load and add the thread base pointer from %gs:0.
15505
15506 (define_insn "*load_tp_si"
15507   [(set (match_operand:SI 0 "register_operand" "=r")
15508         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15509   "!TARGET_64BIT"
15510   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15511   [(set_attr "type" "imov")
15512    (set_attr "modrm" "0")
15513    (set_attr "length" "7")
15514    (set_attr "memory" "load")
15515    (set_attr "imm_disp" "false")])
15516
15517 (define_insn "*add_tp_si"
15518   [(set (match_operand:SI 0 "register_operand" "=r")
15519         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15520                  (match_operand:SI 1 "register_operand" "0")))
15521    (clobber (reg:CC FLAGS_REG))]
15522   "!TARGET_64BIT"
15523   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15524   [(set_attr "type" "alu")
15525    (set_attr "modrm" "0")
15526    (set_attr "length" "7")
15527    (set_attr "memory" "load")
15528    (set_attr "imm_disp" "false")])
15529
15530 (define_insn "*load_tp_di"
15531   [(set (match_operand:DI 0 "register_operand" "=r")
15532         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15533   "TARGET_64BIT"
15534   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15535   [(set_attr "type" "imov")
15536    (set_attr "modrm" "0")
15537    (set_attr "length" "7")
15538    (set_attr "memory" "load")
15539    (set_attr "imm_disp" "false")])
15540
15541 (define_insn "*add_tp_di"
15542   [(set (match_operand:DI 0 "register_operand" "=r")
15543         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15544                  (match_operand:DI 1 "register_operand" "0")))
15545    (clobber (reg:CC FLAGS_REG))]
15546   "TARGET_64BIT"
15547   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15548   [(set_attr "type" "alu")
15549    (set_attr "modrm" "0")
15550    (set_attr "length" "7")
15551    (set_attr "memory" "load")
15552    (set_attr "imm_disp" "false")])
15553
15554 ;; GNU2 TLS patterns can be split.
15555
15556 (define_expand "tls_dynamic_gnu2_32"
15557   [(set (match_dup 3)
15558         (plus:SI (match_operand:SI 2 "register_operand" "")
15559                  (const:SI
15560                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15561                              UNSPEC_TLSDESC))))
15562    (parallel
15563     [(set (match_operand:SI 0 "register_operand" "")
15564           (unspec:SI [(match_dup 1) (match_dup 3)
15565                       (match_dup 2) (reg:SI SP_REG)]
15566                       UNSPEC_TLSDESC))
15567      (clobber (reg:CC FLAGS_REG))])]
15568   "!TARGET_64BIT && TARGET_GNU2_TLS"
15569 {
15570   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15571   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15572 })
15573
15574 (define_insn "*tls_dynamic_lea_32"
15575   [(set (match_operand:SI 0 "register_operand" "=r")
15576         (plus:SI (match_operand:SI 1 "register_operand" "b")
15577                  (const:SI
15578                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15579                               UNSPEC_TLSDESC))))]
15580   "!TARGET_64BIT && TARGET_GNU2_TLS"
15581   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15582   [(set_attr "type" "lea")
15583    (set_attr "mode" "SI")
15584    (set_attr "length" "6")
15585    (set_attr "length_address" "4")])
15586
15587 (define_insn "*tls_dynamic_call_32"
15588   [(set (match_operand:SI 0 "register_operand" "=a")
15589         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15590                     (match_operand:SI 2 "register_operand" "0")
15591                     ;; we have to make sure %ebx still points to the GOT
15592                     (match_operand:SI 3 "register_operand" "b")
15593                     (reg:SI SP_REG)]
15594                    UNSPEC_TLSDESC))
15595    (clobber (reg:CC FLAGS_REG))]
15596   "!TARGET_64BIT && TARGET_GNU2_TLS"
15597   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15598   [(set_attr "type" "call")
15599    (set_attr "length" "2")
15600    (set_attr "length_address" "0")])
15601
15602 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15603   [(set (match_operand:SI 0 "register_operand" "=&a")
15604         (plus:SI
15605          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15606                      (match_operand:SI 4 "" "")
15607                      (match_operand:SI 2 "register_operand" "b")
15608                      (reg:SI SP_REG)]
15609                     UNSPEC_TLSDESC)
15610          (const:SI (unspec:SI
15611                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15612                     UNSPEC_DTPOFF))))
15613    (clobber (reg:CC FLAGS_REG))]
15614   "!TARGET_64BIT && TARGET_GNU2_TLS"
15615   "#"
15616   ""
15617   [(set (match_dup 0) (match_dup 5))]
15618 {
15619   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15620   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15621 })
15622
15623 (define_expand "tls_dynamic_gnu2_64"
15624   [(set (match_dup 2)
15625         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15626                    UNSPEC_TLSDESC))
15627    (parallel
15628     [(set (match_operand:DI 0 "register_operand" "")
15629           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15630                      UNSPEC_TLSDESC))
15631      (clobber (reg:CC FLAGS_REG))])]
15632   "TARGET_64BIT && TARGET_GNU2_TLS"
15633 {
15634   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15635   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15636 })
15637
15638 (define_insn "*tls_dynamic_lea_64"
15639   [(set (match_operand:DI 0 "register_operand" "=r")
15640         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15641                    UNSPEC_TLSDESC))]
15642   "TARGET_64BIT && TARGET_GNU2_TLS"
15643   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15644   [(set_attr "type" "lea")
15645    (set_attr "mode" "DI")
15646    (set_attr "length" "7")
15647    (set_attr "length_address" "4")])
15648
15649 (define_insn "*tls_dynamic_call_64"
15650   [(set (match_operand:DI 0 "register_operand" "=a")
15651         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15652                     (match_operand:DI 2 "register_operand" "0")
15653                     (reg:DI SP_REG)]
15654                    UNSPEC_TLSDESC))
15655    (clobber (reg:CC FLAGS_REG))]
15656   "TARGET_64BIT && TARGET_GNU2_TLS"
15657   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15658   [(set_attr "type" "call")
15659    (set_attr "length" "2")
15660    (set_attr "length_address" "0")])
15661
15662 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15663   [(set (match_operand:DI 0 "register_operand" "=&a")
15664         (plus:DI
15665          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15666                      (match_operand:DI 3 "" "")
15667                      (reg:DI SP_REG)]
15668                     UNSPEC_TLSDESC)
15669          (const:DI (unspec:DI
15670                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15671                     UNSPEC_DTPOFF))))
15672    (clobber (reg:CC FLAGS_REG))]
15673   "TARGET_64BIT && TARGET_GNU2_TLS"
15674   "#"
15675   ""
15676   [(set (match_dup 0) (match_dup 4))]
15677 {
15678   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15679   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15680 })
15681
15682 ;;
15683 \f
15684 ;; These patterns match the binary 387 instructions for addM3, subM3,
15685 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15686 ;; SFmode.  The first is the normal insn, the second the same insn but
15687 ;; with one operand a conversion, and the third the same insn but with
15688 ;; the other operand a conversion.  The conversion may be SFmode or
15689 ;; SImode if the target mode DFmode, but only SImode if the target mode
15690 ;; is SFmode.
15691
15692 ;; Gcc is slightly more smart about handling normal two address instructions
15693 ;; so use special patterns for add and mull.
15694
15695 (define_insn "*fop_sf_comm_mixed"
15696   [(set (match_operand:SF 0 "register_operand" "=f,x")
15697         (match_operator:SF 3 "binary_fp_operator"
15698                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15699                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15700   "TARGET_MIX_SSE_I387
15701    && COMMUTATIVE_ARITH_P (operands[3])
15702    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15703   "* return output_387_binary_op (insn, operands);"
15704   [(set (attr "type")
15705         (if_then_else (eq_attr "alternative" "1")
15706            (if_then_else (match_operand:SF 3 "mult_operator" "")
15707               (const_string "ssemul")
15708               (const_string "sseadd"))
15709            (if_then_else (match_operand:SF 3 "mult_operator" "")
15710               (const_string "fmul")
15711               (const_string "fop"))))
15712    (set_attr "mode" "SF")])
15713
15714 (define_insn "*fop_sf_comm_sse"
15715   [(set (match_operand:SF 0 "register_operand" "=x")
15716         (match_operator:SF 3 "binary_fp_operator"
15717                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15718                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15719   "TARGET_SSE_MATH
15720    && COMMUTATIVE_ARITH_P (operands[3])
15721    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15722   "* return output_387_binary_op (insn, operands);"
15723   [(set (attr "type")
15724         (if_then_else (match_operand:SF 3 "mult_operator" "")
15725            (const_string "ssemul")
15726            (const_string "sseadd")))
15727    (set_attr "mode" "SF")])
15728
15729 (define_insn "*fop_sf_comm_i387"
15730   [(set (match_operand:SF 0 "register_operand" "=f")
15731         (match_operator:SF 3 "binary_fp_operator"
15732                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15733                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15734   "TARGET_80387
15735    && COMMUTATIVE_ARITH_P (operands[3])
15736    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15737   "* return output_387_binary_op (insn, operands);"
15738   [(set (attr "type")
15739         (if_then_else (match_operand:SF 3 "mult_operator" "")
15740            (const_string "fmul")
15741            (const_string "fop")))
15742    (set_attr "mode" "SF")])
15743
15744 (define_insn "*fop_sf_1_mixed"
15745   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15746         (match_operator:SF 3 "binary_fp_operator"
15747                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15748                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15749   "TARGET_MIX_SSE_I387
15750    && !COMMUTATIVE_ARITH_P (operands[3])
15751    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15752   "* return output_387_binary_op (insn, operands);"
15753   [(set (attr "type")
15754         (cond [(and (eq_attr "alternative" "2")
15755                     (match_operand:SF 3 "mult_operator" ""))
15756                  (const_string "ssemul")
15757                (and (eq_attr "alternative" "2")
15758                     (match_operand:SF 3 "div_operator" ""))
15759                  (const_string "ssediv")
15760                (eq_attr "alternative" "2")
15761                  (const_string "sseadd")
15762                (match_operand:SF 3 "mult_operator" "")
15763                  (const_string "fmul")
15764                (match_operand:SF 3 "div_operator" "")
15765                  (const_string "fdiv")
15766               ]
15767               (const_string "fop")))
15768    (set_attr "mode" "SF")])
15769
15770 (define_insn "*fop_sf_1_sse"
15771   [(set (match_operand:SF 0 "register_operand" "=x")
15772         (match_operator:SF 3 "binary_fp_operator"
15773                         [(match_operand:SF 1 "register_operand" "0")
15774                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15775   "TARGET_SSE_MATH
15776    && !COMMUTATIVE_ARITH_P (operands[3])"
15777   "* return output_387_binary_op (insn, operands);"
15778   [(set (attr "type")
15779         (cond [(match_operand:SF 3 "mult_operator" "")
15780                  (const_string "ssemul")
15781                (match_operand:SF 3 "div_operator" "")
15782                  (const_string "ssediv")
15783               ]
15784               (const_string "sseadd")))
15785    (set_attr "mode" "SF")])
15786
15787 ;; This pattern is not fully shadowed by the pattern above.
15788 (define_insn "*fop_sf_1_i387"
15789   [(set (match_operand:SF 0 "register_operand" "=f,f")
15790         (match_operator:SF 3 "binary_fp_operator"
15791                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15792                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15793   "TARGET_80387 && !TARGET_SSE_MATH
15794    && !COMMUTATIVE_ARITH_P (operands[3])
15795    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15796   "* return output_387_binary_op (insn, operands);"
15797   [(set (attr "type")
15798         (cond [(match_operand:SF 3 "mult_operator" "")
15799                  (const_string "fmul")
15800                (match_operand:SF 3 "div_operator" "")
15801                  (const_string "fdiv")
15802               ]
15803               (const_string "fop")))
15804    (set_attr "mode" "SF")])
15805
15806 ;; ??? Add SSE splitters for these!
15807 (define_insn "*fop_sf_2<mode>_i387"
15808   [(set (match_operand:SF 0 "register_operand" "=f,f")
15809         (match_operator:SF 3 "binary_fp_operator"
15810           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15811            (match_operand:SF 2 "register_operand" "0,0")]))]
15812   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15813   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15814   [(set (attr "type")
15815         (cond [(match_operand:SF 3 "mult_operator" "")
15816                  (const_string "fmul")
15817                (match_operand:SF 3 "div_operator" "")
15818                  (const_string "fdiv")
15819               ]
15820               (const_string "fop")))
15821    (set_attr "fp_int_src" "true")
15822    (set_attr "mode" "<MODE>")])
15823
15824 (define_insn "*fop_sf_3<mode>_i387"
15825   [(set (match_operand:SF 0 "register_operand" "=f,f")
15826         (match_operator:SF 3 "binary_fp_operator"
15827           [(match_operand:SF 1 "register_operand" "0,0")
15828            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15829   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15830   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15831   [(set (attr "type")
15832         (cond [(match_operand:SF 3 "mult_operator" "")
15833                  (const_string "fmul")
15834                (match_operand:SF 3 "div_operator" "")
15835                  (const_string "fdiv")
15836               ]
15837               (const_string "fop")))
15838    (set_attr "fp_int_src" "true")
15839    (set_attr "mode" "<MODE>")])
15840
15841 (define_insn "*fop_df_comm_mixed"
15842   [(set (match_operand:DF 0 "register_operand" "=f,x")
15843         (match_operator:DF 3 "binary_fp_operator"
15844           [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15845            (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15846   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15847    && COMMUTATIVE_ARITH_P (operands[3])
15848    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15849   "* return output_387_binary_op (insn, operands);"
15850   [(set (attr "type")
15851         (if_then_else (eq_attr "alternative" "1")
15852            (if_then_else (match_operand:DF 3 "mult_operator" "")
15853               (const_string "ssemul")
15854               (const_string "sseadd"))
15855            (if_then_else (match_operand:DF 3 "mult_operator" "")
15856               (const_string "fmul")
15857               (const_string "fop"))))
15858    (set_attr "mode" "DF")])
15859
15860 (define_insn "*fop_df_comm_sse"
15861   [(set (match_operand:DF 0 "register_operand" "=x")
15862         (match_operator:DF 3 "binary_fp_operator"
15863           [(match_operand:DF 1 "nonimmediate_operand" "%0")
15864            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15865   "TARGET_SSE2 && TARGET_SSE_MATH
15866    && COMMUTATIVE_ARITH_P (operands[3])
15867    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15868   "* return output_387_binary_op (insn, operands);"
15869   [(set (attr "type")
15870         (if_then_else (match_operand:DF 3 "mult_operator" "")
15871            (const_string "ssemul")
15872            (const_string "sseadd")))
15873    (set_attr "mode" "DF")])
15874
15875 (define_insn "*fop_df_comm_i387"
15876   [(set (match_operand:DF 0 "register_operand" "=f")
15877         (match_operator:DF 3 "binary_fp_operator"
15878                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15879                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15880   "TARGET_80387
15881    && COMMUTATIVE_ARITH_P (operands[3])
15882    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15883   "* return output_387_binary_op (insn, operands);"
15884   [(set (attr "type")
15885         (if_then_else (match_operand:DF 3 "mult_operator" "")
15886            (const_string "fmul")
15887            (const_string "fop")))
15888    (set_attr "mode" "DF")])
15889
15890 (define_insn "*fop_df_1_mixed"
15891   [(set (match_operand:DF 0 "register_operand" "=f,f,x")
15892         (match_operator:DF 3 "binary_fp_operator"
15893           [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15894            (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
15895   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15896    && !COMMUTATIVE_ARITH_P (operands[3])
15897    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15898   "* return output_387_binary_op (insn, operands);"
15899   [(set (attr "type")
15900         (cond [(and (eq_attr "alternative" "2")
15901                     (match_operand:DF 3 "mult_operator" ""))
15902                  (const_string "ssemul")
15903                (and (eq_attr "alternative" "2")
15904                     (match_operand:DF 3 "div_operator" ""))
15905                  (const_string "ssediv")
15906                (eq_attr "alternative" "2")
15907                  (const_string "sseadd")
15908                (match_operand:DF 3 "mult_operator" "")
15909                  (const_string "fmul")
15910                (match_operand:DF 3 "div_operator" "")
15911                  (const_string "fdiv")
15912               ]
15913               (const_string "fop")))
15914    (set_attr "mode" "DF")])
15915
15916 (define_insn "*fop_df_1_sse"
15917   [(set (match_operand:DF 0 "register_operand" "=x")
15918         (match_operator:DF 3 "binary_fp_operator"
15919           [(match_operand:DF 1 "register_operand" "0")
15920            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15921   "TARGET_SSE2 && TARGET_SSE_MATH
15922    && !COMMUTATIVE_ARITH_P (operands[3])"
15923   "* return output_387_binary_op (insn, operands);"
15924   [(set_attr "mode" "DF")
15925    (set (attr "type")
15926         (cond [(match_operand:DF 3 "mult_operator" "")
15927                  (const_string "ssemul")
15928                (match_operand:DF 3 "div_operator" "")
15929                  (const_string "ssediv")
15930               ]
15931               (const_string "sseadd")))])
15932
15933 ;; This pattern is not fully shadowed by the pattern above.
15934 (define_insn "*fop_df_1_i387"
15935   [(set (match_operand:DF 0 "register_operand" "=f,f")
15936         (match_operator:DF 3 "binary_fp_operator"
15937                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15938                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15939   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15940    && !COMMUTATIVE_ARITH_P (operands[3])
15941    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15942   "* return output_387_binary_op (insn, operands);"
15943   [(set (attr "type")
15944         (cond [(match_operand:DF 3 "mult_operator" "")
15945                  (const_string "fmul")
15946                (match_operand:DF 3 "div_operator" "")
15947                  (const_string "fdiv")
15948               ]
15949               (const_string "fop")))
15950    (set_attr "mode" "DF")])
15951
15952 ;; ??? Add SSE splitters for these!
15953 (define_insn "*fop_df_2<mode>_i387"
15954   [(set (match_operand:DF 0 "register_operand" "=f,f")
15955         (match_operator:DF 3 "binary_fp_operator"
15956            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15957             (match_operand:DF 2 "register_operand" "0,0")]))]
15958   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15959    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15960   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15961   [(set (attr "type")
15962         (cond [(match_operand:DF 3 "mult_operator" "")
15963                  (const_string "fmul")
15964                (match_operand:DF 3 "div_operator" "")
15965                  (const_string "fdiv")
15966               ]
15967               (const_string "fop")))
15968    (set_attr "fp_int_src" "true")
15969    (set_attr "mode" "<MODE>")])
15970
15971 (define_insn "*fop_df_3<mode>_i387"
15972   [(set (match_operand:DF 0 "register_operand" "=f,f")
15973         (match_operator:DF 3 "binary_fp_operator"
15974            [(match_operand:DF 1 "register_operand" "0,0")
15975             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15976   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15977    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15978   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15979   [(set (attr "type")
15980         (cond [(match_operand:DF 3 "mult_operator" "")
15981                  (const_string "fmul")
15982                (match_operand:DF 3 "div_operator" "")
15983                  (const_string "fdiv")
15984               ]
15985               (const_string "fop")))
15986    (set_attr "fp_int_src" "true")
15987    (set_attr "mode" "<MODE>")])
15988
15989 (define_insn "*fop_df_4_i387"
15990   [(set (match_operand:DF 0 "register_operand" "=f,f")
15991         (match_operator:DF 3 "binary_fp_operator"
15992            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15993             (match_operand:DF 2 "register_operand" "0,f")]))]
15994   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15995    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15996   "* return output_387_binary_op (insn, operands);"
15997   [(set (attr "type")
15998         (cond [(match_operand:DF 3 "mult_operator" "")
15999                  (const_string "fmul")
16000                (match_operand:DF 3 "div_operator" "")
16001                  (const_string "fdiv")
16002               ]
16003               (const_string "fop")))
16004    (set_attr "mode" "SF")])
16005
16006 (define_insn "*fop_df_5_i387"
16007   [(set (match_operand:DF 0 "register_operand" "=f,f")
16008         (match_operator:DF 3 "binary_fp_operator"
16009           [(match_operand:DF 1 "register_operand" "0,f")
16010            (float_extend:DF
16011             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16012   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16013   "* return output_387_binary_op (insn, operands);"
16014   [(set (attr "type")
16015         (cond [(match_operand:DF 3 "mult_operator" "")
16016                  (const_string "fmul")
16017                (match_operand:DF 3 "div_operator" "")
16018                  (const_string "fdiv")
16019               ]
16020               (const_string "fop")))
16021    (set_attr "mode" "SF")])
16022
16023 (define_insn "*fop_df_6_i387"
16024   [(set (match_operand:DF 0 "register_operand" "=f,f")
16025         (match_operator:DF 3 "binary_fp_operator"
16026           [(float_extend:DF
16027             (match_operand:SF 1 "register_operand" "0,f"))
16028            (float_extend:DF
16029             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16030   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16031   "* return output_387_binary_op (insn, operands);"
16032   [(set (attr "type")
16033         (cond [(match_operand:DF 3 "mult_operator" "")
16034                  (const_string "fmul")
16035                (match_operand:DF 3 "div_operator" "")
16036                  (const_string "fdiv")
16037               ]
16038               (const_string "fop")))
16039    (set_attr "mode" "SF")])
16040
16041 (define_insn "*fop_xf_comm_i387"
16042   [(set (match_operand:XF 0 "register_operand" "=f")
16043         (match_operator:XF 3 "binary_fp_operator"
16044                         [(match_operand:XF 1 "register_operand" "%0")
16045                          (match_operand:XF 2 "register_operand" "f")]))]
16046   "TARGET_80387
16047    && COMMUTATIVE_ARITH_P (operands[3])"
16048   "* return output_387_binary_op (insn, operands);"
16049   [(set (attr "type")
16050         (if_then_else (match_operand:XF 3 "mult_operator" "")
16051            (const_string "fmul")
16052            (const_string "fop")))
16053    (set_attr "mode" "XF")])
16054
16055 (define_insn "*fop_xf_1_i387"
16056   [(set (match_operand:XF 0 "register_operand" "=f,f")
16057         (match_operator:XF 3 "binary_fp_operator"
16058                         [(match_operand:XF 1 "register_operand" "0,f")
16059                          (match_operand:XF 2 "register_operand" "f,0")]))]
16060   "TARGET_80387
16061    && !COMMUTATIVE_ARITH_P (operands[3])"
16062   "* return output_387_binary_op (insn, operands);"
16063   [(set (attr "type")
16064         (cond [(match_operand:XF 3 "mult_operator" "")
16065                  (const_string "fmul")
16066                (match_operand:XF 3 "div_operator" "")
16067                  (const_string "fdiv")
16068               ]
16069               (const_string "fop")))
16070    (set_attr "mode" "XF")])
16071
16072 (define_insn "*fop_xf_2<mode>_i387"
16073   [(set (match_operand:XF 0 "register_operand" "=f,f")
16074         (match_operator:XF 3 "binary_fp_operator"
16075            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16076             (match_operand:XF 2 "register_operand" "0,0")]))]
16077   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16078   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16079   [(set (attr "type")
16080         (cond [(match_operand:XF 3 "mult_operator" "")
16081                  (const_string "fmul")
16082                (match_operand:XF 3 "div_operator" "")
16083                  (const_string "fdiv")
16084               ]
16085               (const_string "fop")))
16086    (set_attr "fp_int_src" "true")
16087    (set_attr "mode" "<MODE>")])
16088
16089 (define_insn "*fop_xf_3<mode>_i387"
16090   [(set (match_operand:XF 0 "register_operand" "=f,f")
16091         (match_operator:XF 3 "binary_fp_operator"
16092           [(match_operand:XF 1 "register_operand" "0,0")
16093            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16094   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16095   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16096   [(set (attr "type")
16097         (cond [(match_operand:XF 3 "mult_operator" "")
16098                  (const_string "fmul")
16099                (match_operand:XF 3 "div_operator" "")
16100                  (const_string "fdiv")
16101               ]
16102               (const_string "fop")))
16103    (set_attr "fp_int_src" "true")
16104    (set_attr "mode" "<MODE>")])
16105
16106 (define_insn "*fop_xf_4_i387"
16107   [(set (match_operand:XF 0 "register_operand" "=f,f")
16108         (match_operator:XF 3 "binary_fp_operator"
16109            [(float_extend:XF
16110               (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
16111             (match_operand:XF 2 "register_operand" "0,f")]))]
16112   "TARGET_80387"
16113   "* return output_387_binary_op (insn, operands);"
16114   [(set (attr "type")
16115         (cond [(match_operand:XF 3 "mult_operator" "")
16116                  (const_string "fmul")
16117                (match_operand:XF 3 "div_operator" "")
16118                  (const_string "fdiv")
16119               ]
16120               (const_string "fop")))
16121    (set_attr "mode" "SF")])
16122
16123 (define_insn "*fop_xf_5_i387"
16124   [(set (match_operand:XF 0 "register_operand" "=f,f")
16125         (match_operator:XF 3 "binary_fp_operator"
16126           [(match_operand:XF 1 "register_operand" "0,f")
16127            (float_extend:XF
16128              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
16129   "TARGET_80387"
16130   "* return output_387_binary_op (insn, operands);"
16131   [(set (attr "type")
16132         (cond [(match_operand:XF 3 "mult_operator" "")
16133                  (const_string "fmul")
16134                (match_operand:XF 3 "div_operator" "")
16135                  (const_string "fdiv")
16136               ]
16137               (const_string "fop")))
16138    (set_attr "mode" "SF")])
16139
16140 (define_insn "*fop_xf_6_i387"
16141   [(set (match_operand:XF 0 "register_operand" "=f,f")
16142         (match_operator:XF 3 "binary_fp_operator"
16143           [(float_extend:XF
16144              (match_operand:X87MODEF12 1 "register_operand" "0,f"))
16145            (float_extend:XF
16146              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
16147   "TARGET_80387"
16148   "* return output_387_binary_op (insn, operands);"
16149   [(set (attr "type")
16150         (cond [(match_operand:XF 3 "mult_operator" "")
16151                  (const_string "fmul")
16152                (match_operand:XF 3 "div_operator" "")
16153                  (const_string "fdiv")
16154               ]
16155               (const_string "fop")))
16156    (set_attr "mode" "SF")])
16157
16158 (define_split
16159   [(set (match_operand 0 "register_operand" "")
16160         (match_operator 3 "binary_fp_operator"
16161            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16162             (match_operand 2 "register_operand" "")]))]
16163   "TARGET_80387 && reload_completed
16164    && FLOAT_MODE_P (GET_MODE (operands[0]))"
16165   [(const_int 0)]
16166 {
16167   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16168   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16169   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16170                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16171                                           GET_MODE (operands[3]),
16172                                           operands[4],
16173                                           operands[2])));
16174   ix86_free_from_memory (GET_MODE (operands[1]));
16175   DONE;
16176 })
16177
16178 (define_split
16179   [(set (match_operand 0 "register_operand" "")
16180         (match_operator 3 "binary_fp_operator"
16181            [(match_operand 1 "register_operand" "")
16182             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16183   "TARGET_80387 && reload_completed
16184    && FLOAT_MODE_P (GET_MODE (operands[0]))"
16185   [(const_int 0)]
16186 {
16187   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16188   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16189   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16190                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16191                                           GET_MODE (operands[3]),
16192                                           operands[1],
16193                                           operands[4])));
16194   ix86_free_from_memory (GET_MODE (operands[2]));
16195   DONE;
16196 })
16197 \f
16198 ;; FPU special functions.
16199
16200 ;; This pattern implements a no-op XFmode truncation for
16201 ;; all fancy i386 XFmode math functions.
16202
16203 (define_insn "truncxf<mode>2_i387_noop_unspec"
16204   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16205         (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
16206         UNSPEC_TRUNC_NOOP))]
16207   "TARGET_USE_FANCY_MATH_387"
16208   "* return output_387_reg_move (insn, operands);"
16209   [(set_attr "type" "fmov")
16210    (set_attr "mode" "<MODE>")])
16211
16212 (define_insn "sqrtxf2"
16213   [(set (match_operand:XF 0 "register_operand" "=f")
16214         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16215   "TARGET_USE_FANCY_MATH_387"
16216   "fsqrt"
16217   [(set_attr "type" "fpspc")
16218    (set_attr "mode" "XF")
16219    (set_attr "athlon_decode" "direct")
16220    (set_attr "amdfam10_decode" "direct")])
16221
16222 (define_insn "sqrt_extend<mode>xf2_i387"
16223   [(set (match_operand:XF 0 "register_operand" "=f")
16224         (sqrt:XF
16225           (float_extend:XF
16226             (match_operand:X87MODEF12 1 "register_operand" "0"))))]
16227   "TARGET_USE_FANCY_MATH_387"
16228   "fsqrt"
16229   [(set_attr "type" "fpspc")
16230    (set_attr "mode" "XF")
16231    (set_attr "athlon_decode" "direct")   
16232    (set_attr "amdfam10_decode" "direct")])
16233
16234 (define_insn "*sqrt<mode>2_sse"
16235   [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
16236         (sqrt:SSEMODEF
16237           (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
16238   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16239   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16240   [(set_attr "type" "sse")
16241    (set_attr "mode" "<MODE>")
16242    (set_attr "athlon_decode" "*")
16243    (set_attr "amdfam10_decode" "*")])
16244
16245 (define_expand "sqrt<mode>2"
16246   [(set (match_operand:X87MODEF12 0 "register_operand" "")
16247         (sqrt:X87MODEF12
16248           (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
16249   "TARGET_USE_FANCY_MATH_387
16250    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16251 {
16252   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16253     {
16254       rtx op0 = gen_reg_rtx (XFmode);
16255       rtx op1 = force_reg (<MODE>mode, operands[1]);
16256
16257       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16258       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16259       DONE;
16260    }
16261 })
16262
16263 (define_insn "fpremxf4_i387"
16264   [(set (match_operand:XF 0 "register_operand" "=f")
16265         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16266                     (match_operand:XF 3 "register_operand" "1")]
16267                    UNSPEC_FPREM_F))
16268    (set (match_operand:XF 1 "register_operand" "=u")
16269         (unspec:XF [(match_dup 2) (match_dup 3)]
16270                    UNSPEC_FPREM_U))
16271    (set (reg:CCFP FPSR_REG)
16272         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
16273   "TARGET_USE_FANCY_MATH_387"
16274   "fprem"
16275   [(set_attr "type" "fpspc")
16276    (set_attr "mode" "XF")])
16277
16278 (define_expand "fmodxf3"
16279   [(use (match_operand:XF 0 "register_operand" ""))
16280    (use (match_operand:XF 1 "register_operand" ""))
16281    (use (match_operand:XF 2 "register_operand" ""))]
16282   "TARGET_USE_FANCY_MATH_387"
16283 {
16284   rtx label = gen_label_rtx ();
16285
16286   emit_label (label);
16287
16288   emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
16289                                 operands[1], operands[2]));
16290   ix86_emit_fp_unordered_jump (label);
16291
16292   emit_move_insn (operands[0], operands[1]);
16293   DONE;
16294 })
16295
16296 (define_expand "fmod<mode>3"
16297   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16298    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16299    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16300   "TARGET_USE_FANCY_MATH_387"
16301 {
16302   rtx label = gen_label_rtx ();
16303
16304   rtx op1 = gen_reg_rtx (XFmode);
16305   rtx op2 = gen_reg_rtx (XFmode);
16306
16307   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16308   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16309
16310   emit_label (label);
16311   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16312   ix86_emit_fp_unordered_jump (label);
16313
16314   /* Truncate the result properly for strict SSE math.  */
16315   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16316       && !TARGET_MIX_SSE_I387)
16317     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16318   else
16319     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16320
16321   DONE;
16322 })
16323
16324 (define_insn "fprem1xf4_i387"
16325   [(set (match_operand:XF 0 "register_operand" "=f")
16326         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16327                     (match_operand:XF 3 "register_operand" "1")]
16328                    UNSPEC_FPREM1_F))
16329    (set (match_operand:XF 1 "register_operand" "=u")
16330         (unspec:XF [(match_dup 2) (match_dup 3)]
16331                    UNSPEC_FPREM1_U))
16332    (set (reg:CCFP FPSR_REG)
16333         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
16334   "TARGET_USE_FANCY_MATH_387"
16335   "fprem1"
16336   [(set_attr "type" "fpspc")
16337    (set_attr "mode" "XF")])
16338
16339 (define_expand "remainderxf3"
16340   [(use (match_operand:XF 0 "register_operand" ""))
16341    (use (match_operand:XF 1 "register_operand" ""))
16342    (use (match_operand:XF 2 "register_operand" ""))]
16343   "TARGET_USE_FANCY_MATH_387"
16344 {
16345   rtx label = gen_label_rtx ();
16346
16347   emit_label (label);
16348
16349   emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
16350                                  operands[1], operands[2]));
16351   ix86_emit_fp_unordered_jump (label);
16352
16353   emit_move_insn (operands[0], operands[1]);
16354   DONE;
16355 })
16356
16357 (define_expand "remainder<mode>3"
16358   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16359    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16360    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16361   "TARGET_USE_FANCY_MATH_387"
16362 {
16363   rtx label = gen_label_rtx ();
16364
16365   rtx op1 = gen_reg_rtx (XFmode);
16366   rtx op2 = gen_reg_rtx (XFmode);
16367
16368   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16369   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16370
16371   emit_label (label);
16372
16373   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16374   ix86_emit_fp_unordered_jump (label);
16375
16376   /* Truncate the result properly for strict SSE math.  */
16377   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16378       && !TARGET_MIX_SSE_I387)
16379     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16380   else
16381     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16382
16383   DONE;
16384 })
16385
16386 (define_insn "*sinxf2_i387"
16387   [(set (match_operand:XF 0 "register_operand" "=f")
16388         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16389   "TARGET_USE_FANCY_MATH_387
16390    && flag_unsafe_math_optimizations"
16391   "fsin"
16392   [(set_attr "type" "fpspc")
16393    (set_attr "mode" "XF")])
16394
16395 (define_insn "*sin_extend<mode>xf2_i387"
16396   [(set (match_operand:XF 0 "register_operand" "=f")
16397         (unspec:XF [(float_extend:XF
16398                       (match_operand:X87MODEF12 1 "register_operand" "0"))]
16399                    UNSPEC_SIN))]
16400   "TARGET_USE_FANCY_MATH_387
16401    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16402        || TARGET_MIX_SSE_I387)
16403    && flag_unsafe_math_optimizations"
16404   "fsin"
16405   [(set_attr "type" "fpspc")
16406    (set_attr "mode" "XF")])
16407
16408 (define_insn "*cosxf2_i387"
16409   [(set (match_operand:XF 0 "register_operand" "=f")
16410         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16411   "TARGET_USE_FANCY_MATH_387
16412    && flag_unsafe_math_optimizations"
16413   "fcos"
16414   [(set_attr "type" "fpspc")
16415    (set_attr "mode" "XF")])
16416
16417 (define_insn "*cos_extend<mode>xf2_i387"
16418   [(set (match_operand:XF 0 "register_operand" "=f")
16419         (unspec:XF [(float_extend:XF
16420                       (match_operand:X87MODEF12 1 "register_operand" "0"))]
16421                    UNSPEC_COS))]
16422   "TARGET_USE_FANCY_MATH_387
16423    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16424        || TARGET_MIX_SSE_I387)
16425    && flag_unsafe_math_optimizations"
16426   "fcos"
16427   [(set_attr "type" "fpspc")
16428    (set_attr "mode" "XF")])
16429
16430 ;; When sincos pattern is defined, sin and cos builtin functions will be
16431 ;; expanded to sincos pattern with one of its outputs left unused.
16432 ;; CSE pass will figure out if two sincos patterns can be combined,
16433 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16434 ;; depending on the unused output.
16435
16436 (define_insn "sincosxf3"
16437   [(set (match_operand:XF 0 "register_operand" "=f")
16438         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16439                    UNSPEC_SINCOS_COS))
16440    (set (match_operand:XF 1 "register_operand" "=u")
16441         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16442   "TARGET_USE_FANCY_MATH_387
16443    && flag_unsafe_math_optimizations"
16444   "fsincos"
16445   [(set_attr "type" "fpspc")
16446    (set_attr "mode" "XF")])
16447
16448 (define_split
16449   [(set (match_operand:XF 0 "register_operand" "")
16450         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16451                    UNSPEC_SINCOS_COS))
16452    (set (match_operand:XF 1 "register_operand" "")
16453         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16454   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16455    && !reload_completed && !reload_in_progress"
16456   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16457   "")
16458
16459 (define_split
16460   [(set (match_operand:XF 0 "register_operand" "")
16461         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16462                    UNSPEC_SINCOS_COS))
16463    (set (match_operand:XF 1 "register_operand" "")
16464         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16465   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16466    && !reload_completed && !reload_in_progress"
16467   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16468   "")
16469
16470 (define_insn "sincos_extend<mode>xf3_i387"
16471   [(set (match_operand:XF 0 "register_operand" "=f")
16472         (unspec:XF [(float_extend:XF
16473                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16474                    UNSPEC_SINCOS_COS))
16475    (set (match_operand:XF 1 "register_operand" "=u")
16476         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16477   "TARGET_USE_FANCY_MATH_387
16478    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16479        || TARGET_MIX_SSE_I387)
16480    && flag_unsafe_math_optimizations"
16481   "fsincos"
16482   [(set_attr "type" "fpspc")
16483    (set_attr "mode" "XF")])
16484
16485 (define_split
16486   [(set (match_operand:XF 0 "register_operand" "")
16487         (unspec:XF [(float_extend:XF
16488                       (match_operand:X87MODEF12 2 "register_operand" ""))]
16489                    UNSPEC_SINCOS_COS))
16490    (set (match_operand:XF 1 "register_operand" "")
16491         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16492   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16493    && !reload_completed && !reload_in_progress"
16494   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16495   "")
16496
16497 (define_split
16498   [(set (match_operand:XF 0 "register_operand" "")
16499         (unspec:XF [(float_extend:XF
16500                       (match_operand:X87MODEF12 2 "register_operand" ""))]
16501                    UNSPEC_SINCOS_COS))
16502    (set (match_operand:XF 1 "register_operand" "")
16503         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16504   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16505    && !reload_completed && !reload_in_progress"
16506   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16507   "")
16508
16509 (define_expand "sincos<mode>3"
16510   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16511    (use (match_operand:X87MODEF12 1 "register_operand" ""))
16512    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16513   "TARGET_USE_FANCY_MATH_387
16514    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16515        || TARGET_MIX_SSE_I387)
16516    && flag_unsafe_math_optimizations"
16517 {
16518   rtx op0 = gen_reg_rtx (XFmode);
16519   rtx op1 = gen_reg_rtx (XFmode);
16520
16521   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16522   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16523   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16524   DONE;
16525 })
16526
16527 (define_insn "fptanxf4_i387"
16528   [(set (match_operand:XF 0 "register_operand" "=f")
16529         (match_operand:XF 3 "const_double_operand" "F"))
16530    (set (match_operand:XF 1 "register_operand" "=u")
16531         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16532                    UNSPEC_TAN))]
16533   "TARGET_USE_FANCY_MATH_387
16534    && flag_unsafe_math_optimizations
16535    && standard_80387_constant_p (operands[3]) == 2"
16536   "fptan"
16537   [(set_attr "type" "fpspc")
16538    (set_attr "mode" "XF")])
16539
16540 (define_insn "fptan_extend<mode>xf4_i387"
16541   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16542         (match_operand:X87MODEF12 3 "const_double_operand" "F"))
16543    (set (match_operand:XF 1 "register_operand" "=u")
16544         (unspec:XF [(float_extend:XF
16545                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16546                    UNSPEC_TAN))]
16547   "TARGET_USE_FANCY_MATH_387
16548    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16549        || TARGET_MIX_SSE_I387)
16550    && flag_unsafe_math_optimizations
16551    && standard_80387_constant_p (operands[3]) == 2"
16552   "fptan"
16553   [(set_attr "type" "fpspc")
16554    (set_attr "mode" "XF")])
16555
16556 (define_expand "tanxf2"
16557   [(use (match_operand:XF 0 "register_operand" ""))
16558    (use (match_operand:XF 1 "register_operand" ""))]
16559   "TARGET_USE_FANCY_MATH_387
16560    && flag_unsafe_math_optimizations"
16561 {
16562   rtx one = gen_reg_rtx (XFmode);
16563   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16564
16565   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16566   DONE;
16567 })
16568
16569 (define_expand "tan<mode>2"
16570   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16571    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16572   "TARGET_USE_FANCY_MATH_387
16573    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16574        || TARGET_MIX_SSE_I387)
16575    && flag_unsafe_math_optimizations"
16576 {
16577   rtx op0 = gen_reg_rtx (XFmode);
16578
16579   rtx one = gen_reg_rtx (<MODE>mode);
16580   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16581
16582   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16583                                              operands[1], op2));
16584   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16585   DONE;
16586 })
16587
16588 (define_insn "*fpatanxf3_i387"
16589   [(set (match_operand:XF 0 "register_operand" "=f")
16590         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16591                     (match_operand:XF 2 "register_operand" "u")]
16592                    UNSPEC_FPATAN))
16593    (clobber (match_scratch:XF 3 "=2"))]
16594   "TARGET_USE_FANCY_MATH_387
16595    && flag_unsafe_math_optimizations"
16596   "fpatan"
16597   [(set_attr "type" "fpspc")
16598    (set_attr "mode" "XF")])
16599
16600 (define_insn "fpatan_extend<mode>xf3_i387"
16601   [(set (match_operand:XF 0 "register_operand" "=f")
16602         (unspec:XF [(float_extend:XF
16603                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16604                     (float_extend:XF
16605                       (match_operand:X87MODEF12 2 "register_operand" "u"))]
16606                    UNSPEC_FPATAN))
16607    (clobber (match_scratch:XF 3 "=2"))]
16608   "TARGET_USE_FANCY_MATH_387
16609    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16610        || TARGET_MIX_SSE_I387)
16611    && flag_unsafe_math_optimizations"
16612   "fpatan"
16613   [(set_attr "type" "fpspc")
16614    (set_attr "mode" "XF")])
16615
16616 (define_expand "atan2xf3"
16617   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16618                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
16619                                (match_operand:XF 1 "register_operand" "")]
16620                               UNSPEC_FPATAN))
16621               (clobber (match_scratch:XF 3 ""))])]
16622   "TARGET_USE_FANCY_MATH_387
16623    && flag_unsafe_math_optimizations"
16624   "")
16625
16626 (define_expand "atan2<mode>3"
16627   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16628    (use (match_operand:X87MODEF12 1 "register_operand" ""))
16629    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16630   "TARGET_USE_FANCY_MATH_387
16631    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16632        || TARGET_MIX_SSE_I387)
16633    && flag_unsafe_math_optimizations"
16634 {
16635   rtx op0 = gen_reg_rtx (XFmode);
16636
16637   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16638   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16639   DONE;
16640 })
16641
16642 (define_expand "atanxf2"
16643   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16644                    (unspec:XF [(match_dup 2)
16645                                (match_operand:XF 1 "register_operand" "")]
16646                               UNSPEC_FPATAN))
16647               (clobber (match_scratch:XF 3 ""))])]
16648   "TARGET_USE_FANCY_MATH_387
16649    && flag_unsafe_math_optimizations"
16650 {
16651   operands[2] = gen_reg_rtx (XFmode);
16652   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16653 })
16654
16655 (define_expand "atan<mode>2"
16656   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16657    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16658   "TARGET_USE_FANCY_MATH_387
16659    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16660        || TARGET_MIX_SSE_I387)
16661    && flag_unsafe_math_optimizations"
16662 {
16663   rtx op0 = gen_reg_rtx (XFmode);
16664
16665   rtx op2 = gen_reg_rtx (<MODE>mode);
16666   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
16667
16668   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16669   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16670   DONE;
16671 })
16672
16673 (define_expand "asinxf2"
16674   [(set (match_dup 2)
16675         (mult:XF (match_operand:XF 1 "register_operand" "")
16676                  (match_dup 1)))
16677    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16678    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16679    (parallel [(set (match_operand:XF 0 "register_operand" "")
16680                    (unspec:XF [(match_dup 5) (match_dup 1)]
16681                               UNSPEC_FPATAN))
16682               (clobber (match_scratch:XF 6 ""))])]
16683   "TARGET_USE_FANCY_MATH_387
16684    && flag_unsafe_math_optimizations && !optimize_size"
16685 {
16686   int i;
16687
16688   for (i = 2; i < 6; i++)
16689     operands[i] = gen_reg_rtx (XFmode);
16690
16691   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16692 })
16693
16694 (define_expand "asin<mode>2"
16695   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16696    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16697  "TARGET_USE_FANCY_MATH_387
16698    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16699        || TARGET_MIX_SSE_I387)
16700    && flag_unsafe_math_optimizations && !optimize_size"
16701 {
16702   rtx op0 = gen_reg_rtx (XFmode);
16703   rtx op1 = gen_reg_rtx (XFmode);
16704
16705   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16706   emit_insn (gen_asinxf2 (op0, op1));
16707   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16708   DONE;
16709 })
16710
16711 (define_expand "acosxf2"
16712   [(set (match_dup 2)
16713         (mult:XF (match_operand:XF 1 "register_operand" "")
16714                  (match_dup 1)))
16715    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16716    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16717    (parallel [(set (match_operand:XF 0 "register_operand" "")
16718                    (unspec:XF [(match_dup 1) (match_dup 5)]
16719                               UNSPEC_FPATAN))
16720               (clobber (match_scratch:XF 6 ""))])]
16721   "TARGET_USE_FANCY_MATH_387
16722    && flag_unsafe_math_optimizations && !optimize_size"
16723 {
16724   int i;
16725
16726   for (i = 2; i < 6; i++)
16727     operands[i] = gen_reg_rtx (XFmode);
16728
16729   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16730 })
16731
16732 (define_expand "acos<mode>2"
16733   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16734    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16735  "TARGET_USE_FANCY_MATH_387
16736    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16737        || TARGET_MIX_SSE_I387)
16738    && flag_unsafe_math_optimizations && !optimize_size"
16739 {
16740   rtx op0 = gen_reg_rtx (XFmode);
16741   rtx op1 = gen_reg_rtx (XFmode);
16742
16743   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16744   emit_insn (gen_acosxf2 (op0, op1));
16745   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16746   DONE;
16747 })
16748
16749 (define_insn "fyl2xxf3_i387"
16750   [(set (match_operand:XF 0 "register_operand" "=f")
16751         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16752                     (match_operand:XF 2 "register_operand" "u")]
16753                    UNSPEC_FYL2X))
16754    (clobber (match_scratch:XF 3 "=2"))]
16755   "TARGET_USE_FANCY_MATH_387
16756    && flag_unsafe_math_optimizations"
16757   "fyl2x"
16758   [(set_attr "type" "fpspc")
16759    (set_attr "mode" "XF")])
16760
16761 (define_insn "fyl2x_extend<mode>xf3_i387"
16762   [(set (match_operand:XF 0 "register_operand" "=f")
16763         (unspec:XF [(float_extend:XF
16764                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16765                     (match_operand:XF 2 "register_operand" "u")]
16766                    UNSPEC_FYL2X))
16767    (clobber (match_scratch:XF 3 "=2"))]
16768   "TARGET_USE_FANCY_MATH_387
16769    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16770        || TARGET_MIX_SSE_I387)
16771    && flag_unsafe_math_optimizations"
16772   "fyl2x"
16773   [(set_attr "type" "fpspc")
16774    (set_attr "mode" "XF")])
16775
16776 (define_expand "logxf2"
16777   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16778                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16779                                (match_dup 2)] UNSPEC_FYL2X))
16780               (clobber (match_scratch:XF 3 ""))])]
16781   "TARGET_USE_FANCY_MATH_387
16782    && flag_unsafe_math_optimizations"
16783 {
16784   operands[2] = gen_reg_rtx (XFmode);
16785   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16786 })
16787
16788 (define_expand "log<mode>2"
16789   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16790    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16791   "TARGET_USE_FANCY_MATH_387
16792    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16793        || TARGET_MIX_SSE_I387)
16794    && flag_unsafe_math_optimizations"
16795 {
16796   rtx op0 = gen_reg_rtx (XFmode);
16797
16798   rtx op2 = gen_reg_rtx (XFmode);
16799   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16800
16801   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16802   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16803   DONE;
16804 })
16805
16806 (define_expand "log10xf2"
16807   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16808                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16809                                (match_dup 2)] UNSPEC_FYL2X))
16810               (clobber (match_scratch:XF 3 ""))])]
16811   "TARGET_USE_FANCY_MATH_387
16812    && flag_unsafe_math_optimizations"
16813 {
16814   operands[2] = gen_reg_rtx (XFmode);
16815   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16816 })
16817
16818 (define_expand "log10<mode>2"
16819   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16820    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16821   "TARGET_USE_FANCY_MATH_387
16822    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16823        || TARGET_MIX_SSE_I387)
16824    && flag_unsafe_math_optimizations"
16825 {
16826   rtx op0 = gen_reg_rtx (XFmode);
16827
16828   rtx op2 = gen_reg_rtx (XFmode);
16829   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16830
16831   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16832   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16833   DONE;
16834 })
16835
16836 (define_expand "log2xf2"
16837   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16838                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16839                                (match_dup 2)] UNSPEC_FYL2X))
16840               (clobber (match_scratch:XF 3 ""))])]
16841   "TARGET_USE_FANCY_MATH_387
16842    && flag_unsafe_math_optimizations"
16843 {
16844   operands[2] = gen_reg_rtx (XFmode);
16845   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16846 })
16847
16848 (define_expand "log2<mode>2"
16849   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16850    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16851   "TARGET_USE_FANCY_MATH_387
16852    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16853        || TARGET_MIX_SSE_I387)
16854    && flag_unsafe_math_optimizations"
16855 {
16856   rtx op0 = gen_reg_rtx (XFmode);
16857
16858   rtx op2 = gen_reg_rtx (XFmode);
16859   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16860
16861   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16862   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16863   DONE;
16864 })
16865
16866 (define_insn "fyl2xp1xf3_i387"
16867   [(set (match_operand:XF 0 "register_operand" "=f")
16868         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16869                     (match_operand:XF 2 "register_operand" "u")]
16870                    UNSPEC_FYL2XP1))
16871    (clobber (match_scratch:XF 3 "=2"))]
16872   "TARGET_USE_FANCY_MATH_387
16873    && flag_unsafe_math_optimizations"
16874   "fyl2xp1"
16875   [(set_attr "type" "fpspc")
16876    (set_attr "mode" "XF")])
16877
16878 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16879   [(set (match_operand:XF 0 "register_operand" "=f")
16880         (unspec:XF [(float_extend:XF
16881                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16882                     (match_operand:XF 2 "register_operand" "u")]
16883                    UNSPEC_FYL2XP1))
16884    (clobber (match_scratch:XF 3 "=2"))]
16885   "TARGET_USE_FANCY_MATH_387
16886    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16887        || TARGET_MIX_SSE_I387)
16888    && flag_unsafe_math_optimizations"
16889   "fyl2xp1"
16890   [(set_attr "type" "fpspc")
16891    (set_attr "mode" "XF")])
16892
16893 (define_expand "log1pxf2"
16894   [(use (match_operand:XF 0 "register_operand" ""))
16895    (use (match_operand:XF 1 "register_operand" ""))]
16896   "TARGET_USE_FANCY_MATH_387
16897    && flag_unsafe_math_optimizations && !optimize_size"
16898 {
16899   ix86_emit_i387_log1p (operands[0], operands[1]);
16900   DONE;
16901 })
16902
16903 (define_expand "log1p<mode>2"
16904   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16905    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16906   "TARGET_USE_FANCY_MATH_387
16907    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16908        || TARGET_MIX_SSE_I387)
16909    && flag_unsafe_math_optimizations && !optimize_size"
16910 {
16911   rtx op0 = gen_reg_rtx (XFmode);
16912
16913   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16914
16915   ix86_emit_i387_log1p (op0, operands[1]);
16916   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16917   DONE;
16918 })
16919
16920 (define_insn "fxtractxf3_i387"
16921   [(set (match_operand:XF 0 "register_operand" "=f")
16922         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16923                    UNSPEC_XTRACT_FRACT))
16924    (set (match_operand:XF 1 "register_operand" "=u")
16925         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16926   "TARGET_USE_FANCY_MATH_387
16927    && flag_unsafe_math_optimizations"
16928   "fxtract"
16929   [(set_attr "type" "fpspc")
16930    (set_attr "mode" "XF")])
16931
16932 (define_insn "fxtract_extend<mode>xf3_i387"
16933   [(set (match_operand:XF 0 "register_operand" "=f")
16934         (unspec:XF [(float_extend:XF
16935                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16936                    UNSPEC_XTRACT_FRACT))
16937    (set (match_operand:XF 1 "register_operand" "=u")
16938         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16939   "TARGET_USE_FANCY_MATH_387
16940    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16941        || TARGET_MIX_SSE_I387)
16942    && flag_unsafe_math_optimizations"
16943   "fxtract"
16944   [(set_attr "type" "fpspc")
16945    (set_attr "mode" "XF")])
16946
16947 (define_expand "logbxf2"
16948   [(parallel [(set (match_dup 2)
16949                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16950                               UNSPEC_XTRACT_FRACT))
16951               (set (match_operand:XF 0 "register_operand" "")
16952                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16953   "TARGET_USE_FANCY_MATH_387
16954    && flag_unsafe_math_optimizations"
16955 {
16956   operands[2] = gen_reg_rtx (XFmode);
16957 })
16958
16959 (define_expand "logb<mode>2"
16960   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16961    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16962   "TARGET_USE_FANCY_MATH_387
16963    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16964        || TARGET_MIX_SSE_I387)
16965    && flag_unsafe_math_optimizations"
16966 {
16967   rtx op0 = gen_reg_rtx (XFmode);
16968   rtx op1 = gen_reg_rtx (XFmode);
16969
16970   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16971   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16972   DONE;
16973 })
16974
16975 (define_expand "ilogbxf2"
16976   [(use (match_operand:SI 0 "register_operand" ""))
16977    (use (match_operand:XF 1 "register_operand" ""))]
16978   "TARGET_USE_FANCY_MATH_387
16979    && flag_unsafe_math_optimizations && !optimize_size"
16980 {
16981   rtx op0 = gen_reg_rtx (XFmode);
16982   rtx op1 = gen_reg_rtx (XFmode);
16983
16984   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16985   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16986   DONE;
16987 })
16988
16989 (define_expand "ilogb<mode>2"
16990   [(use (match_operand:SI 0 "register_operand" ""))
16991    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16992   "TARGET_USE_FANCY_MATH_387
16993    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16994        || TARGET_MIX_SSE_I387)
16995    && flag_unsafe_math_optimizations && !optimize_size"
16996 {
16997   rtx op0 = gen_reg_rtx (XFmode);
16998   rtx op1 = gen_reg_rtx (XFmode);
16999
17000   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17001   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17002   DONE;
17003 })
17004
17005 (define_insn "*f2xm1xf2_i387"
17006   [(set (match_operand:XF 0 "register_operand" "=f")
17007         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17008                    UNSPEC_F2XM1))]
17009   "TARGET_USE_FANCY_MATH_387
17010    && flag_unsafe_math_optimizations"
17011   "f2xm1"
17012   [(set_attr "type" "fpspc")
17013    (set_attr "mode" "XF")])
17014
17015 (define_insn "*fscalexf4_i387"
17016   [(set (match_operand:XF 0 "register_operand" "=f")
17017         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17018                     (match_operand:XF 3 "register_operand" "1")]
17019                    UNSPEC_FSCALE_FRACT))
17020    (set (match_operand:XF 1 "register_operand" "=u")
17021         (unspec:XF [(match_dup 2) (match_dup 3)]
17022                    UNSPEC_FSCALE_EXP))]
17023   "TARGET_USE_FANCY_MATH_387
17024    && flag_unsafe_math_optimizations"
17025   "fscale"
17026   [(set_attr "type" "fpspc")
17027    (set_attr "mode" "XF")])
17028
17029 (define_expand "expNcorexf3"
17030   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17031                                (match_operand:XF 2 "register_operand" "")))
17032    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17033    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17034    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17035    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17036    (parallel [(set (match_operand:XF 0 "register_operand" "")
17037                    (unspec:XF [(match_dup 8) (match_dup 4)]
17038                               UNSPEC_FSCALE_FRACT))
17039               (set (match_dup 9)
17040                    (unspec:XF [(match_dup 8) (match_dup 4)]
17041                               UNSPEC_FSCALE_EXP))])]
17042   "TARGET_USE_FANCY_MATH_387
17043    && flag_unsafe_math_optimizations && !optimize_size"
17044 {
17045   int i;
17046
17047   for (i = 3; i < 10; i++)
17048     operands[i] = gen_reg_rtx (XFmode);
17049
17050   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17051 })
17052
17053 (define_expand "expxf2"
17054   [(use (match_operand:XF 0 "register_operand" ""))
17055    (use (match_operand:XF 1 "register_operand" ""))]
17056   "TARGET_USE_FANCY_MATH_387
17057    && flag_unsafe_math_optimizations && !optimize_size"
17058 {
17059   rtx op2 = gen_reg_rtx (XFmode);
17060   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17061
17062   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17063   DONE;
17064 })
17065
17066 (define_expand "exp<mode>2"
17067   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17068    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17069  "TARGET_USE_FANCY_MATH_387
17070    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17071        || TARGET_MIX_SSE_I387)
17072    && flag_unsafe_math_optimizations && !optimize_size"
17073 {
17074   rtx op0 = gen_reg_rtx (XFmode);
17075   rtx op1 = gen_reg_rtx (XFmode);
17076
17077   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17078   emit_insn (gen_expxf2 (op0, op1));
17079   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17080   DONE;
17081 })
17082
17083 (define_expand "exp10xf2"
17084   [(use (match_operand:XF 0 "register_operand" ""))
17085    (use (match_operand:XF 1 "register_operand" ""))]
17086   "TARGET_USE_FANCY_MATH_387
17087    && flag_unsafe_math_optimizations && !optimize_size"
17088 {
17089   rtx op2 = gen_reg_rtx (XFmode);
17090   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17091
17092   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17093   DONE;
17094 })
17095
17096 (define_expand "exp10<mode>2"
17097   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17098    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17099  "TARGET_USE_FANCY_MATH_387
17100    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17101        || TARGET_MIX_SSE_I387)
17102    && flag_unsafe_math_optimizations && !optimize_size"
17103 {
17104   rtx op0 = gen_reg_rtx (XFmode);
17105   rtx op1 = gen_reg_rtx (XFmode);
17106
17107   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17108   emit_insn (gen_exp10xf2 (op0, op1));
17109   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17110   DONE;
17111 })
17112
17113 (define_expand "exp2xf2"
17114   [(use (match_operand:XF 0 "register_operand" ""))
17115    (use (match_operand:XF 1 "register_operand" ""))]
17116   "TARGET_USE_FANCY_MATH_387
17117    && flag_unsafe_math_optimizations && !optimize_size"
17118 {
17119   rtx op2 = gen_reg_rtx (XFmode);
17120   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17121
17122   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17123   DONE;
17124 })
17125
17126 (define_expand "exp2<mode>2"
17127   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17128    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17129  "TARGET_USE_FANCY_MATH_387
17130    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17131        || TARGET_MIX_SSE_I387)
17132    && flag_unsafe_math_optimizations && !optimize_size"
17133 {
17134   rtx op0 = gen_reg_rtx (XFmode);
17135   rtx op1 = gen_reg_rtx (XFmode);
17136
17137   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17138   emit_insn (gen_exp2xf2 (op0, op1));
17139   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17140   DONE;
17141 })
17142
17143 (define_expand "expm1xf2"
17144   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17145                                (match_dup 2)))
17146    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17147    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17148    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17149    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17150    (parallel [(set (match_dup 7)
17151                    (unspec:XF [(match_dup 6) (match_dup 4)]
17152                               UNSPEC_FSCALE_FRACT))
17153               (set (match_dup 8)
17154                    (unspec:XF [(match_dup 6) (match_dup 4)]
17155                               UNSPEC_FSCALE_EXP))])
17156    (parallel [(set (match_dup 10)
17157                    (unspec:XF [(match_dup 9) (match_dup 8)]
17158                               UNSPEC_FSCALE_FRACT))
17159               (set (match_dup 11)
17160                    (unspec:XF [(match_dup 9) (match_dup 8)]
17161                               UNSPEC_FSCALE_EXP))])
17162    (set (match_dup 12) (minus:XF (match_dup 10)
17163                                  (float_extend:XF (match_dup 13))))
17164    (set (match_operand:XF 0 "register_operand" "")
17165         (plus:XF (match_dup 12) (match_dup 7)))]
17166   "TARGET_USE_FANCY_MATH_387
17167    && flag_unsafe_math_optimizations && !optimize_size"
17168 {
17169   int i;
17170
17171   for (i = 2; i < 13; i++)
17172     operands[i] = gen_reg_rtx (XFmode);
17173
17174   operands[13]
17175     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17176
17177   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17178 })
17179
17180 (define_expand "expm1<mode>2"
17181   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17182    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17183  "TARGET_USE_FANCY_MATH_387
17184    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17185        || TARGET_MIX_SSE_I387)
17186    && flag_unsafe_math_optimizations && !optimize_size"
17187 {
17188   rtx op0 = gen_reg_rtx (XFmode);
17189   rtx op1 = gen_reg_rtx (XFmode);
17190
17191   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17192   emit_insn (gen_expm1xf2 (op0, op1));
17193   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17194   DONE;
17195 })
17196
17197 (define_expand "ldexpxf3"
17198   [(set (match_dup 3)
17199         (float:XF (match_operand:SI 2 "register_operand" "")))
17200    (parallel [(set (match_operand:XF 0 " register_operand" "")
17201                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17202                                (match_dup 3)]
17203                               UNSPEC_FSCALE_FRACT))
17204               (set (match_dup 4)
17205                    (unspec:XF [(match_dup 1) (match_dup 3)]
17206                               UNSPEC_FSCALE_EXP))])]
17207   "TARGET_USE_FANCY_MATH_387
17208    && flag_unsafe_math_optimizations && !optimize_size"
17209 {
17210   operands[3] = gen_reg_rtx (XFmode);
17211   operands[4] = gen_reg_rtx (XFmode);
17212 })
17213
17214 (define_expand "ldexp<mode>3"
17215   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17216    (use (match_operand:X87MODEF12 1 "general_operand" ""))
17217    (use (match_operand:SI 2 "register_operand" ""))]
17218  "TARGET_USE_FANCY_MATH_387
17219    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17220        || TARGET_MIX_SSE_I387)
17221    && flag_unsafe_math_optimizations && !optimize_size"
17222 {
17223   rtx op0 = gen_reg_rtx (XFmode);
17224   rtx op1 = gen_reg_rtx (XFmode);
17225
17226   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17227   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17228   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17229   DONE;
17230 })
17231 \f
17232
17233 (define_insn "frndintxf2"
17234   [(set (match_operand:XF 0 "register_operand" "=f")
17235         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17236          UNSPEC_FRNDINT))]
17237   "TARGET_USE_FANCY_MATH_387
17238    && flag_unsafe_math_optimizations"
17239   "frndint"
17240   [(set_attr "type" "fpspc")
17241    (set_attr "mode" "XF")])
17242
17243 (define_expand "rintdf2"
17244   [(use (match_operand:DF 0 "register_operand" ""))
17245    (use (match_operand:DF 1 "register_operand" ""))]
17246   "(TARGET_USE_FANCY_MATH_387
17247     && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17248     && flag_unsafe_math_optimizations)
17249    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17250        && !flag_trapping_math
17251        && !optimize_size)"
17252 {
17253   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17254       && !flag_trapping_math
17255       && !optimize_size)
17256     ix86_expand_rint (operand0, operand1);
17257   else
17258     {
17259       rtx op0 = gen_reg_rtx (XFmode);
17260       rtx op1 = gen_reg_rtx (XFmode);
17261
17262       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17263       emit_insn (gen_frndintxf2 (op0, op1));
17264
17265       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17266     }
17267   DONE;
17268 })
17269
17270 (define_expand "rintsf2"
17271   [(use (match_operand:SF 0 "register_operand" ""))
17272    (use (match_operand:SF 1 "register_operand" ""))]
17273   "(TARGET_USE_FANCY_MATH_387
17274     && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17275     && flag_unsafe_math_optimizations)
17276    || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17277        && !flag_trapping_math
17278        && !optimize_size)"
17279 {
17280   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17281       && !flag_trapping_math
17282       && !optimize_size)
17283     ix86_expand_rint (operand0, operand1);
17284   else
17285     {
17286       rtx op0 = gen_reg_rtx (XFmode);
17287       rtx op1 = gen_reg_rtx (XFmode);
17288
17289       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17290       emit_insn (gen_frndintxf2 (op0, op1));
17291
17292       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17293     }
17294   DONE;
17295 })
17296
17297 (define_expand "rintxf2"
17298   [(use (match_operand:XF 0 "register_operand" ""))
17299    (use (match_operand:XF 1 "register_operand" ""))]
17300   "TARGET_USE_FANCY_MATH_387
17301    && flag_unsafe_math_optimizations && !optimize_size"
17302 {
17303   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17304   DONE;
17305 })
17306
17307 (define_expand "roundsf2"
17308   [(match_operand:SF 0 "register_operand" "")
17309    (match_operand:SF 1 "nonimmediate_operand" "")]
17310   "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17311    && !flag_trapping_math && !flag_rounding_math
17312    && !optimize_size"
17313 {
17314   ix86_expand_round (operand0, operand1);
17315   DONE;
17316 })
17317
17318 (define_expand "rounddf2"
17319   [(match_operand:DF 0 "register_operand" "")
17320    (match_operand:DF 1 "nonimmediate_operand" "")]
17321   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17322    && !flag_trapping_math && !flag_rounding_math
17323    && !optimize_size"
17324 {
17325   if (TARGET_64BIT)
17326     ix86_expand_round (operand0, operand1);
17327   else
17328     ix86_expand_rounddf_32 (operand0, operand1);
17329   DONE;
17330 })
17331
17332 (define_insn_and_split "*fistdi2_1"
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   "TARGET_USE_FANCY_MATH_387
17337    && !(reload_completed || reload_in_progress)"
17338   "#"
17339   "&& 1"
17340   [(const_int 0)]
17341 {
17342   if (memory_operand (operands[0], VOIDmode))
17343     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17344   else
17345     {
17346       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17347       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17348                                          operands[2]));
17349     }
17350   DONE;
17351 }
17352   [(set_attr "type" "fpspc")
17353    (set_attr "mode" "DI")])
17354
17355 (define_insn "fistdi2"
17356   [(set (match_operand:DI 0 "memory_operand" "=m")
17357         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17358          UNSPEC_FIST))
17359    (clobber (match_scratch:XF 2 "=&1f"))]
17360   "TARGET_USE_FANCY_MATH_387"
17361   "* return output_fix_trunc (insn, operands, 0);"
17362   [(set_attr "type" "fpspc")
17363    (set_attr "mode" "DI")])
17364
17365 (define_insn "fistdi2_with_temp"
17366   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17367         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17368          UNSPEC_FIST))
17369    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17370    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17371   "TARGET_USE_FANCY_MATH_387"
17372   "#"
17373   [(set_attr "type" "fpspc")
17374    (set_attr "mode" "DI")])
17375
17376 (define_split
17377   [(set (match_operand:DI 0 "register_operand" "")
17378         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17379          UNSPEC_FIST))
17380    (clobber (match_operand:DI 2 "memory_operand" ""))
17381    (clobber (match_scratch 3 ""))]
17382   "reload_completed"
17383   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17384               (clobber (match_dup 3))])
17385    (set (match_dup 0) (match_dup 2))]
17386   "")
17387
17388 (define_split
17389   [(set (match_operand:DI 0 "memory_operand" "")
17390         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17391          UNSPEC_FIST))
17392    (clobber (match_operand:DI 2 "memory_operand" ""))
17393    (clobber (match_scratch 3 ""))]
17394   "reload_completed"
17395   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17396               (clobber (match_dup 3))])]
17397   "")
17398
17399 (define_insn_and_split "*fist<mode>2_1"
17400   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17401         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17402          UNSPEC_FIST))]
17403   "TARGET_USE_FANCY_MATH_387
17404    && !(reload_completed || reload_in_progress)"
17405   "#"
17406   "&& 1"
17407   [(const_int 0)]
17408 {
17409   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17410   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17411                                         operands[2]));
17412   DONE;
17413 }
17414   [(set_attr "type" "fpspc")
17415    (set_attr "mode" "<MODE>")])
17416
17417 (define_insn "fist<mode>2"
17418   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17419         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17420          UNSPEC_FIST))]
17421   "TARGET_USE_FANCY_MATH_387"
17422   "* return output_fix_trunc (insn, operands, 0);"
17423   [(set_attr "type" "fpspc")
17424    (set_attr "mode" "<MODE>")])
17425
17426 (define_insn "fist<mode>2_with_temp"
17427   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17428         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17429          UNSPEC_FIST))
17430    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17431   "TARGET_USE_FANCY_MATH_387"
17432   "#"
17433   [(set_attr "type" "fpspc")
17434    (set_attr "mode" "<MODE>")])
17435
17436 (define_split
17437   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17438         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17439          UNSPEC_FIST))
17440    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17441   "reload_completed"
17442   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17443                        UNSPEC_FIST))
17444    (set (match_dup 0) (match_dup 2))]
17445   "")
17446
17447 (define_split
17448   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17449         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17450          UNSPEC_FIST))
17451    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17452   "reload_completed"
17453   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17454                        UNSPEC_FIST))]
17455   "")
17456
17457 (define_expand "lrintxf<mode>2"
17458   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17459      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17460       UNSPEC_FIST))]
17461   "TARGET_USE_FANCY_MATH_387"
17462   "")
17463
17464 (define_expand "lrint<mode>di2"
17465   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17466      (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
17467       UNSPEC_FIX_NOTRUNC))]
17468   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
17469   "")
17470
17471 (define_expand "lrint<mode>si2"
17472   [(set (match_operand:SI 0 "nonimmediate_operand" "")
17473      (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
17474       UNSPEC_FIX_NOTRUNC))]
17475   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17476   "")
17477
17478 (define_expand "lround<mode>di2"
17479   [(match_operand:DI 0 "nonimmediate_operand" "")
17480    (match_operand:SSEMODEF 1 "register_operand" "")]
17481   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17482    && !flag_trapping_math && !flag_rounding_math
17483    && !optimize_size"
17484 {
17485   ix86_expand_lround (operand0, operand1);
17486   DONE;
17487 })
17488
17489 (define_expand "lround<mode>si2"
17490   [(match_operand:SI 0 "nonimmediate_operand" "")
17491    (match_operand:SSEMODEF 1 "register_operand" "")]
17492   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17493    && !flag_trapping_math && !flag_rounding_math
17494    && !optimize_size"
17495 {
17496   ix86_expand_lround (operand0, operand1);
17497   DONE;
17498 })
17499
17500 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17501 (define_insn_and_split "frndintxf2_floor"
17502   [(set (match_operand:XF 0 "register_operand" "=f")
17503         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17504          UNSPEC_FRNDINT_FLOOR))
17505    (clobber (reg:CC FLAGS_REG))]
17506   "TARGET_USE_FANCY_MATH_387
17507    && flag_unsafe_math_optimizations
17508    && !(reload_completed || reload_in_progress)"
17509   "#"
17510   "&& 1"
17511   [(const_int 0)]
17512 {
17513   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17514
17515   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17516   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17517
17518   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17519                                         operands[2], operands[3]));
17520   DONE;
17521 }
17522   [(set_attr "type" "frndint")
17523    (set_attr "i387_cw" "floor")
17524    (set_attr "mode" "XF")])
17525
17526 (define_insn "frndintxf2_floor_i387"
17527   [(set (match_operand:XF 0 "register_operand" "=f")
17528         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17529          UNSPEC_FRNDINT_FLOOR))
17530    (use (match_operand:HI 2 "memory_operand" "m"))
17531    (use (match_operand:HI 3 "memory_operand" "m"))]
17532   "TARGET_USE_FANCY_MATH_387
17533    && flag_unsafe_math_optimizations"
17534   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17535   [(set_attr "type" "frndint")
17536    (set_attr "i387_cw" "floor")
17537    (set_attr "mode" "XF")])
17538
17539 (define_expand "floorxf2"
17540   [(use (match_operand:XF 0 "register_operand" ""))
17541    (use (match_operand:XF 1 "register_operand" ""))]
17542   "TARGET_USE_FANCY_MATH_387
17543    && flag_unsafe_math_optimizations && !optimize_size"
17544 {
17545   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17546   DONE;
17547 })
17548
17549 (define_expand "floordf2"
17550   [(use (match_operand:DF 0 "register_operand" ""))
17551    (use (match_operand:DF 1 "register_operand" ""))]
17552   "((TARGET_USE_FANCY_MATH_387
17553      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17554      && flag_unsafe_math_optimizations)
17555     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17556         && !flag_trapping_math))
17557    && !optimize_size"
17558 {
17559   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17560       && !flag_trapping_math)
17561     {
17562       if (TARGET_64BIT)
17563         ix86_expand_floorceil (operand0, operand1, true);
17564       else
17565         ix86_expand_floorceildf_32 (operand0, operand1, true);
17566     }
17567   else
17568     {
17569       rtx op0 = gen_reg_rtx (XFmode);
17570       rtx op1 = gen_reg_rtx (XFmode);
17571
17572       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17573       emit_insn (gen_frndintxf2_floor (op0, op1));
17574
17575       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17576     }
17577   DONE;
17578 })
17579
17580 (define_expand "floorsf2"
17581   [(use (match_operand:SF 0 "register_operand" ""))
17582    (use (match_operand:SF 1 "register_operand" ""))]
17583   "((TARGET_USE_FANCY_MATH_387
17584      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17585      && flag_unsafe_math_optimizations)
17586     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17587         && !flag_trapping_math))
17588    && !optimize_size"
17589 {
17590   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17591       && !flag_trapping_math)
17592     ix86_expand_floorceil (operand0, operand1, true);
17593   else
17594     {
17595       rtx op0 = gen_reg_rtx (XFmode);
17596       rtx op1 = gen_reg_rtx (XFmode);
17597
17598       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17599       emit_insn (gen_frndintxf2_floor (op0, op1));
17600
17601       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17602     }
17603   DONE;
17604 })
17605
17606 (define_insn_and_split "*fist<mode>2_floor_1"
17607   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17608         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17609          UNSPEC_FIST_FLOOR))
17610    (clobber (reg:CC FLAGS_REG))]
17611   "TARGET_USE_FANCY_MATH_387
17612    && flag_unsafe_math_optimizations
17613    && !(reload_completed || reload_in_progress)"
17614   "#"
17615   "&& 1"
17616   [(const_int 0)]
17617 {
17618   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17619
17620   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17621   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17622   if (memory_operand (operands[0], VOIDmode))
17623     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17624                                       operands[2], operands[3]));
17625   else
17626     {
17627       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17628       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17629                                                   operands[2], operands[3],
17630                                                   operands[4]));
17631     }
17632   DONE;
17633 }
17634   [(set_attr "type" "fistp")
17635    (set_attr "i387_cw" "floor")
17636    (set_attr "mode" "<MODE>")])
17637
17638 (define_insn "fistdi2_floor"
17639   [(set (match_operand:DI 0 "memory_operand" "=m")
17640         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17641          UNSPEC_FIST_FLOOR))
17642    (use (match_operand:HI 2 "memory_operand" "m"))
17643    (use (match_operand:HI 3 "memory_operand" "m"))
17644    (clobber (match_scratch:XF 4 "=&1f"))]
17645   "TARGET_USE_FANCY_MATH_387
17646    && flag_unsafe_math_optimizations"
17647   "* return output_fix_trunc (insn, operands, 0);"
17648   [(set_attr "type" "fistp")
17649    (set_attr "i387_cw" "floor")
17650    (set_attr "mode" "DI")])
17651
17652 (define_insn "fistdi2_floor_with_temp"
17653   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17654         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17655          UNSPEC_FIST_FLOOR))
17656    (use (match_operand:HI 2 "memory_operand" "m,m"))
17657    (use (match_operand:HI 3 "memory_operand" "m,m"))
17658    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17659    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17660   "TARGET_USE_FANCY_MATH_387
17661    && flag_unsafe_math_optimizations"
17662   "#"
17663   [(set_attr "type" "fistp")
17664    (set_attr "i387_cw" "floor")
17665    (set_attr "mode" "DI")])
17666
17667 (define_split
17668   [(set (match_operand:DI 0 "register_operand" "")
17669         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17670          UNSPEC_FIST_FLOOR))
17671    (use (match_operand:HI 2 "memory_operand" ""))
17672    (use (match_operand:HI 3 "memory_operand" ""))
17673    (clobber (match_operand:DI 4 "memory_operand" ""))
17674    (clobber (match_scratch 5 ""))]
17675   "reload_completed"
17676   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17677               (use (match_dup 2))
17678               (use (match_dup 3))
17679               (clobber (match_dup 5))])
17680    (set (match_dup 0) (match_dup 4))]
17681   "")
17682
17683 (define_split
17684   [(set (match_operand:DI 0 "memory_operand" "")
17685         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17686          UNSPEC_FIST_FLOOR))
17687    (use (match_operand:HI 2 "memory_operand" ""))
17688    (use (match_operand:HI 3 "memory_operand" ""))
17689    (clobber (match_operand:DI 4 "memory_operand" ""))
17690    (clobber (match_scratch 5 ""))]
17691   "reload_completed"
17692   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17693               (use (match_dup 2))
17694               (use (match_dup 3))
17695               (clobber (match_dup 5))])]
17696   "")
17697
17698 (define_insn "fist<mode>2_floor"
17699   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17700         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17701          UNSPEC_FIST_FLOOR))
17702    (use (match_operand:HI 2 "memory_operand" "m"))
17703    (use (match_operand:HI 3 "memory_operand" "m"))]
17704   "TARGET_USE_FANCY_MATH_387
17705    && flag_unsafe_math_optimizations"
17706   "* return output_fix_trunc (insn, operands, 0);"
17707   [(set_attr "type" "fistp")
17708    (set_attr "i387_cw" "floor")
17709    (set_attr "mode" "<MODE>")])
17710
17711 (define_insn "fist<mode>2_floor_with_temp"
17712   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17713         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17714          UNSPEC_FIST_FLOOR))
17715    (use (match_operand:HI 2 "memory_operand" "m,m"))
17716    (use (match_operand:HI 3 "memory_operand" "m,m"))
17717    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17718   "TARGET_USE_FANCY_MATH_387
17719    && flag_unsafe_math_optimizations"
17720   "#"
17721   [(set_attr "type" "fistp")
17722    (set_attr "i387_cw" "floor")
17723    (set_attr "mode" "<MODE>")])
17724
17725 (define_split
17726   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17727         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17728          UNSPEC_FIST_FLOOR))
17729    (use (match_operand:HI 2 "memory_operand" ""))
17730    (use (match_operand:HI 3 "memory_operand" ""))
17731    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17732   "reload_completed"
17733   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17734                                   UNSPEC_FIST_FLOOR))
17735               (use (match_dup 2))
17736               (use (match_dup 3))])
17737    (set (match_dup 0) (match_dup 4))]
17738   "")
17739
17740 (define_split
17741   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17742         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17743          UNSPEC_FIST_FLOOR))
17744    (use (match_operand:HI 2 "memory_operand" ""))
17745    (use (match_operand:HI 3 "memory_operand" ""))
17746    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17747   "reload_completed"
17748   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17749                                   UNSPEC_FIST_FLOOR))
17750               (use (match_dup 2))
17751               (use (match_dup 3))])]
17752   "")
17753
17754 (define_expand "lfloorxf<mode>2"
17755   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17756                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17757                     UNSPEC_FIST_FLOOR))
17758               (clobber (reg:CC FLAGS_REG))])]
17759   "TARGET_USE_FANCY_MATH_387
17760    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17761    && flag_unsafe_math_optimizations"
17762   "")
17763
17764 (define_expand "lfloor<mode>di2"
17765   [(match_operand:DI 0 "nonimmediate_operand" "")
17766    (match_operand:SSEMODEF 1 "register_operand" "")]
17767   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17768    && !flag_trapping_math
17769    && !optimize_size"
17770 {
17771   ix86_expand_lfloorceil (operand0, operand1, true);
17772   DONE;
17773 })
17774
17775 (define_expand "lfloor<mode>si2"
17776   [(match_operand:SI 0 "nonimmediate_operand" "")
17777    (match_operand:SSEMODEF 1 "register_operand" "")]
17778   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17779    && !flag_trapping_math
17780    && (!optimize_size || !TARGET_64BIT)"
17781 {
17782   ix86_expand_lfloorceil (operand0, operand1, true);
17783   DONE;
17784 })
17785
17786 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17787 (define_insn_and_split "frndintxf2_ceil"
17788   [(set (match_operand:XF 0 "register_operand" "=f")
17789         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17790          UNSPEC_FRNDINT_CEIL))
17791    (clobber (reg:CC FLAGS_REG))]
17792   "TARGET_USE_FANCY_MATH_387
17793    && flag_unsafe_math_optimizations
17794    && !(reload_completed || reload_in_progress)"
17795   "#"
17796   "&& 1"
17797   [(const_int 0)]
17798 {
17799   ix86_optimize_mode_switching[I387_CEIL] = 1;
17800
17801   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17802   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17803
17804   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17805                                        operands[2], operands[3]));
17806   DONE;
17807 }
17808   [(set_attr "type" "frndint")
17809    (set_attr "i387_cw" "ceil")
17810    (set_attr "mode" "XF")])
17811
17812 (define_insn "frndintxf2_ceil_i387"
17813   [(set (match_operand:XF 0 "register_operand" "=f")
17814         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17815          UNSPEC_FRNDINT_CEIL))
17816    (use (match_operand:HI 2 "memory_operand" "m"))
17817    (use (match_operand:HI 3 "memory_operand" "m"))]
17818   "TARGET_USE_FANCY_MATH_387
17819    && flag_unsafe_math_optimizations"
17820   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17821   [(set_attr "type" "frndint")
17822    (set_attr "i387_cw" "ceil")
17823    (set_attr "mode" "XF")])
17824
17825 (define_expand "ceilxf2"
17826   [(use (match_operand:XF 0 "register_operand" ""))
17827    (use (match_operand:XF 1 "register_operand" ""))]
17828   "TARGET_USE_FANCY_MATH_387
17829    && flag_unsafe_math_optimizations && !optimize_size"
17830 {
17831   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17832   DONE;
17833 })
17834
17835 (define_expand "ceildf2"
17836   [(use (match_operand:DF 0 "register_operand" ""))
17837    (use (match_operand:DF 1 "register_operand" ""))]
17838   "((TARGET_USE_FANCY_MATH_387
17839      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17840      && flag_unsafe_math_optimizations)
17841     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17842         && !flag_trapping_math))
17843    && !optimize_size"
17844 {
17845   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17846       && !flag_trapping_math)
17847     {
17848       if (TARGET_64BIT)
17849         ix86_expand_floorceil (operand0, operand1, false);
17850       else
17851         ix86_expand_floorceildf_32 (operand0, operand1, false);
17852     }
17853   else
17854     {
17855       rtx op0 = gen_reg_rtx (XFmode);
17856       rtx op1 = gen_reg_rtx (XFmode);
17857
17858       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17859       emit_insn (gen_frndintxf2_ceil (op0, op1));
17860
17861       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17862     }
17863   DONE;
17864 })
17865
17866 (define_expand "ceilsf2"
17867   [(use (match_operand:SF 0 "register_operand" ""))
17868    (use (match_operand:SF 1 "register_operand" ""))]
17869   "((TARGET_USE_FANCY_MATH_387
17870      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17871      && flag_unsafe_math_optimizations)
17872     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17873         && !flag_trapping_math))
17874    && !optimize_size"
17875 {
17876   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17877       && !flag_trapping_math)
17878     ix86_expand_floorceil (operand0, operand1, false);
17879   else
17880     {
17881       rtx op0 = gen_reg_rtx (XFmode);
17882       rtx op1 = gen_reg_rtx (XFmode);
17883
17884       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17885       emit_insn (gen_frndintxf2_ceil (op0, op1));
17886
17887       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17888     }
17889   DONE;
17890 })
17891
17892 (define_insn_and_split "*fist<mode>2_ceil_1"
17893   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17894         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17895          UNSPEC_FIST_CEIL))
17896    (clobber (reg:CC FLAGS_REG))]
17897   "TARGET_USE_FANCY_MATH_387
17898    && flag_unsafe_math_optimizations
17899    && !(reload_completed || reload_in_progress)"
17900   "#"
17901   "&& 1"
17902   [(const_int 0)]
17903 {
17904   ix86_optimize_mode_switching[I387_CEIL] = 1;
17905
17906   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17907   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17908   if (memory_operand (operands[0], VOIDmode))
17909     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17910                                      operands[2], operands[3]));
17911   else
17912     {
17913       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17914       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17915                                                  operands[2], operands[3],
17916                                                  operands[4]));
17917     }
17918   DONE;
17919 }
17920   [(set_attr "type" "fistp")
17921    (set_attr "i387_cw" "ceil")
17922    (set_attr "mode" "<MODE>")])
17923
17924 (define_insn "fistdi2_ceil"
17925   [(set (match_operand:DI 0 "memory_operand" "=m")
17926         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17927          UNSPEC_FIST_CEIL))
17928    (use (match_operand:HI 2 "memory_operand" "m"))
17929    (use (match_operand:HI 3 "memory_operand" "m"))
17930    (clobber (match_scratch:XF 4 "=&1f"))]
17931   "TARGET_USE_FANCY_MATH_387
17932    && flag_unsafe_math_optimizations"
17933   "* return output_fix_trunc (insn, operands, 0);"
17934   [(set_attr "type" "fistp")
17935    (set_attr "i387_cw" "ceil")
17936    (set_attr "mode" "DI")])
17937
17938 (define_insn "fistdi2_ceil_with_temp"
17939   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17940         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17941          UNSPEC_FIST_CEIL))
17942    (use (match_operand:HI 2 "memory_operand" "m,m"))
17943    (use (match_operand:HI 3 "memory_operand" "m,m"))
17944    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17945    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17946   "TARGET_USE_FANCY_MATH_387
17947    && flag_unsafe_math_optimizations"
17948   "#"
17949   [(set_attr "type" "fistp")
17950    (set_attr "i387_cw" "ceil")
17951    (set_attr "mode" "DI")])
17952
17953 (define_split
17954   [(set (match_operand:DI 0 "register_operand" "")
17955         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17956          UNSPEC_FIST_CEIL))
17957    (use (match_operand:HI 2 "memory_operand" ""))
17958    (use (match_operand:HI 3 "memory_operand" ""))
17959    (clobber (match_operand:DI 4 "memory_operand" ""))
17960    (clobber (match_scratch 5 ""))]
17961   "reload_completed"
17962   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17963               (use (match_dup 2))
17964               (use (match_dup 3))
17965               (clobber (match_dup 5))])
17966    (set (match_dup 0) (match_dup 4))]
17967   "")
17968
17969 (define_split
17970   [(set (match_operand:DI 0 "memory_operand" "")
17971         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17972          UNSPEC_FIST_CEIL))
17973    (use (match_operand:HI 2 "memory_operand" ""))
17974    (use (match_operand:HI 3 "memory_operand" ""))
17975    (clobber (match_operand:DI 4 "memory_operand" ""))
17976    (clobber (match_scratch 5 ""))]
17977   "reload_completed"
17978   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17979               (use (match_dup 2))
17980               (use (match_dup 3))
17981               (clobber (match_dup 5))])]
17982   "")
17983
17984 (define_insn "fist<mode>2_ceil"
17985   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17986         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17987          UNSPEC_FIST_CEIL))
17988    (use (match_operand:HI 2 "memory_operand" "m"))
17989    (use (match_operand:HI 3 "memory_operand" "m"))]
17990   "TARGET_USE_FANCY_MATH_387
17991    && flag_unsafe_math_optimizations"
17992   "* return output_fix_trunc (insn, operands, 0);"
17993   [(set_attr "type" "fistp")
17994    (set_attr "i387_cw" "ceil")
17995    (set_attr "mode" "<MODE>")])
17996
17997 (define_insn "fist<mode>2_ceil_with_temp"
17998   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17999         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18000          UNSPEC_FIST_CEIL))
18001    (use (match_operand:HI 2 "memory_operand" "m,m"))
18002    (use (match_operand:HI 3 "memory_operand" "m,m"))
18003    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18004   "TARGET_USE_FANCY_MATH_387
18005    && flag_unsafe_math_optimizations"
18006   "#"
18007   [(set_attr "type" "fistp")
18008    (set_attr "i387_cw" "ceil")
18009    (set_attr "mode" "<MODE>")])
18010
18011 (define_split
18012   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18013         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18014          UNSPEC_FIST_CEIL))
18015    (use (match_operand:HI 2 "memory_operand" ""))
18016    (use (match_operand:HI 3 "memory_operand" ""))
18017    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18018   "reload_completed"
18019   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18020                                   UNSPEC_FIST_CEIL))
18021               (use (match_dup 2))
18022               (use (match_dup 3))])
18023    (set (match_dup 0) (match_dup 4))]
18024   "")
18025
18026 (define_split
18027   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18028         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18029          UNSPEC_FIST_CEIL))
18030    (use (match_operand:HI 2 "memory_operand" ""))
18031    (use (match_operand:HI 3 "memory_operand" ""))
18032    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18033   "reload_completed"
18034   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18035                                   UNSPEC_FIST_CEIL))
18036               (use (match_dup 2))
18037               (use (match_dup 3))])]
18038   "")
18039
18040 (define_expand "lceilxf<mode>2"
18041   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18042                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18043                     UNSPEC_FIST_CEIL))
18044               (clobber (reg:CC FLAGS_REG))])]
18045   "TARGET_USE_FANCY_MATH_387
18046    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18047    && flag_unsafe_math_optimizations"
18048   "")
18049
18050 (define_expand "lceil<mode>di2"
18051   [(match_operand:DI 0 "nonimmediate_operand" "")
18052    (match_operand:SSEMODEF 1 "register_operand" "")]
18053   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18054    && !flag_trapping_math"
18055 {
18056   ix86_expand_lfloorceil (operand0, operand1, false);
18057   DONE;
18058 })
18059
18060 (define_expand "lceil<mode>si2"
18061   [(match_operand:SI 0 "nonimmediate_operand" "")
18062    (match_operand:SSEMODEF 1 "register_operand" "")]
18063   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18064    && !flag_trapping_math"
18065 {
18066   ix86_expand_lfloorceil (operand0, operand1, false);
18067   DONE;
18068 })
18069
18070 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18071 (define_insn_and_split "frndintxf2_trunc"
18072   [(set (match_operand:XF 0 "register_operand" "=f")
18073         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18074          UNSPEC_FRNDINT_TRUNC))
18075    (clobber (reg:CC FLAGS_REG))]
18076   "TARGET_USE_FANCY_MATH_387
18077    && flag_unsafe_math_optimizations
18078    && !(reload_completed || reload_in_progress)"
18079   "#"
18080   "&& 1"
18081   [(const_int 0)]
18082 {
18083   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18084
18085   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18086   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18087
18088   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18089                                         operands[2], operands[3]));
18090   DONE;
18091 }
18092   [(set_attr "type" "frndint")
18093    (set_attr "i387_cw" "trunc")
18094    (set_attr "mode" "XF")])
18095
18096 (define_insn "frndintxf2_trunc_i387"
18097   [(set (match_operand:XF 0 "register_operand" "=f")
18098         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18099          UNSPEC_FRNDINT_TRUNC))
18100    (use (match_operand:HI 2 "memory_operand" "m"))
18101    (use (match_operand:HI 3 "memory_operand" "m"))]
18102   "TARGET_USE_FANCY_MATH_387
18103    && flag_unsafe_math_optimizations"
18104   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18105   [(set_attr "type" "frndint")
18106    (set_attr "i387_cw" "trunc")
18107    (set_attr "mode" "XF")])
18108
18109 (define_expand "btruncxf2"
18110   [(use (match_operand:XF 0 "register_operand" ""))
18111    (use (match_operand:XF 1 "register_operand" ""))]
18112   "TARGET_USE_FANCY_MATH_387
18113    && flag_unsafe_math_optimizations && !optimize_size"
18114 {
18115   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18116   DONE;
18117 })
18118
18119 (define_expand "btruncdf2"
18120   [(use (match_operand:DF 0 "register_operand" ""))
18121    (use (match_operand:DF 1 "register_operand" ""))]
18122   "((TARGET_USE_FANCY_MATH_387
18123      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18124      && flag_unsafe_math_optimizations)
18125     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18126         && !flag_trapping_math))
18127    && !optimize_size"
18128 {
18129   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18130       && !flag_trapping_math)
18131     {
18132       if (TARGET_64BIT)
18133         ix86_expand_trunc (operand0, operand1);
18134       else
18135         ix86_expand_truncdf_32 (operand0, operand1);
18136     }
18137   else
18138     {
18139       rtx op0 = gen_reg_rtx (XFmode);
18140       rtx op1 = gen_reg_rtx (XFmode);
18141
18142       emit_insn (gen_extenddfxf2 (op1, operands[1]));
18143       emit_insn (gen_frndintxf2_trunc (op0, op1));
18144
18145       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18146     }
18147   DONE;
18148 })
18149
18150 (define_expand "btruncsf2"
18151   [(use (match_operand:SF 0 "register_operand" ""))
18152    (use (match_operand:SF 1 "register_operand" ""))]
18153   "((TARGET_USE_FANCY_MATH_387
18154      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18155      && flag_unsafe_math_optimizations)
18156     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18157         && !flag_trapping_math))
18158    && !optimize_size"
18159 {
18160   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18161       && !flag_trapping_math)
18162     ix86_expand_trunc (operand0, operand1);
18163   else
18164     {
18165       rtx op0 = gen_reg_rtx (XFmode);
18166       rtx op1 = gen_reg_rtx (XFmode);
18167
18168       emit_insn (gen_extendsfxf2 (op1, operands[1]));
18169       emit_insn (gen_frndintxf2_trunc (op0, op1));
18170
18171       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18172     }
18173   DONE;
18174 })
18175
18176 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18177 (define_insn_and_split "frndintxf2_mask_pm"
18178   [(set (match_operand:XF 0 "register_operand" "=f")
18179         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18180          UNSPEC_FRNDINT_MASK_PM))
18181    (clobber (reg:CC FLAGS_REG))]
18182   "TARGET_USE_FANCY_MATH_387
18183    && flag_unsafe_math_optimizations
18184    && !(reload_completed || reload_in_progress)"
18185   "#"
18186   "&& 1"
18187   [(const_int 0)]
18188 {
18189   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18190
18191   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18192   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18193
18194   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18195                                           operands[2], operands[3]));
18196   DONE;
18197 }
18198   [(set_attr "type" "frndint")
18199    (set_attr "i387_cw" "mask_pm")
18200    (set_attr "mode" "XF")])
18201
18202 (define_insn "frndintxf2_mask_pm_i387"
18203   [(set (match_operand:XF 0 "register_operand" "=f")
18204         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18205          UNSPEC_FRNDINT_MASK_PM))
18206    (use (match_operand:HI 2 "memory_operand" "m"))
18207    (use (match_operand:HI 3 "memory_operand" "m"))]
18208   "TARGET_USE_FANCY_MATH_387
18209    && flag_unsafe_math_optimizations"
18210   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18211   [(set_attr "type" "frndint")
18212    (set_attr "i387_cw" "mask_pm")
18213    (set_attr "mode" "XF")])
18214
18215 (define_expand "nearbyintxf2"
18216   [(use (match_operand:XF 0 "register_operand" ""))
18217    (use (match_operand:XF 1 "register_operand" ""))]
18218   "TARGET_USE_FANCY_MATH_387
18219    && flag_unsafe_math_optimizations"
18220 {
18221   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18222
18223   DONE;
18224 })
18225
18226 (define_expand "nearbyintdf2"
18227   [(use (match_operand:DF 0 "register_operand" ""))
18228    (use (match_operand:DF 1 "register_operand" ""))]
18229   "TARGET_USE_FANCY_MATH_387
18230    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18231    && flag_unsafe_math_optimizations"
18232 {
18233   rtx op0 = gen_reg_rtx (XFmode);
18234   rtx op1 = gen_reg_rtx (XFmode);
18235
18236   emit_insn (gen_extenddfxf2 (op1, operands[1]));
18237   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18238
18239   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18240   DONE;
18241 })
18242
18243 (define_expand "nearbyintsf2"
18244   [(use (match_operand:SF 0 "register_operand" ""))
18245    (use (match_operand:SF 1 "register_operand" ""))]
18246   "TARGET_USE_FANCY_MATH_387
18247    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18248    && flag_unsafe_math_optimizations"
18249 {
18250   rtx op0 = gen_reg_rtx (XFmode);
18251   rtx op1 = gen_reg_rtx (XFmode);
18252
18253   emit_insn (gen_extendsfxf2 (op1, operands[1]));
18254   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18255
18256   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18257   DONE;
18258 })
18259
18260 (define_insn "fxam<mode>2_i387"
18261   [(set (match_operand:HI 0 "register_operand" "=a")
18262         (unspec:HI
18263           [(match_operand:X87MODEF 1 "register_operand" "f")]
18264           UNSPEC_FXAM))]
18265   "TARGET_USE_FANCY_MATH_387"
18266   "fxam\n\tfnstsw\t%0"
18267   [(set_attr "type" "multi")
18268    (set_attr "unit" "i387")
18269    (set_attr "mode" "<MODE>")])
18270
18271 (define_expand "isinf<mode>2"
18272   [(use (match_operand:SI 0 "register_operand" ""))
18273    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18274   "TARGET_USE_FANCY_MATH_387
18275   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18276       || TARGET_MIX_SSE_I387)"
18277 {
18278   rtx mask = GEN_INT (0x45);
18279   rtx val = GEN_INT (0x05);
18280
18281   rtx cond;
18282
18283   rtx scratch = gen_reg_rtx (HImode);
18284   rtx res = gen_reg_rtx (QImode);
18285
18286   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18287   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18288   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18289   cond = gen_rtx_fmt_ee (EQ, QImode,
18290                          gen_rtx_REG (CCmode, FLAGS_REG),
18291                          const0_rtx);
18292   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18293   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18294   DONE;
18295 })
18296
18297 \f
18298 ;; Block operation instructions
18299
18300 (define_expand "movmemsi"
18301   [(use (match_operand:BLK 0 "memory_operand" ""))
18302    (use (match_operand:BLK 1 "memory_operand" ""))
18303    (use (match_operand:SI 2 "nonmemory_operand" ""))
18304    (use (match_operand:SI 3 "const_int_operand" ""))
18305    (use (match_operand:SI 4 "const_int_operand" ""))
18306    (use (match_operand:SI 5 "const_int_operand" ""))]
18307   ""
18308 {
18309  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18310                          operands[4], operands[5]))
18311    DONE;
18312  else
18313    FAIL;
18314 })
18315
18316 (define_expand "movmemdi"
18317   [(use (match_operand:BLK 0 "memory_operand" ""))
18318    (use (match_operand:BLK 1 "memory_operand" ""))
18319    (use (match_operand:DI 2 "nonmemory_operand" ""))
18320    (use (match_operand:DI 3 "const_int_operand" ""))
18321    (use (match_operand:SI 4 "const_int_operand" ""))
18322    (use (match_operand:SI 5 "const_int_operand" ""))]
18323   "TARGET_64BIT"
18324 {
18325  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18326                          operands[4], operands[5]))
18327    DONE;
18328  else
18329    FAIL;
18330 })
18331
18332 ;; Most CPUs don't like single string operations
18333 ;; Handle this case here to simplify previous expander.
18334
18335 (define_expand "strmov"
18336   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18337    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18338    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18339               (clobber (reg:CC FLAGS_REG))])
18340    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18341               (clobber (reg:CC FLAGS_REG))])]
18342   ""
18343 {
18344   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18345
18346   /* If .md ever supports :P for Pmode, these can be directly
18347      in the pattern above.  */
18348   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18349   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18350
18351   if (TARGET_SINGLE_STRINGOP || optimize_size)
18352     {
18353       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18354                                       operands[2], operands[3],
18355                                       operands[5], operands[6]));
18356       DONE;
18357     }
18358
18359   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18360 })
18361
18362 (define_expand "strmov_singleop"
18363   [(parallel [(set (match_operand 1 "memory_operand" "")
18364                    (match_operand 3 "memory_operand" ""))
18365               (set (match_operand 0 "register_operand" "")
18366                    (match_operand 4 "" ""))
18367               (set (match_operand 2 "register_operand" "")
18368                    (match_operand 5 "" ""))])]
18369   "TARGET_SINGLE_STRINGOP || optimize_size"
18370   "")
18371
18372 (define_insn "*strmovdi_rex_1"
18373   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18374         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18375    (set (match_operand:DI 0 "register_operand" "=D")
18376         (plus:DI (match_dup 2)
18377                  (const_int 8)))
18378    (set (match_operand:DI 1 "register_operand" "=S")
18379         (plus:DI (match_dup 3)
18380                  (const_int 8)))]
18381   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18382   "movsq"
18383   [(set_attr "type" "str")
18384    (set_attr "mode" "DI")
18385    (set_attr "memory" "both")])
18386
18387 (define_insn "*strmovsi_1"
18388   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18389         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18390    (set (match_operand:SI 0 "register_operand" "=D")
18391         (plus:SI (match_dup 2)
18392                  (const_int 4)))
18393    (set (match_operand:SI 1 "register_operand" "=S")
18394         (plus:SI (match_dup 3)
18395                  (const_int 4)))]
18396   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18397   "{movsl|movsd}"
18398   [(set_attr "type" "str")
18399    (set_attr "mode" "SI")
18400    (set_attr "memory" "both")])
18401
18402 (define_insn "*strmovsi_rex_1"
18403   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18404         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18405    (set (match_operand:DI 0 "register_operand" "=D")
18406         (plus:DI (match_dup 2)
18407                  (const_int 4)))
18408    (set (match_operand:DI 1 "register_operand" "=S")
18409         (plus:DI (match_dup 3)
18410                  (const_int 4)))]
18411   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18412   "{movsl|movsd}"
18413   [(set_attr "type" "str")
18414    (set_attr "mode" "SI")
18415    (set_attr "memory" "both")])
18416
18417 (define_insn "*strmovhi_1"
18418   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18419         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18420    (set (match_operand:SI 0 "register_operand" "=D")
18421         (plus:SI (match_dup 2)
18422                  (const_int 2)))
18423    (set (match_operand:SI 1 "register_operand" "=S")
18424         (plus:SI (match_dup 3)
18425                  (const_int 2)))]
18426   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18427   "movsw"
18428   [(set_attr "type" "str")
18429    (set_attr "memory" "both")
18430    (set_attr "mode" "HI")])
18431
18432 (define_insn "*strmovhi_rex_1"
18433   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18434         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18435    (set (match_operand:DI 0 "register_operand" "=D")
18436         (plus:DI (match_dup 2)
18437                  (const_int 2)))
18438    (set (match_operand:DI 1 "register_operand" "=S")
18439         (plus:DI (match_dup 3)
18440                  (const_int 2)))]
18441   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18442   "movsw"
18443   [(set_attr "type" "str")
18444    (set_attr "memory" "both")
18445    (set_attr "mode" "HI")])
18446
18447 (define_insn "*strmovqi_1"
18448   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18449         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18450    (set (match_operand:SI 0 "register_operand" "=D")
18451         (plus:SI (match_dup 2)
18452                  (const_int 1)))
18453    (set (match_operand:SI 1 "register_operand" "=S")
18454         (plus:SI (match_dup 3)
18455                  (const_int 1)))]
18456   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18457   "movsb"
18458   [(set_attr "type" "str")
18459    (set_attr "memory" "both")
18460    (set_attr "mode" "QI")])
18461
18462 (define_insn "*strmovqi_rex_1"
18463   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18464         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18465    (set (match_operand:DI 0 "register_operand" "=D")
18466         (plus:DI (match_dup 2)
18467                  (const_int 1)))
18468    (set (match_operand:DI 1 "register_operand" "=S")
18469         (plus:DI (match_dup 3)
18470                  (const_int 1)))]
18471   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18472   "movsb"
18473   [(set_attr "type" "str")
18474    (set_attr "memory" "both")
18475    (set_attr "mode" "QI")])
18476
18477 (define_expand "rep_mov"
18478   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18479               (set (match_operand 0 "register_operand" "")
18480                    (match_operand 5 "" ""))
18481               (set (match_operand 2 "register_operand" "")
18482                    (match_operand 6 "" ""))
18483               (set (match_operand 1 "memory_operand" "")
18484                    (match_operand 3 "memory_operand" ""))
18485               (use (match_dup 4))])]
18486   ""
18487   "")
18488
18489 (define_insn "*rep_movdi_rex64"
18490   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18491    (set (match_operand:DI 0 "register_operand" "=D")
18492         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18493                             (const_int 3))
18494                  (match_operand:DI 3 "register_operand" "0")))
18495    (set (match_operand:DI 1 "register_operand" "=S")
18496         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18497                  (match_operand:DI 4 "register_operand" "1")))
18498    (set (mem:BLK (match_dup 3))
18499         (mem:BLK (match_dup 4)))
18500    (use (match_dup 5))]
18501   "TARGET_64BIT"
18502   "{rep\;movsq|rep movsq}"
18503   [(set_attr "type" "str")
18504    (set_attr "prefix_rep" "1")
18505    (set_attr "memory" "both")
18506    (set_attr "mode" "DI")])
18507
18508 (define_insn "*rep_movsi"
18509   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18510    (set (match_operand:SI 0 "register_operand" "=D")
18511         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18512                             (const_int 2))
18513                  (match_operand:SI 3 "register_operand" "0")))
18514    (set (match_operand:SI 1 "register_operand" "=S")
18515         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18516                  (match_operand:SI 4 "register_operand" "1")))
18517    (set (mem:BLK (match_dup 3))
18518         (mem:BLK (match_dup 4)))
18519    (use (match_dup 5))]
18520   "!TARGET_64BIT"
18521   "{rep\;movsl|rep movsd}"
18522   [(set_attr "type" "str")
18523    (set_attr "prefix_rep" "1")
18524    (set_attr "memory" "both")
18525    (set_attr "mode" "SI")])
18526
18527 (define_insn "*rep_movsi_rex64"
18528   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18529    (set (match_operand:DI 0 "register_operand" "=D")
18530         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18531                             (const_int 2))
18532                  (match_operand:DI 3 "register_operand" "0")))
18533    (set (match_operand:DI 1 "register_operand" "=S")
18534         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18535                  (match_operand:DI 4 "register_operand" "1")))
18536    (set (mem:BLK (match_dup 3))
18537         (mem:BLK (match_dup 4)))
18538    (use (match_dup 5))]
18539   "TARGET_64BIT"
18540   "{rep\;movsl|rep movsd}"
18541   [(set_attr "type" "str")
18542    (set_attr "prefix_rep" "1")
18543    (set_attr "memory" "both")
18544    (set_attr "mode" "SI")])
18545
18546 (define_insn "*rep_movqi"
18547   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18548    (set (match_operand:SI 0 "register_operand" "=D")
18549         (plus:SI (match_operand:SI 3 "register_operand" "0")
18550                  (match_operand:SI 5 "register_operand" "2")))
18551    (set (match_operand:SI 1 "register_operand" "=S")
18552         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18553    (set (mem:BLK (match_dup 3))
18554         (mem:BLK (match_dup 4)))
18555    (use (match_dup 5))]
18556   "!TARGET_64BIT"
18557   "{rep\;movsb|rep movsb}"
18558   [(set_attr "type" "str")
18559    (set_attr "prefix_rep" "1")
18560    (set_attr "memory" "both")
18561    (set_attr "mode" "SI")])
18562
18563 (define_insn "*rep_movqi_rex64"
18564   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18565    (set (match_operand:DI 0 "register_operand" "=D")
18566         (plus:DI (match_operand:DI 3 "register_operand" "0")
18567                  (match_operand:DI 5 "register_operand" "2")))
18568    (set (match_operand:DI 1 "register_operand" "=S")
18569         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18570    (set (mem:BLK (match_dup 3))
18571         (mem:BLK (match_dup 4)))
18572    (use (match_dup 5))]
18573   "TARGET_64BIT"
18574   "{rep\;movsb|rep movsb}"
18575   [(set_attr "type" "str")
18576    (set_attr "prefix_rep" "1")
18577    (set_attr "memory" "both")
18578    (set_attr "mode" "SI")])
18579
18580 (define_expand "setmemsi"
18581    [(use (match_operand:BLK 0 "memory_operand" ""))
18582     (use (match_operand:SI 1 "nonmemory_operand" ""))
18583     (use (match_operand 2 "const_int_operand" ""))
18584     (use (match_operand 3 "const_int_operand" ""))
18585     (use (match_operand:SI 4 "const_int_operand" ""))
18586     (use (match_operand:SI 5 "const_int_operand" ""))]
18587   ""
18588 {
18589  if (ix86_expand_setmem (operands[0], operands[1],
18590                          operands[2], operands[3],
18591                          operands[4], operands[5]))
18592    DONE;
18593  else
18594    FAIL;
18595 })
18596
18597 (define_expand "setmemdi"
18598    [(use (match_operand:BLK 0 "memory_operand" ""))
18599     (use (match_operand:DI 1 "nonmemory_operand" ""))
18600     (use (match_operand 2 "const_int_operand" ""))
18601     (use (match_operand 3 "const_int_operand" ""))
18602     (use (match_operand 4 "const_int_operand" ""))
18603     (use (match_operand 5 "const_int_operand" ""))]
18604   "TARGET_64BIT"
18605 {
18606  if (ix86_expand_setmem (operands[0], operands[1],
18607                          operands[2], operands[3],
18608                          operands[4], operands[5]))
18609    DONE;
18610  else
18611    FAIL;
18612 })
18613
18614 ;; Most CPUs don't like single string operations
18615 ;; Handle this case here to simplify previous expander.
18616
18617 (define_expand "strset"
18618   [(set (match_operand 1 "memory_operand" "")
18619         (match_operand 2 "register_operand" ""))
18620    (parallel [(set (match_operand 0 "register_operand" "")
18621                    (match_dup 3))
18622               (clobber (reg:CC FLAGS_REG))])]
18623   ""
18624 {
18625   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18626     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18627
18628   /* If .md ever supports :P for Pmode, this can be directly
18629      in the pattern above.  */
18630   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18631                               GEN_INT (GET_MODE_SIZE (GET_MODE
18632                                                       (operands[2]))));
18633   if (TARGET_SINGLE_STRINGOP || optimize_size)
18634     {
18635       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18636                                       operands[3]));
18637       DONE;
18638     }
18639 })
18640
18641 (define_expand "strset_singleop"
18642   [(parallel [(set (match_operand 1 "memory_operand" "")
18643                    (match_operand 2 "register_operand" ""))
18644               (set (match_operand 0 "register_operand" "")
18645                    (match_operand 3 "" ""))])]
18646   "TARGET_SINGLE_STRINGOP || optimize_size"
18647   "")
18648
18649 (define_insn "*strsetdi_rex_1"
18650   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18651         (match_operand:DI 2 "register_operand" "a"))
18652    (set (match_operand:DI 0 "register_operand" "=D")
18653         (plus:DI (match_dup 1)
18654                  (const_int 8)))]
18655   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18656   "stosq"
18657   [(set_attr "type" "str")
18658    (set_attr "memory" "store")
18659    (set_attr "mode" "DI")])
18660
18661 (define_insn "*strsetsi_1"
18662   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18663         (match_operand:SI 2 "register_operand" "a"))
18664    (set (match_operand:SI 0 "register_operand" "=D")
18665         (plus:SI (match_dup 1)
18666                  (const_int 4)))]
18667   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18668   "{stosl|stosd}"
18669   [(set_attr "type" "str")
18670    (set_attr "memory" "store")
18671    (set_attr "mode" "SI")])
18672
18673 (define_insn "*strsetsi_rex_1"
18674   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18675         (match_operand:SI 2 "register_operand" "a"))
18676    (set (match_operand:DI 0 "register_operand" "=D")
18677         (plus:DI (match_dup 1)
18678                  (const_int 4)))]
18679   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18680   "{stosl|stosd}"
18681   [(set_attr "type" "str")
18682    (set_attr "memory" "store")
18683    (set_attr "mode" "SI")])
18684
18685 (define_insn "*strsethi_1"
18686   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18687         (match_operand:HI 2 "register_operand" "a"))
18688    (set (match_operand:SI 0 "register_operand" "=D")
18689         (plus:SI (match_dup 1)
18690                  (const_int 2)))]
18691   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18692   "stosw"
18693   [(set_attr "type" "str")
18694    (set_attr "memory" "store")
18695    (set_attr "mode" "HI")])
18696
18697 (define_insn "*strsethi_rex_1"
18698   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18699         (match_operand:HI 2 "register_operand" "a"))
18700    (set (match_operand:DI 0 "register_operand" "=D")
18701         (plus:DI (match_dup 1)
18702                  (const_int 2)))]
18703   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18704   "stosw"
18705   [(set_attr "type" "str")
18706    (set_attr "memory" "store")
18707    (set_attr "mode" "HI")])
18708
18709 (define_insn "*strsetqi_1"
18710   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18711         (match_operand:QI 2 "register_operand" "a"))
18712    (set (match_operand:SI 0 "register_operand" "=D")
18713         (plus:SI (match_dup 1)
18714                  (const_int 1)))]
18715   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18716   "stosb"
18717   [(set_attr "type" "str")
18718    (set_attr "memory" "store")
18719    (set_attr "mode" "QI")])
18720
18721 (define_insn "*strsetqi_rex_1"
18722   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18723         (match_operand:QI 2 "register_operand" "a"))
18724    (set (match_operand:DI 0 "register_operand" "=D")
18725         (plus:DI (match_dup 1)
18726                  (const_int 1)))]
18727   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18728   "stosb"
18729   [(set_attr "type" "str")
18730    (set_attr "memory" "store")
18731    (set_attr "mode" "QI")])
18732
18733 (define_expand "rep_stos"
18734   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18735               (set (match_operand 0 "register_operand" "")
18736                    (match_operand 4 "" ""))
18737               (set (match_operand 2 "memory_operand" "") (const_int 0))
18738               (use (match_operand 3 "register_operand" ""))
18739               (use (match_dup 1))])]
18740   ""
18741   "")
18742
18743 (define_insn "*rep_stosdi_rex64"
18744   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18745    (set (match_operand:DI 0 "register_operand" "=D")
18746         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18747                             (const_int 3))
18748                  (match_operand:DI 3 "register_operand" "0")))
18749    (set (mem:BLK (match_dup 3))
18750         (const_int 0))
18751    (use (match_operand:DI 2 "register_operand" "a"))
18752    (use (match_dup 4))]
18753   "TARGET_64BIT"
18754   "{rep\;stosq|rep stosq}"
18755   [(set_attr "type" "str")
18756    (set_attr "prefix_rep" "1")
18757    (set_attr "memory" "store")
18758    (set_attr "mode" "DI")])
18759
18760 (define_insn "*rep_stossi"
18761   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18762    (set (match_operand:SI 0 "register_operand" "=D")
18763         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18764                             (const_int 2))
18765                  (match_operand:SI 3 "register_operand" "0")))
18766    (set (mem:BLK (match_dup 3))
18767         (const_int 0))
18768    (use (match_operand:SI 2 "register_operand" "a"))
18769    (use (match_dup 4))]
18770   "!TARGET_64BIT"
18771   "{rep\;stosl|rep stosd}"
18772   [(set_attr "type" "str")
18773    (set_attr "prefix_rep" "1")
18774    (set_attr "memory" "store")
18775    (set_attr "mode" "SI")])
18776
18777 (define_insn "*rep_stossi_rex64"
18778   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18779    (set (match_operand:DI 0 "register_operand" "=D")
18780         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18781                             (const_int 2))
18782                  (match_operand:DI 3 "register_operand" "0")))
18783    (set (mem:BLK (match_dup 3))
18784         (const_int 0))
18785    (use (match_operand:SI 2 "register_operand" "a"))
18786    (use (match_dup 4))]
18787   "TARGET_64BIT"
18788   "{rep\;stosl|rep stosd}"
18789   [(set_attr "type" "str")
18790    (set_attr "prefix_rep" "1")
18791    (set_attr "memory" "store")
18792    (set_attr "mode" "SI")])
18793
18794 (define_insn "*rep_stosqi"
18795   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18796    (set (match_operand:SI 0 "register_operand" "=D")
18797         (plus:SI (match_operand:SI 3 "register_operand" "0")
18798                  (match_operand:SI 4 "register_operand" "1")))
18799    (set (mem:BLK (match_dup 3))
18800         (const_int 0))
18801    (use (match_operand:QI 2 "register_operand" "a"))
18802    (use (match_dup 4))]
18803   "!TARGET_64BIT"
18804   "{rep\;stosb|rep stosb}"
18805   [(set_attr "type" "str")
18806    (set_attr "prefix_rep" "1")
18807    (set_attr "memory" "store")
18808    (set_attr "mode" "QI")])
18809
18810 (define_insn "*rep_stosqi_rex64"
18811   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18812    (set (match_operand:DI 0 "register_operand" "=D")
18813         (plus:DI (match_operand:DI 3 "register_operand" "0")
18814                  (match_operand:DI 4 "register_operand" "1")))
18815    (set (mem:BLK (match_dup 3))
18816         (const_int 0))
18817    (use (match_operand:QI 2 "register_operand" "a"))
18818    (use (match_dup 4))]
18819   "TARGET_64BIT"
18820   "{rep\;stosb|rep stosb}"
18821   [(set_attr "type" "str")
18822    (set_attr "prefix_rep" "1")
18823    (set_attr "memory" "store")
18824    (set_attr "mode" "QI")])
18825
18826 (define_expand "cmpstrnsi"
18827   [(set (match_operand:SI 0 "register_operand" "")
18828         (compare:SI (match_operand:BLK 1 "general_operand" "")
18829                     (match_operand:BLK 2 "general_operand" "")))
18830    (use (match_operand 3 "general_operand" ""))
18831    (use (match_operand 4 "immediate_operand" ""))]
18832   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18833 {
18834   rtx addr1, addr2, out, outlow, count, countreg, align;
18835
18836   /* Can't use this if the user has appropriated esi or edi.  */
18837   if (global_regs[4] || global_regs[5])
18838     FAIL;
18839
18840   out = operands[0];
18841   if (!REG_P (out))
18842     out = gen_reg_rtx (SImode);
18843
18844   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18845   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18846   if (addr1 != XEXP (operands[1], 0))
18847     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18848   if (addr2 != XEXP (operands[2], 0))
18849     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18850
18851   count = operands[3];
18852   countreg = ix86_zero_extend_to_Pmode (count);
18853
18854   /* %%% Iff we are testing strict equality, we can use known alignment
18855      to good advantage.  This may be possible with combine, particularly
18856      once cc0 is dead.  */
18857   align = operands[4];
18858
18859   if (CONST_INT_P (count))
18860     {
18861       if (INTVAL (count) == 0)
18862         {
18863           emit_move_insn (operands[0], const0_rtx);
18864           DONE;
18865         }
18866       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18867                                      operands[1], operands[2]));
18868     }
18869   else
18870     {
18871       if (TARGET_64BIT)
18872         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18873       else
18874         emit_insn (gen_cmpsi_1 (countreg, countreg));
18875       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18876                                   operands[1], operands[2]));
18877     }
18878
18879   outlow = gen_lowpart (QImode, out);
18880   emit_insn (gen_cmpintqi (outlow));
18881   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18882
18883   if (operands[0] != out)
18884     emit_move_insn (operands[0], out);
18885
18886   DONE;
18887 })
18888
18889 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18890
18891 (define_expand "cmpintqi"
18892   [(set (match_dup 1)
18893         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18894    (set (match_dup 2)
18895         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18896    (parallel [(set (match_operand:QI 0 "register_operand" "")
18897                    (minus:QI (match_dup 1)
18898                              (match_dup 2)))
18899               (clobber (reg:CC FLAGS_REG))])]
18900   ""
18901   "operands[1] = gen_reg_rtx (QImode);
18902    operands[2] = gen_reg_rtx (QImode);")
18903
18904 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18905 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18906
18907 (define_expand "cmpstrnqi_nz_1"
18908   [(parallel [(set (reg:CC FLAGS_REG)
18909                    (compare:CC (match_operand 4 "memory_operand" "")
18910                                (match_operand 5 "memory_operand" "")))
18911               (use (match_operand 2 "register_operand" ""))
18912               (use (match_operand:SI 3 "immediate_operand" ""))
18913               (clobber (match_operand 0 "register_operand" ""))
18914               (clobber (match_operand 1 "register_operand" ""))
18915               (clobber (match_dup 2))])]
18916   ""
18917   "")
18918
18919 (define_insn "*cmpstrnqi_nz_1"
18920   [(set (reg:CC FLAGS_REG)
18921         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18922                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18923    (use (match_operand:SI 6 "register_operand" "2"))
18924    (use (match_operand:SI 3 "immediate_operand" "i"))
18925    (clobber (match_operand:SI 0 "register_operand" "=S"))
18926    (clobber (match_operand:SI 1 "register_operand" "=D"))
18927    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18928   "!TARGET_64BIT"
18929   "repz{\;| }cmpsb"
18930   [(set_attr "type" "str")
18931    (set_attr "mode" "QI")
18932    (set_attr "prefix_rep" "1")])
18933
18934 (define_insn "*cmpstrnqi_nz_rex_1"
18935   [(set (reg:CC FLAGS_REG)
18936         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18937                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18938    (use (match_operand:DI 6 "register_operand" "2"))
18939    (use (match_operand:SI 3 "immediate_operand" "i"))
18940    (clobber (match_operand:DI 0 "register_operand" "=S"))
18941    (clobber (match_operand:DI 1 "register_operand" "=D"))
18942    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18943   "TARGET_64BIT"
18944   "repz{\;| }cmpsb"
18945   [(set_attr "type" "str")
18946    (set_attr "mode" "QI")
18947    (set_attr "prefix_rep" "1")])
18948
18949 ;; The same, but the count is not known to not be zero.
18950
18951 (define_expand "cmpstrnqi_1"
18952   [(parallel [(set (reg:CC FLAGS_REG)
18953                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18954                                      (const_int 0))
18955                   (compare:CC (match_operand 4 "memory_operand" "")
18956                               (match_operand 5 "memory_operand" ""))
18957                   (const_int 0)))
18958               (use (match_operand:SI 3 "immediate_operand" ""))
18959               (use (reg:CC FLAGS_REG))
18960               (clobber (match_operand 0 "register_operand" ""))
18961               (clobber (match_operand 1 "register_operand" ""))
18962               (clobber (match_dup 2))])]
18963   ""
18964   "")
18965
18966 (define_insn "*cmpstrnqi_1"
18967   [(set (reg:CC FLAGS_REG)
18968         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18969                              (const_int 0))
18970           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18971                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18972           (const_int 0)))
18973    (use (match_operand:SI 3 "immediate_operand" "i"))
18974    (use (reg:CC FLAGS_REG))
18975    (clobber (match_operand:SI 0 "register_operand" "=S"))
18976    (clobber (match_operand:SI 1 "register_operand" "=D"))
18977    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18978   "!TARGET_64BIT"
18979   "repz{\;| }cmpsb"
18980   [(set_attr "type" "str")
18981    (set_attr "mode" "QI")
18982    (set_attr "prefix_rep" "1")])
18983
18984 (define_insn "*cmpstrnqi_rex_1"
18985   [(set (reg:CC FLAGS_REG)
18986         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18987                              (const_int 0))
18988           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18989                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18990           (const_int 0)))
18991    (use (match_operand:SI 3 "immediate_operand" "i"))
18992    (use (reg:CC FLAGS_REG))
18993    (clobber (match_operand:DI 0 "register_operand" "=S"))
18994    (clobber (match_operand:DI 1 "register_operand" "=D"))
18995    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18996   "TARGET_64BIT"
18997   "repz{\;| }cmpsb"
18998   [(set_attr "type" "str")
18999    (set_attr "mode" "QI")
19000    (set_attr "prefix_rep" "1")])
19001
19002 (define_expand "strlensi"
19003   [(set (match_operand:SI 0 "register_operand" "")
19004         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19005                     (match_operand:QI 2 "immediate_operand" "")
19006                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19007   ""
19008 {
19009  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19010    DONE;
19011  else
19012    FAIL;
19013 })
19014
19015 (define_expand "strlendi"
19016   [(set (match_operand:DI 0 "register_operand" "")
19017         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19018                     (match_operand:QI 2 "immediate_operand" "")
19019                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19020   ""
19021 {
19022  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19023    DONE;
19024  else
19025    FAIL;
19026 })
19027
19028 (define_expand "strlenqi_1"
19029   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19030               (clobber (match_operand 1 "register_operand" ""))
19031               (clobber (reg:CC FLAGS_REG))])]
19032   ""
19033   "")
19034
19035 (define_insn "*strlenqi_1"
19036   [(set (match_operand:SI 0 "register_operand" "=&c")
19037         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19038                     (match_operand:QI 2 "register_operand" "a")
19039                     (match_operand:SI 3 "immediate_operand" "i")
19040                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19041    (clobber (match_operand:SI 1 "register_operand" "=D"))
19042    (clobber (reg:CC FLAGS_REG))]
19043   "!TARGET_64BIT"
19044   "repnz{\;| }scasb"
19045   [(set_attr "type" "str")
19046    (set_attr "mode" "QI")
19047    (set_attr "prefix_rep" "1")])
19048
19049 (define_insn "*strlenqi_rex_1"
19050   [(set (match_operand:DI 0 "register_operand" "=&c")
19051         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19052                     (match_operand:QI 2 "register_operand" "a")
19053                     (match_operand:DI 3 "immediate_operand" "i")
19054                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19055    (clobber (match_operand:DI 1 "register_operand" "=D"))
19056    (clobber (reg:CC FLAGS_REG))]
19057   "TARGET_64BIT"
19058   "repnz{\;| }scasb"
19059   [(set_attr "type" "str")
19060    (set_attr "mode" "QI")
19061    (set_attr "prefix_rep" "1")])
19062
19063 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19064 ;; handled in combine, but it is not currently up to the task.
19065 ;; When used for their truth value, the cmpstrn* expanders generate
19066 ;; code like this:
19067 ;;
19068 ;;   repz cmpsb
19069 ;;   seta       %al
19070 ;;   setb       %dl
19071 ;;   cmpb       %al, %dl
19072 ;;   jcc        label
19073 ;;
19074 ;; The intermediate three instructions are unnecessary.
19075
19076 ;; This one handles cmpstrn*_nz_1...
19077 (define_peephole2
19078   [(parallel[
19079      (set (reg:CC FLAGS_REG)
19080           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19081                       (mem:BLK (match_operand 5 "register_operand" ""))))
19082      (use (match_operand 6 "register_operand" ""))
19083      (use (match_operand:SI 3 "immediate_operand" ""))
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           (compare:CC (mem:BLK (match_dup 4))
19098                       (mem:BLK (match_dup 5))))
19099      (use (match_dup 6))
19100      (use (match_dup 3))
19101      (clobber (match_dup 0))
19102      (clobber (match_dup 1))
19103      (clobber (match_dup 2))])]
19104   "")
19105
19106 ;; ...and this one handles cmpstrn*_1.
19107 (define_peephole2
19108   [(parallel[
19109      (set (reg:CC FLAGS_REG)
19110           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19111                                (const_int 0))
19112             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19113                         (mem:BLK (match_operand 5 "register_operand" "")))
19114             (const_int 0)))
19115      (use (match_operand:SI 3 "immediate_operand" ""))
19116      (use (reg:CC FLAGS_REG))
19117      (clobber (match_operand 0 "register_operand" ""))
19118      (clobber (match_operand 1 "register_operand" ""))
19119      (clobber (match_operand 2 "register_operand" ""))])
19120    (set (match_operand:QI 7 "register_operand" "")
19121         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19122    (set (match_operand:QI 8 "register_operand" "")
19123         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19124    (set (reg FLAGS_REG)
19125         (compare (match_dup 7) (match_dup 8)))
19126   ]
19127   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19128   [(parallel[
19129      (set (reg:CC FLAGS_REG)
19130           (if_then_else:CC (ne (match_dup 6)
19131                                (const_int 0))
19132             (compare:CC (mem:BLK (match_dup 4))
19133                         (mem:BLK (match_dup 5)))
19134             (const_int 0)))
19135      (use (match_dup 3))
19136      (use (reg:CC FLAGS_REG))
19137      (clobber (match_dup 0))
19138      (clobber (match_dup 1))
19139      (clobber (match_dup 2))])]
19140   "")
19141
19142
19143 \f
19144 ;; Conditional move instructions.
19145
19146 (define_expand "movdicc"
19147   [(set (match_operand:DI 0 "register_operand" "")
19148         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19149                          (match_operand:DI 2 "general_operand" "")
19150                          (match_operand:DI 3 "general_operand" "")))]
19151   "TARGET_64BIT"
19152   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19153
19154 (define_insn "x86_movdicc_0_m1_rex64"
19155   [(set (match_operand:DI 0 "register_operand" "=r")
19156         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19157           (const_int -1)
19158           (const_int 0)))
19159    (clobber (reg:CC FLAGS_REG))]
19160   "TARGET_64BIT"
19161   "sbb{q}\t%0, %0"
19162   ; Since we don't have the proper number of operands for an alu insn,
19163   ; fill in all the blanks.
19164   [(set_attr "type" "alu")
19165    (set_attr "pent_pair" "pu")
19166    (set_attr "memory" "none")
19167    (set_attr "imm_disp" "false")
19168    (set_attr "mode" "DI")
19169    (set_attr "length_immediate" "0")])
19170
19171 (define_insn "*movdicc_c_rex64"
19172   [(set (match_operand:DI 0 "register_operand" "=r,r")
19173         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19174                                 [(reg FLAGS_REG) (const_int 0)])
19175                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19176                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19177   "TARGET_64BIT && TARGET_CMOVE
19178    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19179   "@
19180    cmov%O2%C1\t{%2, %0|%0, %2}
19181    cmov%O2%c1\t{%3, %0|%0, %3}"
19182   [(set_attr "type" "icmov")
19183    (set_attr "mode" "DI")])
19184
19185 (define_expand "movsicc"
19186   [(set (match_operand:SI 0 "register_operand" "")
19187         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19188                          (match_operand:SI 2 "general_operand" "")
19189                          (match_operand:SI 3 "general_operand" "")))]
19190   ""
19191   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19192
19193 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19194 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19195 ;; So just document what we're doing explicitly.
19196
19197 (define_insn "x86_movsicc_0_m1"
19198   [(set (match_operand:SI 0 "register_operand" "=r")
19199         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19200           (const_int -1)
19201           (const_int 0)))
19202    (clobber (reg:CC FLAGS_REG))]
19203   ""
19204   "sbb{l}\t%0, %0"
19205   ; Since we don't have the proper number of operands for an alu insn,
19206   ; fill in all the blanks.
19207   [(set_attr "type" "alu")
19208    (set_attr "pent_pair" "pu")
19209    (set_attr "memory" "none")
19210    (set_attr "imm_disp" "false")
19211    (set_attr "mode" "SI")
19212    (set_attr "length_immediate" "0")])
19213
19214 (define_insn "*movsicc_noc"
19215   [(set (match_operand:SI 0 "register_operand" "=r,r")
19216         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19217                                 [(reg FLAGS_REG) (const_int 0)])
19218                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19219                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19220   "TARGET_CMOVE
19221    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19222   "@
19223    cmov%O2%C1\t{%2, %0|%0, %2}
19224    cmov%O2%c1\t{%3, %0|%0, %3}"
19225   [(set_attr "type" "icmov")
19226    (set_attr "mode" "SI")])
19227
19228 (define_expand "movhicc"
19229   [(set (match_operand:HI 0 "register_operand" "")
19230         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19231                          (match_operand:HI 2 "general_operand" "")
19232                          (match_operand:HI 3 "general_operand" "")))]
19233   "TARGET_HIMODE_MATH"
19234   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19235
19236 (define_insn "*movhicc_noc"
19237   [(set (match_operand:HI 0 "register_operand" "=r,r")
19238         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19239                                 [(reg FLAGS_REG) (const_int 0)])
19240                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19241                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19242   "TARGET_CMOVE
19243    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19244   "@
19245    cmov%O2%C1\t{%2, %0|%0, %2}
19246    cmov%O2%c1\t{%3, %0|%0, %3}"
19247   [(set_attr "type" "icmov")
19248    (set_attr "mode" "HI")])
19249
19250 (define_expand "movqicc"
19251   [(set (match_operand:QI 0 "register_operand" "")
19252         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19253                          (match_operand:QI 2 "general_operand" "")
19254                          (match_operand:QI 3 "general_operand" "")))]
19255   "TARGET_QIMODE_MATH"
19256   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19257
19258 (define_insn_and_split "*movqicc_noc"
19259   [(set (match_operand:QI 0 "register_operand" "=r,r")
19260         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19261                                 [(match_operand 4 "flags_reg_operand" "")
19262                                  (const_int 0)])
19263                       (match_operand:QI 2 "register_operand" "r,0")
19264                       (match_operand:QI 3 "register_operand" "0,r")))]
19265   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19266   "#"
19267   "&& reload_completed"
19268   [(set (match_dup 0)
19269         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19270                       (match_dup 2)
19271                       (match_dup 3)))]
19272   "operands[0] = gen_lowpart (SImode, operands[0]);
19273    operands[2] = gen_lowpart (SImode, operands[2]);
19274    operands[3] = gen_lowpart (SImode, operands[3]);"
19275   [(set_attr "type" "icmov")
19276    (set_attr "mode" "SI")])
19277
19278 (define_expand "movsfcc"
19279   [(set (match_operand:SF 0 "register_operand" "")
19280         (if_then_else:SF (match_operand 1 "comparison_operator" "")
19281                          (match_operand:SF 2 "register_operand" "")
19282                          (match_operand:SF 3 "register_operand" "")))]
19283   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19284   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19285
19286 (define_insn "*movsfcc_1_387"
19287   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19288         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19289                                 [(reg FLAGS_REG) (const_int 0)])
19290                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19291                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19292   "TARGET_80387 && TARGET_CMOVE
19293    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19294   "@
19295    fcmov%F1\t{%2, %0|%0, %2}
19296    fcmov%f1\t{%3, %0|%0, %3}
19297    cmov%O2%C1\t{%2, %0|%0, %2}
19298    cmov%O2%c1\t{%3, %0|%0, %3}"
19299   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19300    (set_attr "mode" "SF,SF,SI,SI")])
19301
19302 (define_expand "movdfcc"
19303   [(set (match_operand:DF 0 "register_operand" "")
19304         (if_then_else:DF (match_operand 1 "comparison_operator" "")
19305                          (match_operand:DF 2 "register_operand" "")
19306                          (match_operand:DF 3 "register_operand" "")))]
19307   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19308   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19309
19310 (define_insn "*movdfcc_1"
19311   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19312         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19313                                 [(reg FLAGS_REG) (const_int 0)])
19314                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19315                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19316   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19317    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19318   "@
19319    fcmov%F1\t{%2, %0|%0, %2}
19320    fcmov%f1\t{%3, %0|%0, %3}
19321    #
19322    #"
19323   [(set_attr "type" "fcmov,fcmov,multi,multi")
19324    (set_attr "mode" "DF")])
19325
19326 (define_insn "*movdfcc_1_rex64"
19327   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19328         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19329                                 [(reg FLAGS_REG) (const_int 0)])
19330                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19331                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19332   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19333    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19334   "@
19335    fcmov%F1\t{%2, %0|%0, %2}
19336    fcmov%f1\t{%3, %0|%0, %3}
19337    cmov%O2%C1\t{%2, %0|%0, %2}
19338    cmov%O2%c1\t{%3, %0|%0, %3}"
19339   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19340    (set_attr "mode" "DF")])
19341
19342 (define_split
19343   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19344         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19345                                 [(match_operand 4 "flags_reg_operand" "")
19346                                  (const_int 0)])
19347                       (match_operand:DF 2 "nonimmediate_operand" "")
19348                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19349   "!TARGET_64BIT && reload_completed"
19350   [(set (match_dup 2)
19351         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19352                       (match_dup 5)
19353                       (match_dup 7)))
19354    (set (match_dup 3)
19355         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19356                       (match_dup 6)
19357                       (match_dup 8)))]
19358   "split_di (operands+2, 1, operands+5, operands+6);
19359    split_di (operands+3, 1, operands+7, operands+8);
19360    split_di (operands, 1, operands+2, operands+3);")
19361
19362 (define_expand "movxfcc"
19363   [(set (match_operand:XF 0 "register_operand" "")
19364         (if_then_else:XF (match_operand 1 "comparison_operator" "")
19365                          (match_operand:XF 2 "register_operand" "")
19366                          (match_operand:XF 3 "register_operand" "")))]
19367   "TARGET_80387 && TARGET_CMOVE"
19368   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19369
19370 (define_insn "*movxfcc_1"
19371   [(set (match_operand:XF 0 "register_operand" "=f,f")
19372         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19373                                 [(reg FLAGS_REG) (const_int 0)])
19374                       (match_operand:XF 2 "register_operand" "f,0")
19375                       (match_operand:XF 3 "register_operand" "0,f")))]
19376   "TARGET_80387 && TARGET_CMOVE"
19377   "@
19378    fcmov%F1\t{%2, %0|%0, %2}
19379    fcmov%f1\t{%3, %0|%0, %3}"
19380   [(set_attr "type" "fcmov")
19381    (set_attr "mode" "XF")])
19382
19383 ;; These versions of the min/max patterns are intentionally ignorant of
19384 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19385 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19386 ;; are undefined in this condition, we're certain this is correct.
19387
19388 (define_insn "sminsf3"
19389   [(set (match_operand:SF 0 "register_operand" "=x")
19390         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19391                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19392   "TARGET_SSE_MATH"
19393   "minss\t{%2, %0|%0, %2}"
19394   [(set_attr "type" "sseadd")
19395    (set_attr "mode" "SF")])
19396
19397 (define_insn "smaxsf3"
19398   [(set (match_operand:SF 0 "register_operand" "=x")
19399         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19400                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19401   "TARGET_SSE_MATH"
19402   "maxss\t{%2, %0|%0, %2}"
19403   [(set_attr "type" "sseadd")
19404    (set_attr "mode" "SF")])
19405
19406 (define_insn "smindf3"
19407   [(set (match_operand:DF 0 "register_operand" "=x")
19408         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19409                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19410   "TARGET_SSE2 && TARGET_SSE_MATH"
19411   "minsd\t{%2, %0|%0, %2}"
19412   [(set_attr "type" "sseadd")
19413    (set_attr "mode" "DF")])
19414
19415 (define_insn "smaxdf3"
19416   [(set (match_operand:DF 0 "register_operand" "=x")
19417         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19418                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19419   "TARGET_SSE2 && TARGET_SSE_MATH"
19420   "maxsd\t{%2, %0|%0, %2}"
19421   [(set_attr "type" "sseadd")
19422    (set_attr "mode" "DF")])
19423
19424 ;; These versions of the min/max patterns implement exactly the operations
19425 ;;   min = (op1 < op2 ? op1 : op2)
19426 ;;   max = (!(op1 < op2) ? op1 : op2)
19427 ;; Their operands are not commutative, and thus they may be used in the
19428 ;; presence of -0.0 and NaN.
19429
19430 (define_insn "*ieee_sminsf3"
19431   [(set (match_operand:SF 0 "register_operand" "=x")
19432         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19433                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19434                    UNSPEC_IEEE_MIN))]
19435   "TARGET_SSE_MATH"
19436   "minss\t{%2, %0|%0, %2}"
19437   [(set_attr "type" "sseadd")
19438    (set_attr "mode" "SF")])
19439
19440 (define_insn "*ieee_smaxsf3"
19441   [(set (match_operand:SF 0 "register_operand" "=x")
19442         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19443                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19444                    UNSPEC_IEEE_MAX))]
19445   "TARGET_SSE_MATH"
19446   "maxss\t{%2, %0|%0, %2}"
19447   [(set_attr "type" "sseadd")
19448    (set_attr "mode" "SF")])
19449
19450 (define_insn "*ieee_smindf3"
19451   [(set (match_operand:DF 0 "register_operand" "=x")
19452         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19453                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19454                    UNSPEC_IEEE_MIN))]
19455   "TARGET_SSE2 && TARGET_SSE_MATH"
19456   "minsd\t{%2, %0|%0, %2}"
19457   [(set_attr "type" "sseadd")
19458    (set_attr "mode" "DF")])
19459
19460 (define_insn "*ieee_smaxdf3"
19461   [(set (match_operand:DF 0 "register_operand" "=x")
19462         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19463                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19464                    UNSPEC_IEEE_MAX))]
19465   "TARGET_SSE2 && TARGET_SSE_MATH"
19466   "maxsd\t{%2, %0|%0, %2}"
19467   [(set_attr "type" "sseadd")
19468    (set_attr "mode" "DF")])
19469
19470 ;; Make two stack loads independent:
19471 ;;   fld aa              fld aa
19472 ;;   fld %st(0)     ->   fld bb
19473 ;;   fmul bb             fmul %st(1), %st
19474 ;;
19475 ;; Actually we only match the last two instructions for simplicity.
19476 (define_peephole2
19477   [(set (match_operand 0 "fp_register_operand" "")
19478         (match_operand 1 "fp_register_operand" ""))
19479    (set (match_dup 0)
19480         (match_operator 2 "binary_fp_operator"
19481            [(match_dup 0)
19482             (match_operand 3 "memory_operand" "")]))]
19483   "REGNO (operands[0]) != REGNO (operands[1])"
19484   [(set (match_dup 0) (match_dup 3))
19485    (set (match_dup 0) (match_dup 4))]
19486
19487   ;; The % modifier is not operational anymore in peephole2's, so we have to
19488   ;; swap the operands manually in the case of addition and multiplication.
19489   "if (COMMUTATIVE_ARITH_P (operands[2]))
19490      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19491                                  operands[0], operands[1]);
19492    else
19493      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19494                                  operands[1], operands[0]);")
19495
19496 ;; Conditional addition patterns
19497 (define_expand "addqicc"
19498   [(match_operand:QI 0 "register_operand" "")
19499    (match_operand 1 "comparison_operator" "")
19500    (match_operand:QI 2 "register_operand" "")
19501    (match_operand:QI 3 "const_int_operand" "")]
19502   ""
19503   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19504
19505 (define_expand "addhicc"
19506   [(match_operand:HI 0 "register_operand" "")
19507    (match_operand 1 "comparison_operator" "")
19508    (match_operand:HI 2 "register_operand" "")
19509    (match_operand:HI 3 "const_int_operand" "")]
19510   ""
19511   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19512
19513 (define_expand "addsicc"
19514   [(match_operand:SI 0 "register_operand" "")
19515    (match_operand 1 "comparison_operator" "")
19516    (match_operand:SI 2 "register_operand" "")
19517    (match_operand:SI 3 "const_int_operand" "")]
19518   ""
19519   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19520
19521 (define_expand "adddicc"
19522   [(match_operand:DI 0 "register_operand" "")
19523    (match_operand 1 "comparison_operator" "")
19524    (match_operand:DI 2 "register_operand" "")
19525    (match_operand:DI 3 "const_int_operand" "")]
19526   "TARGET_64BIT"
19527   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19528
19529 \f
19530 ;; Misc patterns (?)
19531
19532 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19533 ;; Otherwise there will be nothing to keep
19534 ;;
19535 ;; [(set (reg ebp) (reg esp))]
19536 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19537 ;;  (clobber (eflags)]
19538 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19539 ;;
19540 ;; in proper program order.
19541 (define_insn "pro_epilogue_adjust_stack_1"
19542   [(set (match_operand:SI 0 "register_operand" "=r,r")
19543         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19544                  (match_operand:SI 2 "immediate_operand" "i,i")))
19545    (clobber (reg:CC FLAGS_REG))
19546    (clobber (mem:BLK (scratch)))]
19547   "!TARGET_64BIT"
19548 {
19549   switch (get_attr_type (insn))
19550     {
19551     case TYPE_IMOV:
19552       return "mov{l}\t{%1, %0|%0, %1}";
19553
19554     case TYPE_ALU:
19555       if (CONST_INT_P (operands[2])
19556           && (INTVAL (operands[2]) == 128
19557               || (INTVAL (operands[2]) < 0
19558                   && INTVAL (operands[2]) != -128)))
19559         {
19560           operands[2] = GEN_INT (-INTVAL (operands[2]));
19561           return "sub{l}\t{%2, %0|%0, %2}";
19562         }
19563       return "add{l}\t{%2, %0|%0, %2}";
19564
19565     case TYPE_LEA:
19566       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19567       return "lea{l}\t{%a2, %0|%0, %a2}";
19568
19569     default:
19570       gcc_unreachable ();
19571     }
19572 }
19573   [(set (attr "type")
19574         (cond [(eq_attr "alternative" "0")
19575                  (const_string "alu")
19576                (match_operand:SI 2 "const0_operand" "")
19577                  (const_string "imov")
19578               ]
19579               (const_string "lea")))
19580    (set_attr "mode" "SI")])
19581
19582 (define_insn "pro_epilogue_adjust_stack_rex64"
19583   [(set (match_operand:DI 0 "register_operand" "=r,r")
19584         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19585                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19586    (clobber (reg:CC FLAGS_REG))
19587    (clobber (mem:BLK (scratch)))]
19588   "TARGET_64BIT"
19589 {
19590   switch (get_attr_type (insn))
19591     {
19592     case TYPE_IMOV:
19593       return "mov{q}\t{%1, %0|%0, %1}";
19594
19595     case TYPE_ALU:
19596       if (CONST_INT_P (operands[2])
19597           /* Avoid overflows.  */
19598           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19599           && (INTVAL (operands[2]) == 128
19600               || (INTVAL (operands[2]) < 0
19601                   && INTVAL (operands[2]) != -128)))
19602         {
19603           operands[2] = GEN_INT (-INTVAL (operands[2]));
19604           return "sub{q}\t{%2, %0|%0, %2}";
19605         }
19606       return "add{q}\t{%2, %0|%0, %2}";
19607
19608     case TYPE_LEA:
19609       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19610       return "lea{q}\t{%a2, %0|%0, %a2}";
19611
19612     default:
19613       gcc_unreachable ();
19614     }
19615 }
19616   [(set (attr "type")
19617         (cond [(eq_attr "alternative" "0")
19618                  (const_string "alu")
19619                (match_operand:DI 2 "const0_operand" "")
19620                  (const_string "imov")
19621               ]
19622               (const_string "lea")))
19623    (set_attr "mode" "DI")])
19624
19625 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19626   [(set (match_operand:DI 0 "register_operand" "=r,r")
19627         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19628                  (match_operand:DI 3 "immediate_operand" "i,i")))
19629    (use (match_operand:DI 2 "register_operand" "r,r"))
19630    (clobber (reg:CC FLAGS_REG))
19631    (clobber (mem:BLK (scratch)))]
19632   "TARGET_64BIT"
19633 {
19634   switch (get_attr_type (insn))
19635     {
19636     case TYPE_ALU:
19637       return "add{q}\t{%2, %0|%0, %2}";
19638
19639     case TYPE_LEA:
19640       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19641       return "lea{q}\t{%a2, %0|%0, %a2}";
19642
19643     default:
19644       gcc_unreachable ();
19645     }
19646 }
19647   [(set_attr "type" "alu,lea")
19648    (set_attr "mode" "DI")])
19649
19650 (define_expand "allocate_stack_worker"
19651   [(match_operand:SI 0 "register_operand" "")]
19652   "TARGET_STACK_PROBE"
19653 {
19654   if (reload_completed)
19655     {
19656       if (TARGET_64BIT)
19657         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19658       else
19659         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19660     }
19661   else
19662     {
19663       if (TARGET_64BIT)
19664         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19665       else
19666         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19667     }
19668   DONE;
19669 })
19670
19671 (define_insn "allocate_stack_worker_1"
19672   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19673     UNSPECV_STACK_PROBE)
19674    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19675    (clobber (match_scratch:SI 1 "=0"))
19676    (clobber (reg:CC FLAGS_REG))]
19677   "!TARGET_64BIT && TARGET_STACK_PROBE"
19678   "call\t__alloca"
19679   [(set_attr "type" "multi")
19680    (set_attr "length" "5")])
19681
19682 (define_expand "allocate_stack_worker_postreload"
19683   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19684                                     UNSPECV_STACK_PROBE)
19685               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19686               (clobber (match_dup 0))
19687               (clobber (reg:CC FLAGS_REG))])]
19688   ""
19689   "")
19690
19691 (define_insn "allocate_stack_worker_rex64"
19692   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19693     UNSPECV_STACK_PROBE)
19694    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19695    (clobber (match_scratch:DI 1 "=0"))
19696    (clobber (reg:CC FLAGS_REG))]
19697   "TARGET_64BIT && TARGET_STACK_PROBE"
19698   "call\t__alloca"
19699   [(set_attr "type" "multi")
19700    (set_attr "length" "5")])
19701
19702 (define_expand "allocate_stack_worker_rex64_postreload"
19703   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19704                                     UNSPECV_STACK_PROBE)
19705               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19706               (clobber (match_dup 0))
19707               (clobber (reg:CC FLAGS_REG))])]
19708   ""
19709   "")
19710
19711 (define_expand "allocate_stack"
19712   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19713                    (minus:SI (reg:SI SP_REG)
19714                              (match_operand:SI 1 "general_operand" "")))
19715               (clobber (reg:CC FLAGS_REG))])
19716    (parallel [(set (reg:SI SP_REG)
19717                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
19718               (clobber (reg:CC FLAGS_REG))])]
19719   "TARGET_STACK_PROBE"
19720 {
19721 #ifdef CHECK_STACK_LIMIT
19722   if (CONST_INT_P (operands[1])
19723       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19724     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19725                            operands[1]));
19726   else
19727 #endif
19728     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19729                                                             operands[1])));
19730
19731   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19732   DONE;
19733 })
19734
19735 (define_expand "builtin_setjmp_receiver"
19736   [(label_ref (match_operand 0 "" ""))]
19737   "!TARGET_64BIT && flag_pic"
19738 {
19739   if (TARGET_MACHO)
19740     {
19741       rtx xops[3];
19742       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19743       rtx label_rtx = gen_label_rtx ();
19744       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19745       xops[0] = xops[1] = picreg;
19746       xops[2] = gen_rtx_CONST (SImode,
19747                   gen_rtx_MINUS (SImode,
19748                     gen_rtx_LABEL_REF (SImode, label_rtx),
19749                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19750       ix86_expand_binary_operator (MINUS, SImode, xops);
19751     }
19752   else
19753     emit_insn (gen_set_got (pic_offset_table_rtx));
19754   DONE;
19755 })
19756 \f
19757 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19758
19759 (define_split
19760   [(set (match_operand 0 "register_operand" "")
19761         (match_operator 3 "promotable_binary_operator"
19762            [(match_operand 1 "register_operand" "")
19763             (match_operand 2 "aligned_operand" "")]))
19764    (clobber (reg:CC FLAGS_REG))]
19765   "! TARGET_PARTIAL_REG_STALL && reload_completed
19766    && ((GET_MODE (operands[0]) == HImode
19767         && ((!optimize_size && !TARGET_FAST_PREFIX)
19768             /* ??? next two lines just !satisfies_constraint_K (...) */
19769             || !CONST_INT_P (operands[2])
19770             || satisfies_constraint_K (operands[2])))
19771        || (GET_MODE (operands[0]) == QImode
19772            && (TARGET_PROMOTE_QImode || optimize_size)))"
19773   [(parallel [(set (match_dup 0)
19774                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19775               (clobber (reg:CC FLAGS_REG))])]
19776   "operands[0] = gen_lowpart (SImode, operands[0]);
19777    operands[1] = gen_lowpart (SImode, operands[1]);
19778    if (GET_CODE (operands[3]) != ASHIFT)
19779      operands[2] = gen_lowpart (SImode, operands[2]);
19780    PUT_MODE (operands[3], SImode);")
19781
19782 ; Promote the QImode tests, as i386 has encoding of the AND
19783 ; instruction with 32-bit sign-extended immediate and thus the
19784 ; instruction size is unchanged, except in the %eax case for
19785 ; which it is increased by one byte, hence the ! optimize_size.
19786 (define_split
19787   [(set (match_operand 0 "flags_reg_operand" "")
19788         (match_operator 2 "compare_operator"
19789           [(and (match_operand 3 "aligned_operand" "")
19790                 (match_operand 4 "const_int_operand" ""))
19791            (const_int 0)]))
19792    (set (match_operand 1 "register_operand" "")
19793         (and (match_dup 3) (match_dup 4)))]
19794   "! TARGET_PARTIAL_REG_STALL && reload_completed
19795    /* Ensure that the operand will remain sign-extended immediate.  */
19796    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19797    && ! optimize_size
19798    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19799        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19800   [(parallel [(set (match_dup 0)
19801                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19802                                     (const_int 0)]))
19803               (set (match_dup 1)
19804                    (and:SI (match_dup 3) (match_dup 4)))])]
19805 {
19806   operands[4]
19807     = gen_int_mode (INTVAL (operands[4])
19808                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19809   operands[1] = gen_lowpart (SImode, operands[1]);
19810   operands[3] = gen_lowpart (SImode, operands[3]);
19811 })
19812
19813 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19814 ; the TEST instruction with 32-bit sign-extended immediate and thus
19815 ; the instruction size would at least double, which is not what we
19816 ; want even with ! optimize_size.
19817 (define_split
19818   [(set (match_operand 0 "flags_reg_operand" "")
19819         (match_operator 1 "compare_operator"
19820           [(and (match_operand:HI 2 "aligned_operand" "")
19821                 (match_operand:HI 3 "const_int_operand" ""))
19822            (const_int 0)]))]
19823   "! TARGET_PARTIAL_REG_STALL && reload_completed
19824    /* Ensure that the operand will remain sign-extended immediate.  */
19825    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19826    && ! TARGET_FAST_PREFIX
19827    && ! optimize_size"
19828   [(set (match_dup 0)
19829         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19830                          (const_int 0)]))]
19831 {
19832   operands[3]
19833     = gen_int_mode (INTVAL (operands[3])
19834                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19835   operands[2] = gen_lowpart (SImode, operands[2]);
19836 })
19837
19838 (define_split
19839   [(set (match_operand 0 "register_operand" "")
19840         (neg (match_operand 1 "register_operand" "")))
19841    (clobber (reg:CC FLAGS_REG))]
19842   "! TARGET_PARTIAL_REG_STALL && reload_completed
19843    && (GET_MODE (operands[0]) == HImode
19844        || (GET_MODE (operands[0]) == QImode
19845            && (TARGET_PROMOTE_QImode || optimize_size)))"
19846   [(parallel [(set (match_dup 0)
19847                    (neg:SI (match_dup 1)))
19848               (clobber (reg:CC FLAGS_REG))])]
19849   "operands[0] = gen_lowpart (SImode, operands[0]);
19850    operands[1] = gen_lowpart (SImode, operands[1]);")
19851
19852 (define_split
19853   [(set (match_operand 0 "register_operand" "")
19854         (not (match_operand 1 "register_operand" "")))]
19855   "! TARGET_PARTIAL_REG_STALL && reload_completed
19856    && (GET_MODE (operands[0]) == HImode
19857        || (GET_MODE (operands[0]) == QImode
19858            && (TARGET_PROMOTE_QImode || optimize_size)))"
19859   [(set (match_dup 0)
19860         (not:SI (match_dup 1)))]
19861   "operands[0] = gen_lowpart (SImode, operands[0]);
19862    operands[1] = gen_lowpart (SImode, operands[1]);")
19863
19864 (define_split
19865   [(set (match_operand 0 "register_operand" "")
19866         (if_then_else (match_operator 1 "comparison_operator"
19867                                 [(reg FLAGS_REG) (const_int 0)])
19868                       (match_operand 2 "register_operand" "")
19869                       (match_operand 3 "register_operand" "")))]
19870   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19871    && (GET_MODE (operands[0]) == HImode
19872        || (GET_MODE (operands[0]) == QImode
19873            && (TARGET_PROMOTE_QImode || optimize_size)))"
19874   [(set (match_dup 0)
19875         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19876   "operands[0] = gen_lowpart (SImode, operands[0]);
19877    operands[2] = gen_lowpart (SImode, operands[2]);
19878    operands[3] = gen_lowpart (SImode, operands[3]);")
19879
19880 \f
19881 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19882 ;; transform a complex memory operation into two memory to register operations.
19883
19884 ;; Don't push memory operands
19885 (define_peephole2
19886   [(set (match_operand:SI 0 "push_operand" "")
19887         (match_operand:SI 1 "memory_operand" ""))
19888    (match_scratch:SI 2 "r")]
19889   "!optimize_size && !TARGET_PUSH_MEMORY
19890    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19891   [(set (match_dup 2) (match_dup 1))
19892    (set (match_dup 0) (match_dup 2))]
19893   "")
19894
19895 (define_peephole2
19896   [(set (match_operand:DI 0 "push_operand" "")
19897         (match_operand:DI 1 "memory_operand" ""))
19898    (match_scratch:DI 2 "r")]
19899   "!optimize_size && !TARGET_PUSH_MEMORY
19900    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19901   [(set (match_dup 2) (match_dup 1))
19902    (set (match_dup 0) (match_dup 2))]
19903   "")
19904
19905 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19906 ;; SImode pushes.
19907 (define_peephole2
19908   [(set (match_operand:SF 0 "push_operand" "")
19909         (match_operand:SF 1 "memory_operand" ""))
19910    (match_scratch:SF 2 "r")]
19911   "!optimize_size && !TARGET_PUSH_MEMORY
19912    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19913   [(set (match_dup 2) (match_dup 1))
19914    (set (match_dup 0) (match_dup 2))]
19915   "")
19916
19917 (define_peephole2
19918   [(set (match_operand:HI 0 "push_operand" "")
19919         (match_operand:HI 1 "memory_operand" ""))
19920    (match_scratch:HI 2 "r")]
19921   "!optimize_size && !TARGET_PUSH_MEMORY
19922    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19923   [(set (match_dup 2) (match_dup 1))
19924    (set (match_dup 0) (match_dup 2))]
19925   "")
19926
19927 (define_peephole2
19928   [(set (match_operand:QI 0 "push_operand" "")
19929         (match_operand:QI 1 "memory_operand" ""))
19930    (match_scratch:QI 2 "q")]
19931   "!optimize_size && !TARGET_PUSH_MEMORY
19932    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19933   [(set (match_dup 2) (match_dup 1))
19934    (set (match_dup 0) (match_dup 2))]
19935   "")
19936
19937 ;; Don't move an immediate directly to memory when the instruction
19938 ;; gets too big.
19939 (define_peephole2
19940   [(match_scratch:SI 1 "r")
19941    (set (match_operand:SI 0 "memory_operand" "")
19942         (const_int 0))]
19943   "! optimize_size
19944    && ! TARGET_USE_MOV0
19945    && TARGET_SPLIT_LONG_MOVES
19946    && get_attr_length (insn) >= ix86_cost->large_insn
19947    && peep2_regno_dead_p (0, FLAGS_REG)"
19948   [(parallel [(set (match_dup 1) (const_int 0))
19949               (clobber (reg:CC FLAGS_REG))])
19950    (set (match_dup 0) (match_dup 1))]
19951   "")
19952
19953 (define_peephole2
19954   [(match_scratch:HI 1 "r")
19955    (set (match_operand:HI 0 "memory_operand" "")
19956         (const_int 0))]
19957   "! optimize_size
19958    && ! TARGET_USE_MOV0
19959    && TARGET_SPLIT_LONG_MOVES
19960    && get_attr_length (insn) >= ix86_cost->large_insn
19961    && peep2_regno_dead_p (0, FLAGS_REG)"
19962   [(parallel [(set (match_dup 2) (const_int 0))
19963               (clobber (reg:CC FLAGS_REG))])
19964    (set (match_dup 0) (match_dup 1))]
19965   "operands[2] = gen_lowpart (SImode, operands[1]);")
19966
19967 (define_peephole2
19968   [(match_scratch:QI 1 "q")
19969    (set (match_operand:QI 0 "memory_operand" "")
19970         (const_int 0))]
19971   "! optimize_size
19972    && ! TARGET_USE_MOV0
19973    && TARGET_SPLIT_LONG_MOVES
19974    && get_attr_length (insn) >= ix86_cost->large_insn
19975    && peep2_regno_dead_p (0, FLAGS_REG)"
19976   [(parallel [(set (match_dup 2) (const_int 0))
19977               (clobber (reg:CC FLAGS_REG))])
19978    (set (match_dup 0) (match_dup 1))]
19979   "operands[2] = gen_lowpart (SImode, operands[1]);")
19980
19981 (define_peephole2
19982   [(match_scratch:SI 2 "r")
19983    (set (match_operand:SI 0 "memory_operand" "")
19984         (match_operand:SI 1 "immediate_operand" ""))]
19985   "! optimize_size
19986    && get_attr_length (insn) >= ix86_cost->large_insn
19987    && TARGET_SPLIT_LONG_MOVES"
19988   [(set (match_dup 2) (match_dup 1))
19989    (set (match_dup 0) (match_dup 2))]
19990   "")
19991
19992 (define_peephole2
19993   [(match_scratch:HI 2 "r")
19994    (set (match_operand:HI 0 "memory_operand" "")
19995         (match_operand:HI 1 "immediate_operand" ""))]
19996   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19997   && TARGET_SPLIT_LONG_MOVES"
19998   [(set (match_dup 2) (match_dup 1))
19999    (set (match_dup 0) (match_dup 2))]
20000   "")
20001
20002 (define_peephole2
20003   [(match_scratch:QI 2 "q")
20004    (set (match_operand:QI 0 "memory_operand" "")
20005         (match_operand:QI 1 "immediate_operand" ""))]
20006   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
20007   && TARGET_SPLIT_LONG_MOVES"
20008   [(set (match_dup 2) (match_dup 1))
20009    (set (match_dup 0) (match_dup 2))]
20010   "")
20011
20012 ;; Don't compare memory with zero, load and use a test instead.
20013 (define_peephole2
20014   [(set (match_operand 0 "flags_reg_operand" "")
20015         (match_operator 1 "compare_operator"
20016           [(match_operand:SI 2 "memory_operand" "")
20017            (const_int 0)]))
20018    (match_scratch:SI 3 "r")]
20019   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
20020   [(set (match_dup 3) (match_dup 2))
20021    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20022   "")
20023
20024 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20025 ;; Don't split NOTs with a displacement operand, because resulting XOR
20026 ;; will not be pairable anyway.
20027 ;;
20028 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20029 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20030 ;; so this split helps here as well.
20031 ;;
20032 ;; Note: Can't do this as a regular split because we can't get proper
20033 ;; lifetime information then.
20034
20035 (define_peephole2
20036   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20037         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20038   "!optimize_size
20039    && peep2_regno_dead_p (0, FLAGS_REG)
20040    && ((TARGET_PENTIUM
20041         && (!MEM_P (operands[0])
20042             || !memory_displacement_operand (operands[0], SImode)))
20043        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
20044   [(parallel [(set (match_dup 0)
20045                    (xor:SI (match_dup 1) (const_int -1)))
20046               (clobber (reg:CC FLAGS_REG))])]
20047   "")
20048
20049 (define_peephole2
20050   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20051         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20052   "!optimize_size
20053    && peep2_regno_dead_p (0, FLAGS_REG)
20054    && ((TARGET_PENTIUM
20055         && (!MEM_P (operands[0])
20056             || !memory_displacement_operand (operands[0], HImode)))
20057        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
20058   [(parallel [(set (match_dup 0)
20059                    (xor:HI (match_dup 1) (const_int -1)))
20060               (clobber (reg:CC FLAGS_REG))])]
20061   "")
20062
20063 (define_peephole2
20064   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20065         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20066   "!optimize_size
20067    && peep2_regno_dead_p (0, FLAGS_REG)
20068    && ((TARGET_PENTIUM
20069         && (!MEM_P (operands[0])
20070             || !memory_displacement_operand (operands[0], QImode)))
20071        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
20072   [(parallel [(set (match_dup 0)
20073                    (xor:QI (match_dup 1) (const_int -1)))
20074               (clobber (reg:CC FLAGS_REG))])]
20075   "")
20076
20077 ;; Non pairable "test imm, reg" instructions can be translated to
20078 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20079 ;; byte opcode instead of two, have a short form for byte operands),
20080 ;; so do it for other CPUs as well.  Given that the value was dead,
20081 ;; this should not create any new dependencies.  Pass on the sub-word
20082 ;; versions if we're concerned about partial register stalls.
20083
20084 (define_peephole2
20085   [(set (match_operand 0 "flags_reg_operand" "")
20086         (match_operator 1 "compare_operator"
20087           [(and:SI (match_operand:SI 2 "register_operand" "")
20088                    (match_operand:SI 3 "immediate_operand" ""))
20089            (const_int 0)]))]
20090   "ix86_match_ccmode (insn, CCNOmode)
20091    && (true_regnum (operands[2]) != 0
20092        || satisfies_constraint_K (operands[3]))
20093    && peep2_reg_dead_p (1, operands[2])"
20094   [(parallel
20095      [(set (match_dup 0)
20096            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20097                             (const_int 0)]))
20098       (set (match_dup 2)
20099            (and:SI (match_dup 2) (match_dup 3)))])]
20100   "")
20101
20102 ;; We don't need to handle HImode case, because it will be promoted to SImode
20103 ;; on ! TARGET_PARTIAL_REG_STALL
20104
20105 (define_peephole2
20106   [(set (match_operand 0 "flags_reg_operand" "")
20107         (match_operator 1 "compare_operator"
20108           [(and:QI (match_operand:QI 2 "register_operand" "")
20109                    (match_operand:QI 3 "immediate_operand" ""))
20110            (const_int 0)]))]
20111   "! TARGET_PARTIAL_REG_STALL
20112    && ix86_match_ccmode (insn, CCNOmode)
20113    && true_regnum (operands[2]) != 0
20114    && peep2_reg_dead_p (1, operands[2])"
20115   [(parallel
20116      [(set (match_dup 0)
20117            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20118                             (const_int 0)]))
20119       (set (match_dup 2)
20120            (and:QI (match_dup 2) (match_dup 3)))])]
20121   "")
20122
20123 (define_peephole2
20124   [(set (match_operand 0 "flags_reg_operand" "")
20125         (match_operator 1 "compare_operator"
20126           [(and:SI
20127              (zero_extract:SI
20128                (match_operand 2 "ext_register_operand" "")
20129                (const_int 8)
20130                (const_int 8))
20131              (match_operand 3 "const_int_operand" ""))
20132            (const_int 0)]))]
20133   "! TARGET_PARTIAL_REG_STALL
20134    && ix86_match_ccmode (insn, CCNOmode)
20135    && true_regnum (operands[2]) != 0
20136    && peep2_reg_dead_p (1, operands[2])"
20137   [(parallel [(set (match_dup 0)
20138                    (match_op_dup 1
20139                      [(and:SI
20140                         (zero_extract:SI
20141                           (match_dup 2)
20142                           (const_int 8)
20143                           (const_int 8))
20144                         (match_dup 3))
20145                       (const_int 0)]))
20146               (set (zero_extract:SI (match_dup 2)
20147                                     (const_int 8)
20148                                     (const_int 8))
20149                    (and:SI
20150                      (zero_extract:SI
20151                        (match_dup 2)
20152                        (const_int 8)
20153                        (const_int 8))
20154                      (match_dup 3)))])]
20155   "")
20156
20157 ;; Don't do logical operations with memory inputs.
20158 (define_peephole2
20159   [(match_scratch:SI 2 "r")
20160    (parallel [(set (match_operand:SI 0 "register_operand" "")
20161                    (match_operator:SI 3 "arith_or_logical_operator"
20162                      [(match_dup 0)
20163                       (match_operand:SI 1 "memory_operand" "")]))
20164               (clobber (reg:CC FLAGS_REG))])]
20165   "! optimize_size && ! TARGET_READ_MODIFY"
20166   [(set (match_dup 2) (match_dup 1))
20167    (parallel [(set (match_dup 0)
20168                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20169               (clobber (reg:CC FLAGS_REG))])]
20170   "")
20171
20172 (define_peephole2
20173   [(match_scratch:SI 2 "r")
20174    (parallel [(set (match_operand:SI 0 "register_operand" "")
20175                    (match_operator:SI 3 "arith_or_logical_operator"
20176                      [(match_operand:SI 1 "memory_operand" "")
20177                       (match_dup 0)]))
20178               (clobber (reg:CC FLAGS_REG))])]
20179   "! optimize_size && ! TARGET_READ_MODIFY"
20180   [(set (match_dup 2) (match_dup 1))
20181    (parallel [(set (match_dup 0)
20182                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20183               (clobber (reg:CC FLAGS_REG))])]
20184   "")
20185
20186 ; Don't do logical operations with memory outputs
20187 ;
20188 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20189 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20190 ; the same decoder scheduling characteristics as the original.
20191
20192 (define_peephole2
20193   [(match_scratch:SI 2 "r")
20194    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20195                    (match_operator:SI 3 "arith_or_logical_operator"
20196                      [(match_dup 0)
20197                       (match_operand:SI 1 "nonmemory_operand" "")]))
20198               (clobber (reg:CC FLAGS_REG))])]
20199   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20200   [(set (match_dup 2) (match_dup 0))
20201    (parallel [(set (match_dup 2)
20202                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20203               (clobber (reg:CC FLAGS_REG))])
20204    (set (match_dup 0) (match_dup 2))]
20205   "")
20206
20207 (define_peephole2
20208   [(match_scratch:SI 2 "r")
20209    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20210                    (match_operator:SI 3 "arith_or_logical_operator"
20211                      [(match_operand:SI 1 "nonmemory_operand" "")
20212                       (match_dup 0)]))
20213               (clobber (reg:CC FLAGS_REG))])]
20214   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20215   [(set (match_dup 2) (match_dup 0))
20216    (parallel [(set (match_dup 2)
20217                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20218               (clobber (reg:CC FLAGS_REG))])
20219    (set (match_dup 0) (match_dup 2))]
20220   "")
20221
20222 ;; Attempt to always use XOR for zeroing registers.
20223 (define_peephole2
20224   [(set (match_operand 0 "register_operand" "")
20225         (match_operand 1 "const0_operand" ""))]
20226   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20227    && (! TARGET_USE_MOV0 || optimize_size)
20228    && GENERAL_REG_P (operands[0])
20229    && peep2_regno_dead_p (0, FLAGS_REG)"
20230   [(parallel [(set (match_dup 0) (const_int 0))
20231               (clobber (reg:CC FLAGS_REG))])]
20232 {
20233   operands[0] = gen_lowpart (word_mode, operands[0]);
20234 })
20235
20236 (define_peephole2
20237   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20238         (const_int 0))]
20239   "(GET_MODE (operands[0]) == QImode
20240     || GET_MODE (operands[0]) == HImode)
20241    && (! TARGET_USE_MOV0 || optimize_size)
20242    && peep2_regno_dead_p (0, FLAGS_REG)"
20243   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20244               (clobber (reg:CC FLAGS_REG))])])
20245
20246 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20247 (define_peephole2
20248   [(set (match_operand 0 "register_operand" "")
20249         (const_int -1))]
20250   "(GET_MODE (operands[0]) == HImode
20251     || GET_MODE (operands[0]) == SImode
20252     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20253    && (optimize_size || TARGET_PENTIUM)
20254    && peep2_regno_dead_p (0, FLAGS_REG)"
20255   [(parallel [(set (match_dup 0) (const_int -1))
20256               (clobber (reg:CC FLAGS_REG))])]
20257   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20258                               operands[0]);")
20259
20260 ;; Attempt to convert simple leas to adds. These can be created by
20261 ;; move expanders.
20262 (define_peephole2
20263   [(set (match_operand:SI 0 "register_operand" "")
20264         (plus:SI (match_dup 0)
20265                  (match_operand:SI 1 "nonmemory_operand" "")))]
20266   "peep2_regno_dead_p (0, FLAGS_REG)"
20267   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20268               (clobber (reg:CC FLAGS_REG))])]
20269   "")
20270
20271 (define_peephole2
20272   [(set (match_operand:SI 0 "register_operand" "")
20273         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20274                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20275   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20276   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20277               (clobber (reg:CC FLAGS_REG))])]
20278   "operands[2] = gen_lowpart (SImode, operands[2]);")
20279
20280 (define_peephole2
20281   [(set (match_operand:DI 0 "register_operand" "")
20282         (plus:DI (match_dup 0)
20283                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20284   "peep2_regno_dead_p (0, FLAGS_REG)"
20285   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20286               (clobber (reg:CC FLAGS_REG))])]
20287   "")
20288
20289 (define_peephole2
20290   [(set (match_operand:SI 0 "register_operand" "")
20291         (mult:SI (match_dup 0)
20292                  (match_operand:SI 1 "const_int_operand" "")))]
20293   "exact_log2 (INTVAL (operands[1])) >= 0
20294    && peep2_regno_dead_p (0, FLAGS_REG)"
20295   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20296               (clobber (reg:CC FLAGS_REG))])]
20297   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20298
20299 (define_peephole2
20300   [(set (match_operand:DI 0 "register_operand" "")
20301         (mult:DI (match_dup 0)
20302                  (match_operand:DI 1 "const_int_operand" "")))]
20303   "exact_log2 (INTVAL (operands[1])) >= 0
20304    && peep2_regno_dead_p (0, FLAGS_REG)"
20305   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20306               (clobber (reg:CC FLAGS_REG))])]
20307   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20308
20309 (define_peephole2
20310   [(set (match_operand:SI 0 "register_operand" "")
20311         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20312                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20313   "exact_log2 (INTVAL (operands[2])) >= 0
20314    && REGNO (operands[0]) == REGNO (operands[1])
20315    && peep2_regno_dead_p (0, FLAGS_REG)"
20316   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20317               (clobber (reg:CC FLAGS_REG))])]
20318   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20319
20320 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20321 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20322 ;; many CPUs it is also faster, since special hardware to avoid esp
20323 ;; dependencies is present.
20324
20325 ;; While some of these conversions may be done using splitters, we use peepholes
20326 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20327
20328 ;; Convert prologue esp subtractions to push.
20329 ;; We need register to push.  In order to keep verify_flow_info happy we have
20330 ;; two choices
20331 ;; - use scratch and clobber it in order to avoid dependencies
20332 ;; - use already live register
20333 ;; We can't use the second way right now, since there is no reliable way how to
20334 ;; verify that given register is live.  First choice will also most likely in
20335 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20336 ;; call clobbered registers are dead.  We may want to use base pointer as an
20337 ;; alternative when no register is available later.
20338
20339 (define_peephole2
20340   [(match_scratch:SI 0 "r")
20341    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20342               (clobber (reg:CC FLAGS_REG))
20343               (clobber (mem:BLK (scratch)))])]
20344   "optimize_size || !TARGET_SUB_ESP_4"
20345   [(clobber (match_dup 0))
20346    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20347               (clobber (mem:BLK (scratch)))])])
20348
20349 (define_peephole2
20350   [(match_scratch:SI 0 "r")
20351    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20352               (clobber (reg:CC FLAGS_REG))
20353               (clobber (mem:BLK (scratch)))])]
20354   "optimize_size || !TARGET_SUB_ESP_8"
20355   [(clobber (match_dup 0))
20356    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20357    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20358               (clobber (mem:BLK (scratch)))])])
20359
20360 ;; Convert esp subtractions to push.
20361 (define_peephole2
20362   [(match_scratch:SI 0 "r")
20363    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20364               (clobber (reg:CC FLAGS_REG))])]
20365   "optimize_size || !TARGET_SUB_ESP_4"
20366   [(clobber (match_dup 0))
20367    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20368
20369 (define_peephole2
20370   [(match_scratch:SI 0 "r")
20371    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20372               (clobber (reg:CC FLAGS_REG))])]
20373   "optimize_size || !TARGET_SUB_ESP_8"
20374   [(clobber (match_dup 0))
20375    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20376    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20377
20378 ;; Convert epilogue deallocator to pop.
20379 (define_peephole2
20380   [(match_scratch:SI 0 "r")
20381    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20382               (clobber (reg:CC FLAGS_REG))
20383               (clobber (mem:BLK (scratch)))])]
20384   "optimize_size || !TARGET_ADD_ESP_4"
20385   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20386               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20387               (clobber (mem:BLK (scratch)))])]
20388   "")
20389
20390 ;; Two pops case is tricky, since pop causes dependency on destination register.
20391 ;; We use two registers if available.
20392 (define_peephole2
20393   [(match_scratch:SI 0 "r")
20394    (match_scratch:SI 1 "r")
20395    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20396               (clobber (reg:CC FLAGS_REG))
20397               (clobber (mem:BLK (scratch)))])]
20398   "optimize_size || !TARGET_ADD_ESP_8"
20399   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20400               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20401               (clobber (mem:BLK (scratch)))])
20402    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20403               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20404   "")
20405
20406 (define_peephole2
20407   [(match_scratch:SI 0 "r")
20408    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20409               (clobber (reg:CC FLAGS_REG))
20410               (clobber (mem:BLK (scratch)))])]
20411   "optimize_size"
20412   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20413               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20414               (clobber (mem:BLK (scratch)))])
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   "")
20418
20419 ;; Convert esp additions to pop.
20420 (define_peephole2
20421   [(match_scratch:SI 0 "r")
20422    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20423               (clobber (reg:CC FLAGS_REG))])]
20424   ""
20425   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20426               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20427   "")
20428
20429 ;; Two pops case is tricky, since pop causes dependency on destination register.
20430 ;; We use two registers if available.
20431 (define_peephole2
20432   [(match_scratch:SI 0 "r")
20433    (match_scratch:SI 1 "r")
20434    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20435               (clobber (reg:CC FLAGS_REG))])]
20436   ""
20437   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20438               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20439    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20440               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20441   "")
20442
20443 (define_peephole2
20444   [(match_scratch:SI 0 "r")
20445    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20446               (clobber (reg:CC FLAGS_REG))])]
20447   "optimize_size"
20448   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20449               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20450    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20451               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20452   "")
20453 \f
20454 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20455 ;; required and register dies.  Similarly for 128 to plus -128.
20456 (define_peephole2
20457   [(set (match_operand 0 "flags_reg_operand" "")
20458         (match_operator 1 "compare_operator"
20459           [(match_operand 2 "register_operand" "")
20460            (match_operand 3 "const_int_operand" "")]))]
20461   "(INTVAL (operands[3]) == -1
20462     || INTVAL (operands[3]) == 1
20463     || INTVAL (operands[3]) == 128)
20464    && ix86_match_ccmode (insn, CCGCmode)
20465    && peep2_reg_dead_p (1, operands[2])"
20466   [(parallel [(set (match_dup 0)
20467                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20468               (clobber (match_dup 2))])]
20469   "")
20470 \f
20471 (define_peephole2
20472   [(match_scratch:DI 0 "r")
20473    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20474               (clobber (reg:CC FLAGS_REG))
20475               (clobber (mem:BLK (scratch)))])]
20476   "optimize_size || !TARGET_SUB_ESP_4"
20477   [(clobber (match_dup 0))
20478    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20479               (clobber (mem:BLK (scratch)))])])
20480
20481 (define_peephole2
20482   [(match_scratch:DI 0 "r")
20483    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20484               (clobber (reg:CC FLAGS_REG))
20485               (clobber (mem:BLK (scratch)))])]
20486   "optimize_size || !TARGET_SUB_ESP_8"
20487   [(clobber (match_dup 0))
20488    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20489    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20490               (clobber (mem:BLK (scratch)))])])
20491
20492 ;; Convert esp subtractions to push.
20493 (define_peephole2
20494   [(match_scratch:DI 0 "r")
20495    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20496               (clobber (reg:CC FLAGS_REG))])]
20497   "optimize_size || !TARGET_SUB_ESP_4"
20498   [(clobber (match_dup 0))
20499    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20500
20501 (define_peephole2
20502   [(match_scratch:DI 0 "r")
20503    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20504               (clobber (reg:CC FLAGS_REG))])]
20505   "optimize_size || !TARGET_SUB_ESP_8"
20506   [(clobber (match_dup 0))
20507    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20508    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20509
20510 ;; Convert epilogue deallocator to pop.
20511 (define_peephole2
20512   [(match_scratch:DI 0 "r")
20513    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20514               (clobber (reg:CC FLAGS_REG))
20515               (clobber (mem:BLK (scratch)))])]
20516   "optimize_size || !TARGET_ADD_ESP_4"
20517   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20518               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20519               (clobber (mem:BLK (scratch)))])]
20520   "")
20521
20522 ;; Two pops case is tricky, since pop causes dependency on destination register.
20523 ;; We use two registers if available.
20524 (define_peephole2
20525   [(match_scratch:DI 0 "r")
20526    (match_scratch:DI 1 "r")
20527    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20528               (clobber (reg:CC FLAGS_REG))
20529               (clobber (mem:BLK (scratch)))])]
20530   "optimize_size || !TARGET_ADD_ESP_8"
20531   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20532               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20533               (clobber (mem:BLK (scratch)))])
20534    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20535               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20536   "")
20537
20538 (define_peephole2
20539   [(match_scratch:DI 0 "r")
20540    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20541               (clobber (reg:CC FLAGS_REG))
20542               (clobber (mem:BLK (scratch)))])]
20543   "optimize_size"
20544   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20545               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20546               (clobber (mem:BLK (scratch)))])
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   "")
20550
20551 ;; Convert esp additions to pop.
20552 (define_peephole2
20553   [(match_scratch:DI 0 "r")
20554    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20555               (clobber (reg:CC FLAGS_REG))])]
20556   ""
20557   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20558               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20559   "")
20560
20561 ;; Two pops case is tricky, since pop causes dependency on destination register.
20562 ;; We use two registers if available.
20563 (define_peephole2
20564   [(match_scratch:DI 0 "r")
20565    (match_scratch:DI 1 "r")
20566    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20567               (clobber (reg:CC FLAGS_REG))])]
20568   ""
20569   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20570               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20571    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20572               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20573   "")
20574
20575 (define_peephole2
20576   [(match_scratch:DI 0 "r")
20577    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20578               (clobber (reg:CC FLAGS_REG))])]
20579   "optimize_size"
20580   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20581               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20582    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20583               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20584   "")
20585 \f
20586 ;; Convert imul by three, five and nine into lea
20587 (define_peephole2
20588   [(parallel
20589     [(set (match_operand:SI 0 "register_operand" "")
20590           (mult:SI (match_operand:SI 1 "register_operand" "")
20591                    (match_operand:SI 2 "const_int_operand" "")))
20592      (clobber (reg:CC FLAGS_REG))])]
20593   "INTVAL (operands[2]) == 3
20594    || INTVAL (operands[2]) == 5
20595    || INTVAL (operands[2]) == 9"
20596   [(set (match_dup 0)
20597         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20598                  (match_dup 1)))]
20599   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20600
20601 (define_peephole2
20602   [(parallel
20603     [(set (match_operand:SI 0 "register_operand" "")
20604           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20605                    (match_operand:SI 2 "const_int_operand" "")))
20606      (clobber (reg:CC FLAGS_REG))])]
20607   "!optimize_size
20608    && (INTVAL (operands[2]) == 3
20609        || INTVAL (operands[2]) == 5
20610        || INTVAL (operands[2]) == 9)"
20611   [(set (match_dup 0) (match_dup 1))
20612    (set (match_dup 0)
20613         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20614                  (match_dup 0)))]
20615   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20616
20617 (define_peephole2
20618   [(parallel
20619     [(set (match_operand:DI 0 "register_operand" "")
20620           (mult:DI (match_operand:DI 1 "register_operand" "")
20621                    (match_operand:DI 2 "const_int_operand" "")))
20622      (clobber (reg:CC FLAGS_REG))])]
20623   "TARGET_64BIT
20624    && (INTVAL (operands[2]) == 3
20625        || INTVAL (operands[2]) == 5
20626        || INTVAL (operands[2]) == 9)"
20627   [(set (match_dup 0)
20628         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20629                  (match_dup 1)))]
20630   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20631
20632 (define_peephole2
20633   [(parallel
20634     [(set (match_operand:DI 0 "register_operand" "")
20635           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20636                    (match_operand:DI 2 "const_int_operand" "")))
20637      (clobber (reg:CC FLAGS_REG))])]
20638   "TARGET_64BIT
20639    && !optimize_size
20640    && (INTVAL (operands[2]) == 3
20641        || INTVAL (operands[2]) == 5
20642        || INTVAL (operands[2]) == 9)"
20643   [(set (match_dup 0) (match_dup 1))
20644    (set (match_dup 0)
20645         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20646                  (match_dup 0)))]
20647   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20648
20649 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20650 ;; imul $32bit_imm, reg, reg is direct decoded.
20651 (define_peephole2
20652   [(match_scratch:DI 3 "r")
20653    (parallel [(set (match_operand:DI 0 "register_operand" "")
20654                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20655                             (match_operand:DI 2 "immediate_operand" "")))
20656               (clobber (reg:CC FLAGS_REG))])]
20657   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20658    && !satisfies_constraint_K (operands[2])"
20659   [(set (match_dup 3) (match_dup 1))
20660    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20661               (clobber (reg:CC FLAGS_REG))])]
20662 "")
20663
20664 (define_peephole2
20665   [(match_scratch:SI 3 "r")
20666    (parallel [(set (match_operand:SI 0 "register_operand" "")
20667                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20668                             (match_operand:SI 2 "immediate_operand" "")))
20669               (clobber (reg:CC FLAGS_REG))])]
20670   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20671    && !satisfies_constraint_K (operands[2])"
20672   [(set (match_dup 3) (match_dup 1))
20673    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20674               (clobber (reg:CC FLAGS_REG))])]
20675 "")
20676
20677 (define_peephole2
20678   [(match_scratch:SI 3 "r")
20679    (parallel [(set (match_operand:DI 0 "register_operand" "")
20680                    (zero_extend:DI
20681                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20682                               (match_operand:SI 2 "immediate_operand" ""))))
20683               (clobber (reg:CC FLAGS_REG))])]
20684   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20685    && !satisfies_constraint_K (operands[2])"
20686   [(set (match_dup 3) (match_dup 1))
20687    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20688               (clobber (reg:CC FLAGS_REG))])]
20689 "")
20690
20691 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20692 ;; Convert it into imul reg, reg
20693 ;; It would be better to force assembler to encode instruction using long
20694 ;; immediate, but there is apparently no way to do so.
20695 (define_peephole2
20696   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20697                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20698                             (match_operand:DI 2 "const_int_operand" "")))
20699               (clobber (reg:CC FLAGS_REG))])
20700    (match_scratch:DI 3 "r")]
20701   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20702    && satisfies_constraint_K (operands[2])"
20703   [(set (match_dup 3) (match_dup 2))
20704    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20705               (clobber (reg:CC FLAGS_REG))])]
20706 {
20707   if (!rtx_equal_p (operands[0], operands[1]))
20708     emit_move_insn (operands[0], operands[1]);
20709 })
20710
20711 (define_peephole2
20712   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20713                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20714                             (match_operand:SI 2 "const_int_operand" "")))
20715               (clobber (reg:CC FLAGS_REG))])
20716    (match_scratch:SI 3 "r")]
20717   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20718    && satisfies_constraint_K (operands[2])"
20719   [(set (match_dup 3) (match_dup 2))
20720    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20721               (clobber (reg:CC FLAGS_REG))])]
20722 {
20723   if (!rtx_equal_p (operands[0], operands[1]))
20724     emit_move_insn (operands[0], operands[1]);
20725 })
20726
20727 (define_peephole2
20728   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20729                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20730                             (match_operand:HI 2 "immediate_operand" "")))
20731               (clobber (reg:CC FLAGS_REG))])
20732    (match_scratch:HI 3 "r")]
20733   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size"
20734   [(set (match_dup 3) (match_dup 2))
20735    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20736               (clobber (reg:CC FLAGS_REG))])]
20737 {
20738   if (!rtx_equal_p (operands[0], operands[1]))
20739     emit_move_insn (operands[0], operands[1]);
20740 })
20741
20742 ;; After splitting up read-modify operations, array accesses with memory
20743 ;; operands might end up in form:
20744 ;;  sall    $2, %eax
20745 ;;  movl    4(%esp), %edx
20746 ;;  addl    %edx, %eax
20747 ;; instead of pre-splitting:
20748 ;;  sall    $2, %eax
20749 ;;  addl    4(%esp), %eax
20750 ;; Turn it into:
20751 ;;  movl    4(%esp), %edx
20752 ;;  leal    (%edx,%eax,4), %eax
20753
20754 (define_peephole2
20755   [(parallel [(set (match_operand 0 "register_operand" "")
20756                    (ashift (match_operand 1 "register_operand" "")
20757                            (match_operand 2 "const_int_operand" "")))
20758                (clobber (reg:CC FLAGS_REG))])
20759    (set (match_operand 3 "register_operand")
20760         (match_operand 4 "x86_64_general_operand" ""))
20761    (parallel [(set (match_operand 5 "register_operand" "")
20762                    (plus (match_operand 6 "register_operand" "")
20763                          (match_operand 7 "register_operand" "")))
20764                    (clobber (reg:CC FLAGS_REG))])]
20765   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20766    /* Validate MODE for lea.  */
20767    && ((!TARGET_PARTIAL_REG_STALL
20768         && (GET_MODE (operands[0]) == QImode
20769             || GET_MODE (operands[0]) == HImode))
20770        || GET_MODE (operands[0]) == SImode
20771        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20772    /* We reorder load and the shift.  */
20773    && !rtx_equal_p (operands[1], operands[3])
20774    && !reg_overlap_mentioned_p (operands[0], operands[4])
20775    /* Last PLUS must consist of operand 0 and 3.  */
20776    && !rtx_equal_p (operands[0], operands[3])
20777    && (rtx_equal_p (operands[3], operands[6])
20778        || rtx_equal_p (operands[3], operands[7]))
20779    && (rtx_equal_p (operands[0], operands[6])
20780        || rtx_equal_p (operands[0], operands[7]))
20781    /* The intermediate operand 0 must die or be same as output.  */
20782    && (rtx_equal_p (operands[0], operands[5])
20783        || peep2_reg_dead_p (3, operands[0]))"
20784   [(set (match_dup 3) (match_dup 4))
20785    (set (match_dup 0) (match_dup 1))]
20786 {
20787   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20788   int scale = 1 << INTVAL (operands[2]);
20789   rtx index = gen_lowpart (Pmode, operands[1]);
20790   rtx base = gen_lowpart (Pmode, operands[3]);
20791   rtx dest = gen_lowpart (mode, operands[5]);
20792
20793   operands[1] = gen_rtx_PLUS (Pmode, base,
20794                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20795   if (mode != Pmode)
20796     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20797   operands[0] = dest;
20798 })
20799 \f
20800 ;; Call-value patterns last so that the wildcard operand does not
20801 ;; disrupt insn-recog's switch tables.
20802
20803 (define_insn "*call_value_pop_0"
20804   [(set (match_operand 0 "" "")
20805         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20806               (match_operand:SI 2 "" "")))
20807    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20808                             (match_operand:SI 3 "immediate_operand" "")))]
20809   "!TARGET_64BIT"
20810 {
20811   if (SIBLING_CALL_P (insn))
20812     return "jmp\t%P1";
20813   else
20814     return "call\t%P1";
20815 }
20816   [(set_attr "type" "callv")])
20817
20818 (define_insn "*call_value_pop_1"
20819   [(set (match_operand 0 "" "")
20820         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20821               (match_operand:SI 2 "" "")))
20822    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20823                             (match_operand:SI 3 "immediate_operand" "i")))]
20824   "!TARGET_64BIT"
20825 {
20826   if (constant_call_address_operand (operands[1], Pmode))
20827     {
20828       if (SIBLING_CALL_P (insn))
20829         return "jmp\t%P1";
20830       else
20831         return "call\t%P1";
20832     }
20833   if (SIBLING_CALL_P (insn))
20834     return "jmp\t%A1";
20835   else
20836     return "call\t%A1";
20837 }
20838   [(set_attr "type" "callv")])
20839
20840 (define_insn "*call_value_0"
20841   [(set (match_operand 0 "" "")
20842         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20843               (match_operand:SI 2 "" "")))]
20844   "!TARGET_64BIT"
20845 {
20846   if (SIBLING_CALL_P (insn))
20847     return "jmp\t%P1";
20848   else
20849     return "call\t%P1";
20850 }
20851   [(set_attr "type" "callv")])
20852
20853 (define_insn "*call_value_0_rex64"
20854   [(set (match_operand 0 "" "")
20855         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20856               (match_operand:DI 2 "const_int_operand" "")))]
20857   "TARGET_64BIT"
20858 {
20859   if (SIBLING_CALL_P (insn))
20860     return "jmp\t%P1";
20861   else
20862     return "call\t%P1";
20863 }
20864   [(set_attr "type" "callv")])
20865
20866 (define_insn "*call_value_1"
20867   [(set (match_operand 0 "" "")
20868         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20869               (match_operand:SI 2 "" "")))]
20870   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20871 {
20872   if (constant_call_address_operand (operands[1], Pmode))
20873     return "call\t%P1";
20874   return "call\t%A1";
20875 }
20876   [(set_attr "type" "callv")])
20877
20878 (define_insn "*sibcall_value_1"
20879   [(set (match_operand 0 "" "")
20880         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20881               (match_operand:SI 2 "" "")))]
20882   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20883 {
20884   if (constant_call_address_operand (operands[1], Pmode))
20885     return "jmp\t%P1";
20886   return "jmp\t%A1";
20887 }
20888   [(set_attr "type" "callv")])
20889
20890 (define_insn "*call_value_1_rex64"
20891   [(set (match_operand 0 "" "")
20892         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20893               (match_operand:DI 2 "" "")))]
20894   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20895 {
20896   if (constant_call_address_operand (operands[1], Pmode))
20897     return "call\t%P1";
20898   return "call\t%A1";
20899 }
20900   [(set_attr "type" "callv")])
20901
20902 (define_insn "*sibcall_value_1_rex64"
20903   [(set (match_operand 0 "" "")
20904         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20905               (match_operand:DI 2 "" "")))]
20906   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20907   "jmp\t%P1"
20908   [(set_attr "type" "callv")])
20909
20910 (define_insn "*sibcall_value_1_rex64_v"
20911   [(set (match_operand 0 "" "")
20912         (call (mem:QI (reg:DI R11_REG))
20913               (match_operand:DI 1 "" "")))]
20914   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20915   "jmp\t*%%r11"
20916   [(set_attr "type" "callv")])
20917 \f
20918 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20919 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20920 ;; caught for use by garbage collectors and the like.  Using an insn that
20921 ;; maps to SIGILL makes it more likely the program will rightfully die.
20922 ;; Keeping with tradition, "6" is in honor of #UD.
20923 (define_insn "trap"
20924   [(trap_if (const_int 1) (const_int 6))]
20925   ""
20926   { return ASM_SHORT "0x0b0f"; }
20927   [(set_attr "length" "2")])
20928
20929 (define_expand "sse_prologue_save"
20930   [(parallel [(set (match_operand:BLK 0 "" "")
20931                    (unspec:BLK [(reg:DI 21)
20932                                 (reg:DI 22)
20933                                 (reg:DI 23)
20934                                 (reg:DI 24)
20935                                 (reg:DI 25)
20936                                 (reg:DI 26)
20937                                 (reg:DI 27)
20938                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20939               (use (match_operand:DI 1 "register_operand" ""))
20940               (use (match_operand:DI 2 "immediate_operand" ""))
20941               (use (label_ref:DI (match_operand 3 "" "")))])]
20942   "TARGET_64BIT"
20943   "")
20944
20945 (define_insn "*sse_prologue_save_insn"
20946   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20947                           (match_operand:DI 4 "const_int_operand" "n")))
20948         (unspec:BLK [(reg:DI 21)
20949                      (reg:DI 22)
20950                      (reg:DI 23)
20951                      (reg:DI 24)
20952                      (reg:DI 25)
20953                      (reg:DI 26)
20954                      (reg:DI 27)
20955                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20956    (use (match_operand:DI 1 "register_operand" "r"))
20957    (use (match_operand:DI 2 "const_int_operand" "i"))
20958    (use (label_ref:DI (match_operand 3 "" "X")))]
20959   "TARGET_64BIT
20960    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20961    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20962   "*
20963 {
20964   int i;
20965   operands[0] = gen_rtx_MEM (Pmode,
20966                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20967   output_asm_insn (\"jmp\\t%A1\", operands);
20968   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20969     {
20970       operands[4] = adjust_address (operands[0], DImode, i*16);
20971       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20972       PUT_MODE (operands[4], TImode);
20973       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20974         output_asm_insn (\"rex\", operands);
20975       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20976     }
20977   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20978                              CODE_LABEL_NUMBER (operands[3]));
20979   return \"\";
20980 }
20981   "
20982   [(set_attr "type" "other")
20983    (set_attr "length_immediate" "0")
20984    (set_attr "length_address" "0")
20985    (set_attr "length" "135")
20986    (set_attr "memory" "store")
20987    (set_attr "modrm" "0")
20988    (set_attr "mode" "DI")])
20989
20990 (define_expand "prefetch"
20991   [(prefetch (match_operand 0 "address_operand" "")
20992              (match_operand:SI 1 "const_int_operand" "")
20993              (match_operand:SI 2 "const_int_operand" ""))]
20994   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20995 {
20996   int rw = INTVAL (operands[1]);
20997   int locality = INTVAL (operands[2]);
20998
20999   gcc_assert (rw == 0 || rw == 1);
21000   gcc_assert (locality >= 0 && locality <= 3);
21001   gcc_assert (GET_MODE (operands[0]) == Pmode
21002               || GET_MODE (operands[0]) == VOIDmode);
21003
21004   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21005      supported by SSE counterpart or the SSE prefetch is not available
21006      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21007      of locality.  */
21008   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21009     operands[2] = GEN_INT (3);
21010   else
21011     operands[1] = const0_rtx;
21012 })
21013
21014 (define_insn "*prefetch_sse"
21015   [(prefetch (match_operand:SI 0 "address_operand" "p")
21016              (const_int 0)
21017              (match_operand:SI 1 "const_int_operand" ""))]
21018   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21019 {
21020   static const char * const patterns[4] = {
21021    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21022   };
21023
21024   int locality = INTVAL (operands[1]);
21025   gcc_assert (locality >= 0 && locality <= 3);
21026
21027   return patterns[locality];
21028 }
21029   [(set_attr "type" "sse")
21030    (set_attr "memory" "none")])
21031
21032 (define_insn "*prefetch_sse_rex"
21033   [(prefetch (match_operand:DI 0 "address_operand" "p")
21034              (const_int 0)
21035              (match_operand:SI 1 "const_int_operand" ""))]
21036   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21037 {
21038   static const char * const patterns[4] = {
21039    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21040   };
21041
21042   int locality = INTVAL (operands[1]);
21043   gcc_assert (locality >= 0 && locality <= 3);
21044
21045   return patterns[locality];
21046 }
21047   [(set_attr "type" "sse")
21048    (set_attr "memory" "none")])
21049
21050 (define_insn "*prefetch_3dnow"
21051   [(prefetch (match_operand:SI 0 "address_operand" "p")
21052              (match_operand:SI 1 "const_int_operand" "n")
21053              (const_int 3))]
21054   "TARGET_3DNOW && !TARGET_64BIT"
21055 {
21056   if (INTVAL (operands[1]) == 0)
21057     return "prefetch\t%a0";
21058   else
21059     return "prefetchw\t%a0";
21060 }
21061   [(set_attr "type" "mmx")
21062    (set_attr "memory" "none")])
21063
21064 (define_insn "*prefetch_3dnow_rex"
21065   [(prefetch (match_operand:DI 0 "address_operand" "p")
21066              (match_operand:SI 1 "const_int_operand" "n")
21067              (const_int 3))]
21068   "TARGET_3DNOW && TARGET_64BIT"
21069 {
21070   if (INTVAL (operands[1]) == 0)
21071     return "prefetch\t%a0";
21072   else
21073     return "prefetchw\t%a0";
21074 }
21075   [(set_attr "type" "mmx")
21076    (set_attr "memory" "none")])
21077
21078 (define_expand "stack_protect_set"
21079   [(match_operand 0 "memory_operand" "")
21080    (match_operand 1 "memory_operand" "")]
21081   ""
21082 {
21083 #ifdef TARGET_THREAD_SSP_OFFSET
21084   if (TARGET_64BIT)
21085     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21086                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21087   else
21088     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21089                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21090 #else
21091   if (TARGET_64BIT)
21092     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21093   else
21094     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21095 #endif
21096   DONE;
21097 })
21098
21099 (define_insn "stack_protect_set_si"
21100   [(set (match_operand:SI 0 "memory_operand" "=m")
21101         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21102    (set (match_scratch:SI 2 "=&r") (const_int 0))
21103    (clobber (reg:CC FLAGS_REG))]
21104   ""
21105   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21106   [(set_attr "type" "multi")])
21107
21108 (define_insn "stack_protect_set_di"
21109   [(set (match_operand:DI 0 "memory_operand" "=m")
21110         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21111    (set (match_scratch:DI 2 "=&r") (const_int 0))
21112    (clobber (reg:CC FLAGS_REG))]
21113   "TARGET_64BIT"
21114   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21115   [(set_attr "type" "multi")])
21116
21117 (define_insn "stack_tls_protect_set_si"
21118   [(set (match_operand:SI 0 "memory_operand" "=m")
21119         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21120    (set (match_scratch:SI 2 "=&r") (const_int 0))
21121    (clobber (reg:CC FLAGS_REG))]
21122   ""
21123   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21124   [(set_attr "type" "multi")])
21125
21126 (define_insn "stack_tls_protect_set_di"
21127   [(set (match_operand:DI 0 "memory_operand" "=m")
21128         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21129    (set (match_scratch:DI 2 "=&r") (const_int 0))
21130    (clobber (reg:CC FLAGS_REG))]
21131   "TARGET_64BIT"
21132   {
21133      /* The kernel uses a different segment register for performance reasons; a
21134         system call would not have to trash the userspace segment register,
21135         which would be expensive */
21136      if (ix86_cmodel != CM_KERNEL)
21137         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21138      else
21139         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21140   }
21141   [(set_attr "type" "multi")])
21142
21143 (define_expand "stack_protect_test"
21144   [(match_operand 0 "memory_operand" "")
21145    (match_operand 1 "memory_operand" "")
21146    (match_operand 2 "" "")]
21147   ""
21148 {
21149   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21150   ix86_compare_op0 = operands[0];
21151   ix86_compare_op1 = operands[1];
21152   ix86_compare_emitted = flags;
21153
21154 #ifdef TARGET_THREAD_SSP_OFFSET
21155   if (TARGET_64BIT)
21156     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21157                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21158   else
21159     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21160                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21161 #else
21162   if (TARGET_64BIT)
21163     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21164   else
21165     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21166 #endif
21167   emit_jump_insn (gen_beq (operands[2]));
21168   DONE;
21169 })
21170
21171 (define_insn "stack_protect_test_si"
21172   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21173         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21174                      (match_operand:SI 2 "memory_operand" "m")]
21175                     UNSPEC_SP_TEST))
21176    (clobber (match_scratch:SI 3 "=&r"))]
21177   ""
21178   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21179   [(set_attr "type" "multi")])
21180
21181 (define_insn "stack_protect_test_di"
21182   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21183         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21184                      (match_operand:DI 2 "memory_operand" "m")]
21185                     UNSPEC_SP_TEST))
21186    (clobber (match_scratch:DI 3 "=&r"))]
21187   "TARGET_64BIT"
21188   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21189   [(set_attr "type" "multi")])
21190
21191 (define_insn "stack_tls_protect_test_si"
21192   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21193         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21194                      (match_operand:SI 2 "const_int_operand" "i")]
21195                     UNSPEC_SP_TLS_TEST))
21196    (clobber (match_scratch:SI 3 "=r"))]
21197   ""
21198   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21199   [(set_attr "type" "multi")])
21200
21201 (define_insn "stack_tls_protect_test_di"
21202   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21203         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21204                      (match_operand:DI 2 "const_int_operand" "i")]
21205                     UNSPEC_SP_TLS_TEST))
21206    (clobber (match_scratch:DI 3 "=r"))]
21207   "TARGET_64BIT"
21208   {
21209      /* The kernel uses a different segment register for performance reasons; a
21210         system call would not have to trash the userspace segment register,
21211         which would be expensive */
21212      if (ix86_cmodel != CM_KERNEL)
21213         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21214      else
21215         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21216   }
21217   [(set_attr "type" "multi")])
21218
21219 (include "mmx.md")
21220 (include "sse.md")
21221 (include "sync.md")