OSDN Git Service

* config/i386/i386.md (cmpdi_ccno_1_rex64, *cmpsi_ccno_1,
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / i386.md
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING.  If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.  */
24 ;;
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
27 ;;
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;;
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
32 ;;
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
35 ;;     operands[1].
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
43 ;;
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;;     %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
50
51 ;; UNSPEC usage:
52
53 (define_constants
54   [; Relocation specifiers
55    (UNSPEC_GOT                  0)
56    (UNSPEC_GOTOFF               1)
57    (UNSPEC_GOTPCREL             2)
58    (UNSPEC_GOTTPOFF             3)
59    (UNSPEC_TPOFF                4)
60    (UNSPEC_NTPOFF               5)
61    (UNSPEC_DTPOFF               6)
62    (UNSPEC_GOTNTPOFF            7)
63    (UNSPEC_INDNTPOFF            8)
64
65    ; Prologue support
66    (UNSPEC_STACK_ALLOC          11)
67    (UNSPEC_SET_GOT              12)
68    (UNSPEC_SSE_PROLOGUE_SAVE    13)
69    (UNSPEC_REG_SAVE             14)
70    (UNSPEC_DEF_CFA              15)
71
72    ; TLS support
73    (UNSPEC_TP                   16)
74    (UNSPEC_TLS_GD               17)
75    (UNSPEC_TLS_LD_BASE          18)
76    (UNSPEC_TLSDESC              19)
77
78    ; Other random patterns
79    (UNSPEC_SCAS                 20)
80    (UNSPEC_FNSTSW               21)
81    (UNSPEC_SAHF                 22)
82    (UNSPEC_FSTCW                23)
83    (UNSPEC_ADD_CARRY            24)
84    (UNSPEC_FLDCW                25)
85    (UNSPEC_REP                  26)
86    (UNSPEC_EH_RETURN            27)
87    (UNSPEC_LD_MPIC              28)     ; load_macho_picbase
88    (UNSPEC_TRUNC_NOOP           29)
89
90    ; For SSE/MMX support:
91    (UNSPEC_FIX_NOTRUNC          30)
92    (UNSPEC_MASKMOV              31)
93    (UNSPEC_MOVMSK               32)
94    (UNSPEC_MOVNT                33)
95    (UNSPEC_MOVU                 34)
96    (UNSPEC_RCP                  35)
97    (UNSPEC_RSQRT                36)
98    (UNSPEC_SFENCE               37)
99    (UNSPEC_NOP                  38)     ; prevents combiner cleverness
100    (UNSPEC_PFRCP                39)
101    (UNSPEC_PFRCPIT1             40)
102    (UNSPEC_PFRCPIT2             41)
103    (UNSPEC_PFRSQRT              42)
104    (UNSPEC_PFRSQIT1             43)
105    (UNSPEC_MFENCE               44)
106    (UNSPEC_LFENCE               45)
107    (UNSPEC_PSADBW               46)
108    (UNSPEC_LDDQU                47)
109
110    ; Generic math support
111    (UNSPEC_COPYSIGN             50)
112    (UNSPEC_IEEE_MIN             51)     ; not commutative
113    (UNSPEC_IEEE_MAX             52)     ; not commutative
114
115    ; x87 Floating point
116    (UNSPEC_SIN                  60)
117    (UNSPEC_COS                  61)
118    (UNSPEC_FPATAN               62)
119    (UNSPEC_FYL2X                63)
120    (UNSPEC_FYL2XP1              64)
121    (UNSPEC_FRNDINT              65)
122    (UNSPEC_FIST                 66)
123    (UNSPEC_F2XM1                67)
124    (UNSPEC_TAN                  68)
125    (UNSPEC_FXAM                 69)
126
127    ; x87 Rounding
128    (UNSPEC_FRNDINT_FLOOR        70)
129    (UNSPEC_FRNDINT_CEIL         71)
130    (UNSPEC_FRNDINT_TRUNC        72)
131    (UNSPEC_FRNDINT_MASK_PM      73)
132    (UNSPEC_FIST_FLOOR           74)
133    (UNSPEC_FIST_CEIL            75)
134
135    ; x87 Double output FP
136    (UNSPEC_SINCOS_COS           80)
137    (UNSPEC_SINCOS_SIN           81)
138    (UNSPEC_XTRACT_FRACT         84)
139    (UNSPEC_XTRACT_EXP           85)
140    (UNSPEC_FSCALE_FRACT         86)
141    (UNSPEC_FSCALE_EXP           87)
142    (UNSPEC_FPREM_F              88)
143    (UNSPEC_FPREM_U              89)
144    (UNSPEC_FPREM1_F             90)
145    (UNSPEC_FPREM1_U             91)
146
147    ; SSP patterns
148    (UNSPEC_SP_SET               100)
149    (UNSPEC_SP_TEST              101)
150    (UNSPEC_SP_TLS_SET           102)
151    (UNSPEC_SP_TLS_TEST          103)
152
153    ; SSSE3
154    (UNSPEC_PSHUFB               120)
155    (UNSPEC_PSIGN                121)
156    (UNSPEC_PALIGNR              122)
157
158    ; For SSE4A support
159    (UNSPEC_EXTRQI               130)
160    (UNSPEC_EXTRQ                131)   
161    (UNSPEC_INSERTQI             132)
162    (UNSPEC_INSERTQ              133)
163   ])
164
165 (define_constants
166   [(UNSPECV_BLOCKAGE            0)
167    (UNSPECV_STACK_PROBE         1)
168    (UNSPECV_EMMS                2)
169    (UNSPECV_LDMXCSR             3)
170    (UNSPECV_STMXCSR             4)
171    (UNSPECV_FEMMS               5)
172    (UNSPECV_CLFLUSH             6)
173    (UNSPECV_ALIGN               7)
174    (UNSPECV_MONITOR             8)
175    (UNSPECV_MWAIT               9)
176    (UNSPECV_CMPXCHG_1           10)
177    (UNSPECV_CMPXCHG_2           11)
178    (UNSPECV_XCHG                12)
179    (UNSPECV_LOCK                13)
180   ])
181
182 ;; Registers by name.
183 (define_constants
184   [(BP_REG                       6)
185    (SP_REG                       7)
186    (FLAGS_REG                   17)
187    (FPSR_REG                    18)
188    (FPCR_REG                    19)
189    (R10_REG                     39)
190    (R11_REG                     40)
191   ])
192
193 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
194 ;; from i386.c.
195
196 ;; In C guard expressions, put expressions which may be compile-time
197 ;; constants first.  This allows for better optimization.  For
198 ;; example, write "TARGET_64BIT && reload_completed", not
199 ;; "reload_completed && TARGET_64BIT".
200
201 \f
202 ;; Processor type.  This attribute must exactly match the processor_type
203 ;; enumeration in i386.h.
204 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
205                     nocona,core2,generic32,generic64,amdfam10"
206   (const (symbol_ref "ix86_tune")))
207
208 ;; A basic instruction type.  Refinements due to arguments to be
209 ;; provided in other attributes.
210 (define_attr "type"
211   "other,multi,
212    alu,alu1,negnot,imov,imovx,lea,
213    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
214    icmp,test,ibr,setcc,icmov,
215    push,pop,call,callv,leave,
216    str,bitmanip,
217    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
218    sselog,sselog1,sseiadd,sseishft,sseimul,
219    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins,
220    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
221   (const_string "other"))
222
223 ;; Main data type used by the insn
224 (define_attr "mode"
225   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
226   (const_string "unknown"))
227
228 ;; The CPU unit operations uses.
229 (define_attr "unit" "integer,i387,sse,mmx,unknown"
230   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
231            (const_string "i387")
232          (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
233                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins")
234            (const_string "sse")
235          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
236            (const_string "mmx")
237          (eq_attr "type" "other")
238            (const_string "unknown")]
239          (const_string "integer")))
240
241 ;; The (bounding maximum) length of an instruction immediate.
242 (define_attr "length_immediate" ""
243   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
244                           bitmanip")
245            (const_int 0)
246          (eq_attr "unit" "i387,sse,mmx")
247            (const_int 0)
248          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
249                           imul,icmp,push,pop")
250            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
251          (eq_attr "type" "imov,test")
252            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
253          (eq_attr "type" "call")
254            (if_then_else (match_operand 0 "constant_call_address_operand" "")
255              (const_int 4)
256              (const_int 0))
257          (eq_attr "type" "callv")
258            (if_then_else (match_operand 1 "constant_call_address_operand" "")
259              (const_int 4)
260              (const_int 0))
261          ;; We don't know the size before shorten_branches.  Expect
262          ;; the instruction to fit for better scheduling.
263          (eq_attr "type" "ibr")
264            (const_int 1)
265          ]
266          (symbol_ref "/* Update immediate_length and other attributes! */
267                       gcc_unreachable (),1")))
268
269 ;; The (bounding maximum) length of an instruction address.
270 (define_attr "length_address" ""
271   (cond [(eq_attr "type" "str,other,multi,fxch")
272            (const_int 0)
273          (and (eq_attr "type" "call")
274               (match_operand 0 "constant_call_address_operand" ""))
275              (const_int 0)
276          (and (eq_attr "type" "callv")
277               (match_operand 1 "constant_call_address_operand" ""))
278              (const_int 0)
279          ]
280          (symbol_ref "ix86_attr_length_address_default (insn)")))
281
282 ;; Set when length prefix is used.
283 (define_attr "prefix_data16" ""
284   (if_then_else (ior (eq_attr "mode" "HI")
285                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
286     (const_int 1)
287     (const_int 0)))
288
289 ;; Set when string REP prefix is used.
290 (define_attr "prefix_rep" ""
291   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
292     (const_int 1)
293     (const_int 0)))
294
295 ;; Set when 0f opcode prefix is used.
296 (define_attr "prefix_0f" ""
297   (if_then_else
298     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
299          (eq_attr "unit" "sse,mmx"))
300     (const_int 1)
301     (const_int 0)))
302
303 ;; Set when REX opcode prefix is used.
304 (define_attr "prefix_rex" ""
305   (cond [(and (eq_attr "mode" "DI")
306               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
307            (const_int 1)
308          (and (eq_attr "mode" "QI")
309               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
310                   (const_int 0)))
311            (const_int 1)
312          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
313              (const_int 0))
314            (const_int 1)
315         ]
316         (const_int 0)))
317
318 ;; Set when modrm byte is used.
319 (define_attr "modrm" ""
320   (cond [(eq_attr "type" "str,leave")
321            (const_int 0)
322          (eq_attr "unit" "i387")
323            (const_int 0)
324          (and (eq_attr "type" "incdec")
325               (ior (match_operand:SI 1 "register_operand" "")
326                    (match_operand:HI 1 "register_operand" "")))
327            (const_int 0)
328          (and (eq_attr "type" "push")
329               (not (match_operand 1 "memory_operand" "")))
330            (const_int 0)
331          (and (eq_attr "type" "pop")
332               (not (match_operand 0 "memory_operand" "")))
333            (const_int 0)
334          (and (eq_attr "type" "imov")
335               (ior (and (match_operand 0 "register_operand" "")
336                         (match_operand 1 "immediate_operand" ""))
337                    (ior (and (match_operand 0 "ax_reg_operand" "")
338                              (match_operand 1 "memory_displacement_only_operand" ""))
339                         (and (match_operand 0 "memory_displacement_only_operand" "")
340                              (match_operand 1 "ax_reg_operand" "")))))
341            (const_int 0)
342          (and (eq_attr "type" "call")
343               (match_operand 0 "constant_call_address_operand" ""))
344              (const_int 0)
345          (and (eq_attr "type" "callv")
346               (match_operand 1 "constant_call_address_operand" ""))
347              (const_int 0)
348          ]
349          (const_int 1)))
350
351 ;; The (bounding maximum) length of an instruction in bytes.
352 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
353 ;; Later we may want to split them and compute proper length as for
354 ;; other insns.
355 (define_attr "length" ""
356   (cond [(eq_attr "type" "other,multi,fistp,frndint")
357            (const_int 16)
358          (eq_attr "type" "fcmp")
359            (const_int 4)
360          (eq_attr "unit" "i387")
361            (plus (const_int 2)
362                  (plus (attr "prefix_data16")
363                        (attr "length_address")))]
364          (plus (plus (attr "modrm")
365                      (plus (attr "prefix_0f")
366                            (plus (attr "prefix_rex")
367                                  (const_int 1))))
368                (plus (attr "prefix_rep")
369                      (plus (attr "prefix_data16")
370                            (plus (attr "length_immediate")
371                                  (attr "length_address")))))))
372
373 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
374 ;; `store' if there is a simple memory reference therein, or `unknown'
375 ;; if the instruction is complex.
376
377 (define_attr "memory" "none,load,store,both,unknown"
378   (cond [(eq_attr "type" "other,multi,str")
379            (const_string "unknown")
380          (eq_attr "type" "lea,fcmov,fpspc")
381            (const_string "none")
382          (eq_attr "type" "fistp,leave")
383            (const_string "both")
384          (eq_attr "type" "frndint")
385            (const_string "load")
386          (eq_attr "type" "push")
387            (if_then_else (match_operand 1 "memory_operand" "")
388              (const_string "both")
389              (const_string "store"))
390          (eq_attr "type" "pop")
391            (if_then_else (match_operand 0 "memory_operand" "")
392              (const_string "both")
393              (const_string "load"))
394          (eq_attr "type" "setcc")
395            (if_then_else (match_operand 0 "memory_operand" "")
396              (const_string "store")
397              (const_string "none"))
398          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
399            (if_then_else (ior (match_operand 0 "memory_operand" "")
400                               (match_operand 1 "memory_operand" ""))
401              (const_string "load")
402              (const_string "none"))
403          (eq_attr "type" "ibr")
404            (if_then_else (match_operand 0 "memory_operand" "")
405              (const_string "load")
406              (const_string "none"))
407          (eq_attr "type" "call")
408            (if_then_else (match_operand 0 "constant_call_address_operand" "")
409              (const_string "none")
410              (const_string "load"))
411          (eq_attr "type" "callv")
412            (if_then_else (match_operand 1 "constant_call_address_operand" "")
413              (const_string "none")
414              (const_string "load"))
415          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
416               (match_operand 1 "memory_operand" ""))
417            (const_string "both")
418          (and (match_operand 0 "memory_operand" "")
419               (match_operand 1 "memory_operand" ""))
420            (const_string "both")
421          (match_operand 0 "memory_operand" "")
422            (const_string "store")
423          (match_operand 1 "memory_operand" "")
424            (const_string "load")
425          (and (eq_attr "type"
426                  "!alu1,negnot,ishift1,
427                    imov,imovx,icmp,test,bitmanip,
428                    fmov,fcmp,fsgn,
429                    sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
430                    mmx,mmxmov,mmxcmp,mmxcvt")
431               (match_operand 2 "memory_operand" ""))
432            (const_string "load")
433          (and (eq_attr "type" "icmov")
434               (match_operand 3 "memory_operand" ""))
435            (const_string "load")
436         ]
437         (const_string "none")))
438
439 ;; Indicates if an instruction has both an immediate and a displacement.
440
441 (define_attr "imm_disp" "false,true,unknown"
442   (cond [(eq_attr "type" "other,multi")
443            (const_string "unknown")
444          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
445               (and (match_operand 0 "memory_displacement_operand" "")
446                    (match_operand 1 "immediate_operand" "")))
447            (const_string "true")
448          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
449               (and (match_operand 0 "memory_displacement_operand" "")
450                    (match_operand 2 "immediate_operand" "")))
451            (const_string "true")
452         ]
453         (const_string "false")))
454
455 ;; Indicates if an FP operation has an integer source.
456
457 (define_attr "fp_int_src" "false,true"
458   (const_string "false"))
459
460 ;; Defines rounding mode of an FP operation.
461
462 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
463   (const_string "any"))
464
465 ;; Describe a user's asm statement.
466 (define_asm_attributes
467   [(set_attr "length" "128")
468    (set_attr "type" "multi")])
469
470 ;; All x87 floating point modes
471 (define_mode_macro X87MODEF [SF DF XF])
472
473 ;; x87 SFmode and DFMode floating point modes
474 (define_mode_macro X87MODEF12 [SF DF])
475
476 ;; All integer modes handled by x87 fisttp operator.
477 (define_mode_macro X87MODEI [HI SI DI])
478
479 ;; All integer modes handled by integer x87 operators.
480 (define_mode_macro X87MODEI12 [HI SI])
481
482 ;; All SSE floating point modes
483 (define_mode_macro SSEMODEF [SF DF])
484
485 ;; All integer modes handled by SSE cvtts?2si* operators.
486 (define_mode_macro SSEMODEI24 [SI DI])
487
488 ;; SSE asm suffix for floating point modes
489 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
490
491 ;; SSE vector mode corresponding to a scalar mode
492 (define_mode_attr ssevecmode
493   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
494 \f
495 ;; Scheduling descriptions
496
497 (include "pentium.md")
498 (include "ppro.md")
499 (include "k6.md")
500 (include "athlon.md")
501 (include "geode.md")
502
503 \f
504 ;; Operand and operator predicates and constraints
505
506 (include "predicates.md")
507 (include "constraints.md")
508
509 \f
510 ;; Compare instructions.
511
512 ;; All compare insns have expanders that save the operands away without
513 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
514 ;; after the cmp) will actually emit the cmpM.
515
516 (define_expand "cmpti"
517   [(set (reg:CC FLAGS_REG)
518         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
519                     (match_operand:TI 1 "x86_64_general_operand" "")))]
520   "TARGET_64BIT"
521 {
522   if (MEM_P (operands[0]) && MEM_P (operands[1]))
523     operands[0] = force_reg (TImode, operands[0]);
524   ix86_compare_op0 = operands[0];
525   ix86_compare_op1 = operands[1];
526   DONE;
527 })
528
529 (define_expand "cmpdi"
530   [(set (reg:CC FLAGS_REG)
531         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
532                     (match_operand:DI 1 "x86_64_general_operand" "")))]
533   ""
534 {
535   if (MEM_P (operands[0]) && MEM_P (operands[1]))
536     operands[0] = force_reg (DImode, operands[0]);
537   ix86_compare_op0 = operands[0];
538   ix86_compare_op1 = operands[1];
539   DONE;
540 })
541
542 (define_expand "cmpsi"
543   [(set (reg:CC FLAGS_REG)
544         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
545                     (match_operand:SI 1 "general_operand" "")))]
546   ""
547 {
548   if (MEM_P (operands[0]) && MEM_P (operands[1]))
549     operands[0] = force_reg (SImode, operands[0]);
550   ix86_compare_op0 = operands[0];
551   ix86_compare_op1 = operands[1];
552   DONE;
553 })
554
555 (define_expand "cmphi"
556   [(set (reg:CC FLAGS_REG)
557         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
558                     (match_operand:HI 1 "general_operand" "")))]
559   ""
560 {
561   if (MEM_P (operands[0]) && MEM_P (operands[1]))
562     operands[0] = force_reg (HImode, operands[0]);
563   ix86_compare_op0 = operands[0];
564   ix86_compare_op1 = operands[1];
565   DONE;
566 })
567
568 (define_expand "cmpqi"
569   [(set (reg:CC FLAGS_REG)
570         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
571                     (match_operand:QI 1 "general_operand" "")))]
572   "TARGET_QIMODE_MATH"
573 {
574   if (MEM_P (operands[0]) && MEM_P (operands[1]))
575     operands[0] = force_reg (QImode, operands[0]);
576   ix86_compare_op0 = operands[0];
577   ix86_compare_op1 = operands[1];
578   DONE;
579 })
580
581 (define_insn "cmpdi_ccno_1_rex64"
582   [(set (reg FLAGS_REG)
583         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
584                  (match_operand:DI 1 "const0_operand" "n,n")))]
585   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
586   "@
587    test{q}\t%0, %0
588    cmp{q}\t{%1, %0|%0, %1}"
589   [(set_attr "type" "test,icmp")
590    (set_attr "length_immediate" "0,1")
591    (set_attr "mode" "DI")])
592
593 (define_insn "*cmpdi_minus_1_rex64"
594   [(set (reg FLAGS_REG)
595         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
596                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
597                  (const_int 0)))]
598   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
599   "cmp{q}\t{%1, %0|%0, %1}"
600   [(set_attr "type" "icmp")
601    (set_attr "mode" "DI")])
602
603 (define_expand "cmpdi_1_rex64"
604   [(set (reg:CC FLAGS_REG)
605         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
606                     (match_operand:DI 1 "general_operand" "")))]
607   "TARGET_64BIT"
608   "")
609
610 (define_insn "cmpdi_1_insn_rex64"
611   [(set (reg FLAGS_REG)
612         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
613                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
614   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
615   "cmp{q}\t{%1, %0|%0, %1}"
616   [(set_attr "type" "icmp")
617    (set_attr "mode" "DI")])
618
619
620 (define_insn "*cmpsi_ccno_1"
621   [(set (reg FLAGS_REG)
622         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
623                  (match_operand:SI 1 "const0_operand" "n,n")))]
624   "ix86_match_ccmode (insn, CCNOmode)"
625   "@
626    test{l}\t%0, %0
627    cmp{l}\t{%1, %0|%0, %1}"
628   [(set_attr "type" "test,icmp")
629    (set_attr "length_immediate" "0,1")
630    (set_attr "mode" "SI")])
631
632 (define_insn "*cmpsi_minus_1"
633   [(set (reg FLAGS_REG)
634         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
635                            (match_operand:SI 1 "general_operand" "ri,mr"))
636                  (const_int 0)))]
637   "ix86_match_ccmode (insn, CCGOCmode)"
638   "cmp{l}\t{%1, %0|%0, %1}"
639   [(set_attr "type" "icmp")
640    (set_attr "mode" "SI")])
641
642 (define_expand "cmpsi_1"
643   [(set (reg:CC FLAGS_REG)
644         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
645                     (match_operand:SI 1 "general_operand" "ri,mr")))]
646   ""
647   "")
648
649 (define_insn "*cmpsi_1_insn"
650   [(set (reg FLAGS_REG)
651         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
652                  (match_operand:SI 1 "general_operand" "ri,mr")))]
653   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
654     && ix86_match_ccmode (insn, CCmode)"
655   "cmp{l}\t{%1, %0|%0, %1}"
656   [(set_attr "type" "icmp")
657    (set_attr "mode" "SI")])
658
659 (define_insn "*cmphi_ccno_1"
660   [(set (reg FLAGS_REG)
661         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
662                  (match_operand:HI 1 "const0_operand" "n,n")))]
663   "ix86_match_ccmode (insn, CCNOmode)"
664   "@
665    test{w}\t%0, %0
666    cmp{w}\t{%1, %0|%0, %1}"
667   [(set_attr "type" "test,icmp")
668    (set_attr "length_immediate" "0,1")
669    (set_attr "mode" "HI")])
670
671 (define_insn "*cmphi_minus_1"
672   [(set (reg FLAGS_REG)
673         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
674                            (match_operand:HI 1 "general_operand" "ri,mr"))
675                  (const_int 0)))]
676   "ix86_match_ccmode (insn, CCGOCmode)"
677   "cmp{w}\t{%1, %0|%0, %1}"
678   [(set_attr "type" "icmp")
679    (set_attr "mode" "HI")])
680
681 (define_insn "*cmphi_1"
682   [(set (reg FLAGS_REG)
683         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
684                  (match_operand:HI 1 "general_operand" "ri,mr")))]
685   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
686    && ix86_match_ccmode (insn, CCmode)"
687   "cmp{w}\t{%1, %0|%0, %1}"
688   [(set_attr "type" "icmp")
689    (set_attr "mode" "HI")])
690
691 (define_insn "*cmpqi_ccno_1"
692   [(set (reg FLAGS_REG)
693         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
694                  (match_operand:QI 1 "const0_operand" "n,n")))]
695   "ix86_match_ccmode (insn, CCNOmode)"
696   "@
697    test{b}\t%0, %0
698    cmp{b}\t{$0, %0|%0, 0}"
699   [(set_attr "type" "test,icmp")
700    (set_attr "length_immediate" "0,1")
701    (set_attr "mode" "QI")])
702
703 (define_insn "*cmpqi_1"
704   [(set (reg FLAGS_REG)
705         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
706                  (match_operand:QI 1 "general_operand" "qi,mq")))]
707   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
708     && ix86_match_ccmode (insn, CCmode)"
709   "cmp{b}\t{%1, %0|%0, %1}"
710   [(set_attr "type" "icmp")
711    (set_attr "mode" "QI")])
712
713 (define_insn "*cmpqi_minus_1"
714   [(set (reg FLAGS_REG)
715         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
716                            (match_operand:QI 1 "general_operand" "qi,mq"))
717                  (const_int 0)))]
718   "ix86_match_ccmode (insn, CCGOCmode)"
719   "cmp{b}\t{%1, %0|%0, %1}"
720   [(set_attr "type" "icmp")
721    (set_attr "mode" "QI")])
722
723 (define_insn "*cmpqi_ext_1"
724   [(set (reg FLAGS_REG)
725         (compare
726           (match_operand:QI 0 "general_operand" "Qm")
727           (subreg:QI
728             (zero_extract:SI
729               (match_operand 1 "ext_register_operand" "Q")
730               (const_int 8)
731               (const_int 8)) 0)))]
732   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
733   "cmp{b}\t{%h1, %0|%0, %h1}"
734   [(set_attr "type" "icmp")
735    (set_attr "mode" "QI")])
736
737 (define_insn "*cmpqi_ext_1_rex64"
738   [(set (reg FLAGS_REG)
739         (compare
740           (match_operand:QI 0 "register_operand" "Q")
741           (subreg:QI
742             (zero_extract:SI
743               (match_operand 1 "ext_register_operand" "Q")
744               (const_int 8)
745               (const_int 8)) 0)))]
746   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
747   "cmp{b}\t{%h1, %0|%0, %h1}"
748   [(set_attr "type" "icmp")
749    (set_attr "mode" "QI")])
750
751 (define_insn "*cmpqi_ext_2"
752   [(set (reg FLAGS_REG)
753         (compare
754           (subreg:QI
755             (zero_extract:SI
756               (match_operand 0 "ext_register_operand" "Q")
757               (const_int 8)
758               (const_int 8)) 0)
759           (match_operand:QI 1 "const0_operand" "n")))]
760   "ix86_match_ccmode (insn, CCNOmode)"
761   "test{b}\t%h0, %h0"
762   [(set_attr "type" "test")
763    (set_attr "length_immediate" "0")
764    (set_attr "mode" "QI")])
765
766 (define_expand "cmpqi_ext_3"
767   [(set (reg:CC FLAGS_REG)
768         (compare:CC
769           (subreg:QI
770             (zero_extract:SI
771               (match_operand 0 "ext_register_operand" "")
772               (const_int 8)
773               (const_int 8)) 0)
774           (match_operand:QI 1 "general_operand" "")))]
775   ""
776   "")
777
778 (define_insn "cmpqi_ext_3_insn"
779   [(set (reg FLAGS_REG)
780         (compare
781           (subreg:QI
782             (zero_extract:SI
783               (match_operand 0 "ext_register_operand" "Q")
784               (const_int 8)
785               (const_int 8)) 0)
786           (match_operand:QI 1 "general_operand" "Qmn")))]
787   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
788   "cmp{b}\t{%1, %h0|%h0, %1}"
789   [(set_attr "type" "icmp")
790    (set_attr "mode" "QI")])
791
792 (define_insn "cmpqi_ext_3_insn_rex64"
793   [(set (reg FLAGS_REG)
794         (compare
795           (subreg:QI
796             (zero_extract:SI
797               (match_operand 0 "ext_register_operand" "Q")
798               (const_int 8)
799               (const_int 8)) 0)
800           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
801   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
802   "cmp{b}\t{%1, %h0|%h0, %1}"
803   [(set_attr "type" "icmp")
804    (set_attr "mode" "QI")])
805
806 (define_insn "*cmpqi_ext_4"
807   [(set (reg FLAGS_REG)
808         (compare
809           (subreg:QI
810             (zero_extract:SI
811               (match_operand 0 "ext_register_operand" "Q")
812               (const_int 8)
813               (const_int 8)) 0)
814           (subreg:QI
815             (zero_extract:SI
816               (match_operand 1 "ext_register_operand" "Q")
817               (const_int 8)
818               (const_int 8)) 0)))]
819   "ix86_match_ccmode (insn, CCmode)"
820   "cmp{b}\t{%h1, %h0|%h0, %h1}"
821   [(set_attr "type" "icmp")
822    (set_attr "mode" "QI")])
823
824 ;; These implement float point compares.
825 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
826 ;; which would allow mix and match FP modes on the compares.  Which is what
827 ;; the old patterns did, but with many more of them.
828
829 (define_expand "cmpxf"
830   [(set (reg:CC FLAGS_REG)
831         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
832                     (match_operand:XF 1 "nonmemory_operand" "")))]
833   "TARGET_80387"
834 {
835   ix86_compare_op0 = operands[0];
836   ix86_compare_op1 = operands[1];
837   DONE;
838 })
839
840 (define_expand "cmpdf"
841   [(set (reg:CC FLAGS_REG)
842         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
843                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
844   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
845 {
846   ix86_compare_op0 = operands[0];
847   ix86_compare_op1 = operands[1];
848   DONE;
849 })
850
851 (define_expand "cmpsf"
852   [(set (reg:CC FLAGS_REG)
853         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
854                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
855   "TARGET_80387 || TARGET_SSE_MATH"
856 {
857   ix86_compare_op0 = operands[0];
858   ix86_compare_op1 = operands[1];
859   DONE;
860 })
861
862 ;; FP compares, step 1:
863 ;; Set the FP condition codes.
864 ;;
865 ;; CCFPmode     compare with exceptions
866 ;; CCFPUmode    compare with no exceptions
867
868 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
869 ;; used to manage the reg stack popping would not be preserved.
870
871 (define_insn "*cmpfp_0"
872   [(set (match_operand:HI 0 "register_operand" "=a")
873         (unspec:HI
874           [(compare:CCFP
875              (match_operand 1 "register_operand" "f")
876              (match_operand 2 "const0_operand" "X"))]
877         UNSPEC_FNSTSW))]
878   "TARGET_80387
879    && FLOAT_MODE_P (GET_MODE (operands[1]))
880    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
881   "* return output_fp_compare (insn, operands, 0, 0);"
882   [(set_attr "type" "multi")
883    (set_attr "unit" "i387")
884    (set (attr "mode")
885      (cond [(match_operand:SF 1 "" "")
886               (const_string "SF")
887             (match_operand:DF 1 "" "")
888               (const_string "DF")
889            ]
890            (const_string "XF")))])
891
892 (define_insn "*cmpfp_sf"
893   [(set (match_operand:HI 0 "register_operand" "=a")
894         (unspec:HI
895           [(compare:CCFP
896              (match_operand:SF 1 "register_operand" "f")
897              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
898           UNSPEC_FNSTSW))]
899   "TARGET_80387"
900   "* return output_fp_compare (insn, operands, 0, 0);"
901   [(set_attr "type" "multi")
902    (set_attr "unit" "i387")
903    (set_attr "mode" "SF")])
904
905 (define_insn "*cmpfp_df"
906   [(set (match_operand:HI 0 "register_operand" "=a")
907         (unspec:HI
908           [(compare:CCFP
909              (match_operand:DF 1 "register_operand" "f")
910              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
911           UNSPEC_FNSTSW))]
912   "TARGET_80387"
913   "* return output_fp_compare (insn, operands, 0, 0);"
914   [(set_attr "type" "multi")
915    (set_attr "unit" "i387")
916    (set_attr "mode" "DF")])
917
918 (define_insn "*cmpfp_xf"
919   [(set (match_operand:HI 0 "register_operand" "=a")
920         (unspec:HI
921           [(compare:CCFP
922              (match_operand:XF 1 "register_operand" "f")
923              (match_operand:XF 2 "register_operand" "f"))]
924           UNSPEC_FNSTSW))]
925   "TARGET_80387"
926   "* return output_fp_compare (insn, operands, 0, 0);"
927   [(set_attr "type" "multi")
928    (set_attr "unit" "i387")
929    (set_attr "mode" "XF")])
930
931 (define_insn "*cmpfp_u"
932   [(set (match_operand:HI 0 "register_operand" "=a")
933         (unspec:HI
934           [(compare:CCFPU
935              (match_operand 1 "register_operand" "f")
936              (match_operand 2 "register_operand" "f"))]
937           UNSPEC_FNSTSW))]
938   "TARGET_80387
939    && FLOAT_MODE_P (GET_MODE (operands[1]))
940    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
941   "* return output_fp_compare (insn, operands, 0, 1);"
942   [(set_attr "type" "multi")
943    (set_attr "unit" "i387")
944    (set (attr "mode")
945      (cond [(match_operand:SF 1 "" "")
946               (const_string "SF")
947             (match_operand:DF 1 "" "")
948               (const_string "DF")
949            ]
950            (const_string "XF")))])
951
952 (define_insn "*cmpfp_<mode>"
953   [(set (match_operand:HI 0 "register_operand" "=a")
954         (unspec:HI
955           [(compare:CCFP
956              (match_operand 1 "register_operand" "f")
957              (match_operator 3 "float_operator"
958                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
959           UNSPEC_FNSTSW))]
960   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
961    && FLOAT_MODE_P (GET_MODE (operands[1]))
962    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
963   "* return output_fp_compare (insn, operands, 0, 0);"
964   [(set_attr "type" "multi")
965    (set_attr "unit" "i387")
966    (set_attr "fp_int_src" "true")
967    (set_attr "mode" "<MODE>")])
968
969 ;; FP compares, step 2
970 ;; Move the fpsw to ax.
971
972 (define_insn "x86_fnstsw_1"
973   [(set (match_operand:HI 0 "register_operand" "=a")
974         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
975   "TARGET_80387"
976   "fnstsw\t%0"
977   [(set_attr "length" "2")
978    (set_attr "mode" "SI")
979    (set_attr "unit" "i387")])
980
981 ;; FP compares, step 3
982 ;; Get ax into flags, general case.
983
984 (define_insn "x86_sahf_1"
985   [(set (reg:CC FLAGS_REG)
986         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
987   "!TARGET_64BIT"
988   "sahf"
989   [(set_attr "length" "1")
990    (set_attr "athlon_decode" "vector")
991    (set_attr "amdfam10_decode" "direct")
992    (set_attr "mode" "SI")])
993
994 ;; Pentium Pro can do steps 1 through 3 in one go.
995 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes) 
996 (define_insn "*cmpfp_i_mixed"
997   [(set (reg:CCFP FLAGS_REG)
998         (compare:CCFP (match_operand 0 "register_operand" "f,x")
999                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1000   "TARGET_MIX_SSE_I387
1001    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1002    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1003   "* return output_fp_compare (insn, operands, 1, 0);"
1004   [(set_attr "type" "fcmp,ssecomi")
1005    (set (attr "mode")
1006      (if_then_else (match_operand:SF 1 "" "")
1007         (const_string "SF")
1008         (const_string "DF")))
1009    (set_attr "athlon_decode" "vector")
1010    (set_attr "amdfam10_decode" "direct")])
1011
1012 (define_insn "*cmpfp_i_sse"
1013   [(set (reg:CCFP FLAGS_REG)
1014         (compare:CCFP (match_operand 0 "register_operand" "x")
1015                       (match_operand 1 "nonimmediate_operand" "xm")))]
1016   "TARGET_SSE_MATH
1017    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1018    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1019   "* return output_fp_compare (insn, operands, 1, 0);"
1020   [(set_attr "type" "ssecomi")
1021    (set (attr "mode")
1022      (if_then_else (match_operand:SF 1 "" "")
1023         (const_string "SF")
1024         (const_string "DF")))
1025    (set_attr "athlon_decode" "vector")
1026    (set_attr "amdfam10_decode" "direct")])
1027
1028 (define_insn "*cmpfp_i_i387"
1029   [(set (reg:CCFP FLAGS_REG)
1030         (compare:CCFP (match_operand 0 "register_operand" "f")
1031                       (match_operand 1 "register_operand" "f")))]
1032   "TARGET_80387 && TARGET_CMOVE
1033    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1034    && FLOAT_MODE_P (GET_MODE (operands[0]))
1035    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1036   "* return output_fp_compare (insn, operands, 1, 0);"
1037   [(set_attr "type" "fcmp")
1038    (set (attr "mode")
1039      (cond [(match_operand:SF 1 "" "")
1040               (const_string "SF")
1041             (match_operand:DF 1 "" "")
1042               (const_string "DF")
1043            ]
1044            (const_string "XF")))
1045    (set_attr "athlon_decode" "vector")
1046    (set_attr "amdfam10_decode" "direct")])
1047
1048 (define_insn "*cmpfp_iu_mixed"
1049   [(set (reg:CCFPU FLAGS_REG)
1050         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1051                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1052   "TARGET_MIX_SSE_I387
1053    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1054    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1055   "* return output_fp_compare (insn, operands, 1, 1);"
1056   [(set_attr "type" "fcmp,ssecomi")
1057    (set (attr "mode")
1058      (if_then_else (match_operand:SF 1 "" "")
1059         (const_string "SF")
1060         (const_string "DF")))
1061    (set_attr "athlon_decode" "vector")
1062    (set_attr "amdfam10_decode" "direct")])
1063
1064 (define_insn "*cmpfp_iu_sse"
1065   [(set (reg:CCFPU FLAGS_REG)
1066         (compare:CCFPU (match_operand 0 "register_operand" "x")
1067                        (match_operand 1 "nonimmediate_operand" "xm")))]
1068   "TARGET_SSE_MATH
1069    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1070    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1071   "* return output_fp_compare (insn, operands, 1, 1);"
1072   [(set_attr "type" "ssecomi")
1073    (set (attr "mode")
1074      (if_then_else (match_operand:SF 1 "" "")
1075         (const_string "SF")
1076         (const_string "DF")))
1077    (set_attr "athlon_decode" "vector")
1078    (set_attr "amdfam10_decode" "direct")])
1079
1080 (define_insn "*cmpfp_iu_387"
1081   [(set (reg:CCFPU FLAGS_REG)
1082         (compare:CCFPU (match_operand 0 "register_operand" "f")
1083                        (match_operand 1 "register_operand" "f")))]
1084   "TARGET_80387 && TARGET_CMOVE
1085    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1086    && FLOAT_MODE_P (GET_MODE (operands[0]))
1087    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1088   "* return output_fp_compare (insn, operands, 1, 1);"
1089   [(set_attr "type" "fcmp")
1090    (set (attr "mode")
1091      (cond [(match_operand:SF 1 "" "")
1092               (const_string "SF")
1093             (match_operand:DF 1 "" "")
1094               (const_string "DF")
1095            ]
1096            (const_string "XF")))
1097    (set_attr "athlon_decode" "vector")
1098    (set_attr "amdfam10_decode" "direct")])
1099 \f
1100 ;; Move instructions.
1101
1102 ;; General case of fullword move.
1103
1104 (define_expand "movsi"
1105   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1106         (match_operand:SI 1 "general_operand" ""))]
1107   ""
1108   "ix86_expand_move (SImode, operands); DONE;")
1109
1110 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1111 ;; general_operand.
1112 ;;
1113 ;; %%% We don't use a post-inc memory reference because x86 is not a
1114 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1115 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1116 ;; targets without our curiosities, and it is just as easy to represent
1117 ;; this differently.
1118
1119 (define_insn "*pushsi2"
1120   [(set (match_operand:SI 0 "push_operand" "=<")
1121         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1122   "!TARGET_64BIT"
1123   "push{l}\t%1"
1124   [(set_attr "type" "push")
1125    (set_attr "mode" "SI")])
1126
1127 ;; For 64BIT abi we always round up to 8 bytes.
1128 (define_insn "*pushsi2_rex64"
1129   [(set (match_operand:SI 0 "push_operand" "=X")
1130         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1131   "TARGET_64BIT"
1132   "push{q}\t%q1"
1133   [(set_attr "type" "push")
1134    (set_attr "mode" "SI")])
1135
1136 (define_insn "*pushsi2_prologue"
1137   [(set (match_operand:SI 0 "push_operand" "=<")
1138         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1139    (clobber (mem:BLK (scratch)))]
1140   "!TARGET_64BIT"
1141   "push{l}\t%1"
1142   [(set_attr "type" "push")
1143    (set_attr "mode" "SI")])
1144
1145 (define_insn "*popsi1_epilogue"
1146   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1147         (mem:SI (reg:SI SP_REG)))
1148    (set (reg:SI SP_REG)
1149         (plus:SI (reg:SI SP_REG) (const_int 4)))
1150    (clobber (mem:BLK (scratch)))]
1151   "!TARGET_64BIT"
1152   "pop{l}\t%0"
1153   [(set_attr "type" "pop")
1154    (set_attr "mode" "SI")])
1155
1156 (define_insn "popsi1"
1157   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1158         (mem:SI (reg:SI SP_REG)))
1159    (set (reg:SI SP_REG)
1160         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1161   "!TARGET_64BIT"
1162   "pop{l}\t%0"
1163   [(set_attr "type" "pop")
1164    (set_attr "mode" "SI")])
1165
1166 (define_insn "*movsi_xor"
1167   [(set (match_operand:SI 0 "register_operand" "=r")
1168         (match_operand:SI 1 "const0_operand" "i"))
1169    (clobber (reg:CC FLAGS_REG))]
1170   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1171   "xor{l}\t%0, %0"
1172   [(set_attr "type" "alu1")
1173    (set_attr "mode" "SI")
1174    (set_attr "length_immediate" "0")])
1175
1176 (define_insn "*movsi_or"
1177   [(set (match_operand:SI 0 "register_operand" "=r")
1178         (match_operand:SI 1 "immediate_operand" "i"))
1179    (clobber (reg:CC FLAGS_REG))]
1180   "reload_completed
1181    && operands[1] == constm1_rtx
1182    && (TARGET_PENTIUM || optimize_size)"
1183 {
1184   operands[1] = constm1_rtx;
1185   return "or{l}\t{%1, %0|%0, %1}";
1186 }
1187   [(set_attr "type" "alu1")
1188    (set_attr "mode" "SI")
1189    (set_attr "length_immediate" "1")])
1190
1191 (define_insn "*movsi_1"
1192   [(set (match_operand:SI 0 "nonimmediate_operand"
1193                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1194         (match_operand:SI 1 "general_operand"
1195                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1196   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1197 {
1198   switch (get_attr_type (insn))
1199     {
1200     case TYPE_SSELOG1:
1201       if (get_attr_mode (insn) == MODE_TI)
1202         return "pxor\t%0, %0";
1203       return "xorps\t%0, %0";
1204
1205     case TYPE_SSEMOV:
1206       switch (get_attr_mode (insn))
1207         {
1208         case MODE_TI:
1209           return "movdqa\t{%1, %0|%0, %1}";
1210         case MODE_V4SF:
1211           return "movaps\t{%1, %0|%0, %1}";
1212         case MODE_SI:
1213           return "movd\t{%1, %0|%0, %1}";
1214         case MODE_SF:
1215           return "movss\t{%1, %0|%0, %1}";
1216         default:
1217           gcc_unreachable ();
1218         }
1219
1220     case TYPE_MMXADD:
1221       return "pxor\t%0, %0";
1222
1223     case TYPE_MMXMOV:
1224       if (get_attr_mode (insn) == MODE_DI)
1225         return "movq\t{%1, %0|%0, %1}";
1226       return "movd\t{%1, %0|%0, %1}";
1227
1228     case TYPE_LEA:
1229       return "lea{l}\t{%1, %0|%0, %1}";
1230
1231     default:
1232       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1233       return "mov{l}\t{%1, %0|%0, %1}";
1234     }
1235 }
1236   [(set (attr "type")
1237      (cond [(eq_attr "alternative" "2")
1238               (const_string "mmxadd")
1239             (eq_attr "alternative" "3,4,5")
1240               (const_string "mmxmov")
1241             (eq_attr "alternative" "6")
1242               (const_string "sselog1")
1243             (eq_attr "alternative" "7,8,9,10,11")
1244               (const_string "ssemov")
1245             (match_operand:DI 1 "pic_32bit_operand" "")
1246               (const_string "lea")
1247            ]
1248            (const_string "imov")))
1249    (set (attr "mode")
1250      (cond [(eq_attr "alternative" "2,3")
1251               (const_string "DI")
1252             (eq_attr "alternative" "6,7")
1253               (if_then_else
1254                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1255                 (const_string "V4SF")
1256                 (const_string "TI"))
1257             (and (eq_attr "alternative" "8,9,10,11")
1258                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1259               (const_string "SF")
1260            ]
1261            (const_string "SI")))])
1262
1263 ;; Stores and loads of ax to arbitrary constant address.
1264 ;; We fake an second form of instruction to force reload to load address
1265 ;; into register when rax is not available
1266 (define_insn "*movabssi_1_rex64"
1267   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1268         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1269   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1270   "@
1271    movabs{l}\t{%1, %P0|%P0, %1}
1272    mov{l}\t{%1, %a0|%a0, %1}"
1273   [(set_attr "type" "imov")
1274    (set_attr "modrm" "0,*")
1275    (set_attr "length_address" "8,0")
1276    (set_attr "length_immediate" "0,*")
1277    (set_attr "memory" "store")
1278    (set_attr "mode" "SI")])
1279
1280 (define_insn "*movabssi_2_rex64"
1281   [(set (match_operand:SI 0 "register_operand" "=a,r")
1282         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1283   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1284   "@
1285    movabs{l}\t{%P1, %0|%0, %P1}
1286    mov{l}\t{%a1, %0|%0, %a1}"
1287   [(set_attr "type" "imov")
1288    (set_attr "modrm" "0,*")
1289    (set_attr "length_address" "8,0")
1290    (set_attr "length_immediate" "0")
1291    (set_attr "memory" "load")
1292    (set_attr "mode" "SI")])
1293
1294 (define_insn "*swapsi"
1295   [(set (match_operand:SI 0 "register_operand" "+r")
1296         (match_operand:SI 1 "register_operand" "+r"))
1297    (set (match_dup 1)
1298         (match_dup 0))]
1299   ""
1300   "xchg{l}\t%1, %0"
1301   [(set_attr "type" "imov")
1302    (set_attr "mode" "SI")
1303    (set_attr "pent_pair" "np")
1304    (set_attr "athlon_decode" "vector")
1305    (set_attr "amdfam10_decode" "double")])   
1306
1307 (define_expand "movhi"
1308   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1309         (match_operand:HI 1 "general_operand" ""))]
1310   ""
1311   "ix86_expand_move (HImode, operands); DONE;")
1312
1313 (define_insn "*pushhi2"
1314   [(set (match_operand:HI 0 "push_operand" "=X")
1315         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1316   "!TARGET_64BIT"
1317   "push{l}\t%k1"
1318   [(set_attr "type" "push")
1319    (set_attr "mode" "SI")])
1320
1321 ;; For 64BIT abi we always round up to 8 bytes.
1322 (define_insn "*pushhi2_rex64"
1323   [(set (match_operand:HI 0 "push_operand" "=X")
1324         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1325   "TARGET_64BIT"
1326   "push{q}\t%q1"
1327   [(set_attr "type" "push")
1328    (set_attr "mode" "DI")])
1329
1330 (define_insn "*movhi_1"
1331   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1332         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1333   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1334 {
1335   switch (get_attr_type (insn))
1336     {
1337     case TYPE_IMOVX:
1338       /* movzwl is faster than movw on p2 due to partial word stalls,
1339          though not as fast as an aligned movl.  */
1340       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1341     default:
1342       if (get_attr_mode (insn) == MODE_SI)
1343         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1344       else
1345         return "mov{w}\t{%1, %0|%0, %1}";
1346     }
1347 }
1348   [(set (attr "type")
1349      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1350               (const_string "imov")
1351             (and (eq_attr "alternative" "0")
1352                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1353                           (const_int 0))
1354                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1355                           (const_int 0))))
1356               (const_string "imov")
1357             (and (eq_attr "alternative" "1,2")
1358                  (match_operand:HI 1 "aligned_operand" ""))
1359               (const_string "imov")
1360             (and (ne (symbol_ref "TARGET_MOVX")
1361                      (const_int 0))
1362                  (eq_attr "alternative" "0,2"))
1363               (const_string "imovx")
1364            ]
1365            (const_string "imov")))
1366     (set (attr "mode")
1367       (cond [(eq_attr "type" "imovx")
1368                (const_string "SI")
1369              (and (eq_attr "alternative" "1,2")
1370                   (match_operand:HI 1 "aligned_operand" ""))
1371                (const_string "SI")
1372              (and (eq_attr "alternative" "0")
1373                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1374                            (const_int 0))
1375                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1376                            (const_int 0))))
1377                (const_string "SI")
1378             ]
1379             (const_string "HI")))])
1380
1381 ;; Stores and loads of ax to arbitrary constant address.
1382 ;; We fake an second form of instruction to force reload to load address
1383 ;; into register when rax is not available
1384 (define_insn "*movabshi_1_rex64"
1385   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1386         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1387   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1388   "@
1389    movabs{w}\t{%1, %P0|%P0, %1}
1390    mov{w}\t{%1, %a0|%a0, %1}"
1391   [(set_attr "type" "imov")
1392    (set_attr "modrm" "0,*")
1393    (set_attr "length_address" "8,0")
1394    (set_attr "length_immediate" "0,*")
1395    (set_attr "memory" "store")
1396    (set_attr "mode" "HI")])
1397
1398 (define_insn "*movabshi_2_rex64"
1399   [(set (match_operand:HI 0 "register_operand" "=a,r")
1400         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1401   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1402   "@
1403    movabs{w}\t{%P1, %0|%0, %P1}
1404    mov{w}\t{%a1, %0|%0, %a1}"
1405   [(set_attr "type" "imov")
1406    (set_attr "modrm" "0,*")
1407    (set_attr "length_address" "8,0")
1408    (set_attr "length_immediate" "0")
1409    (set_attr "memory" "load")
1410    (set_attr "mode" "HI")])
1411
1412 (define_insn "*swaphi_1"
1413   [(set (match_operand:HI 0 "register_operand" "+r")
1414         (match_operand:HI 1 "register_operand" "+r"))
1415    (set (match_dup 1)
1416         (match_dup 0))]
1417   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1418   "xchg{l}\t%k1, %k0"
1419   [(set_attr "type" "imov")
1420    (set_attr "mode" "SI")
1421    (set_attr "pent_pair" "np")
1422    (set_attr "athlon_decode" "vector")
1423    (set_attr "amdfam10_decode" "double")])   
1424
1425 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1426 (define_insn "*swaphi_2"
1427   [(set (match_operand:HI 0 "register_operand" "+r")
1428         (match_operand:HI 1 "register_operand" "+r"))
1429    (set (match_dup 1)
1430         (match_dup 0))]
1431   "TARGET_PARTIAL_REG_STALL"
1432   "xchg{w}\t%1, %0"
1433   [(set_attr "type" "imov")
1434    (set_attr "mode" "HI")
1435    (set_attr "pent_pair" "np")
1436    (set_attr "athlon_decode" "vector")])
1437
1438 (define_expand "movstricthi"
1439   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1440         (match_operand:HI 1 "general_operand" ""))]
1441   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1442 {
1443   /* Don't generate memory->memory moves, go through a register */
1444   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1445     operands[1] = force_reg (HImode, operands[1]);
1446 })
1447
1448 (define_insn "*movstricthi_1"
1449   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1450         (match_operand:HI 1 "general_operand" "rn,m"))]
1451   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1452    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1453   "mov{w}\t{%1, %0|%0, %1}"
1454   [(set_attr "type" "imov")
1455    (set_attr "mode" "HI")])
1456
1457 (define_insn "*movstricthi_xor"
1458   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1459         (match_operand:HI 1 "const0_operand" "i"))
1460    (clobber (reg:CC FLAGS_REG))]
1461   "reload_completed
1462    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1463   "xor{w}\t%0, %0"
1464   [(set_attr "type" "alu1")
1465    (set_attr "mode" "HI")
1466    (set_attr "length_immediate" "0")])
1467
1468 (define_expand "movqi"
1469   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1470         (match_operand:QI 1 "general_operand" ""))]
1471   ""
1472   "ix86_expand_move (QImode, operands); DONE;")
1473
1474 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1475 ;; "push a byte".  But actually we use pushl, which has the effect
1476 ;; of rounding the amount pushed up to a word.
1477
1478 (define_insn "*pushqi2"
1479   [(set (match_operand:QI 0 "push_operand" "=X")
1480         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1481   "!TARGET_64BIT"
1482   "push{l}\t%k1"
1483   [(set_attr "type" "push")
1484    (set_attr "mode" "SI")])
1485
1486 ;; For 64BIT abi we always round up to 8 bytes.
1487 (define_insn "*pushqi2_rex64"
1488   [(set (match_operand:QI 0 "push_operand" "=X")
1489         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1490   "TARGET_64BIT"
1491   "push{q}\t%q1"
1492   [(set_attr "type" "push")
1493    (set_attr "mode" "DI")])
1494
1495 ;; Situation is quite tricky about when to choose full sized (SImode) move
1496 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1497 ;; partial register dependency machines (such as AMD Athlon), where QImode
1498 ;; moves issue extra dependency and for partial register stalls machines
1499 ;; that don't use QImode patterns (and QImode move cause stall on the next
1500 ;; instruction).
1501 ;;
1502 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1503 ;; register stall machines with, where we use QImode instructions, since
1504 ;; partial register stall can be caused there.  Then we use movzx.
1505 (define_insn "*movqi_1"
1506   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1507         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1508   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1509 {
1510   switch (get_attr_type (insn))
1511     {
1512     case TYPE_IMOVX:
1513       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1514       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1515     default:
1516       if (get_attr_mode (insn) == MODE_SI)
1517         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1518       else
1519         return "mov{b}\t{%1, %0|%0, %1}";
1520     }
1521 }
1522   [(set (attr "type")
1523      (cond [(and (eq_attr "alternative" "5")
1524                  (not (match_operand:QI 1 "aligned_operand" "")))
1525               (const_string "imovx")
1526             (ne (symbol_ref "optimize_size") (const_int 0))
1527               (const_string "imov")
1528             (and (eq_attr "alternative" "3")
1529                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1530                           (const_int 0))
1531                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1532                           (const_int 0))))
1533               (const_string "imov")
1534             (eq_attr "alternative" "3,5")
1535               (const_string "imovx")
1536             (and (ne (symbol_ref "TARGET_MOVX")
1537                      (const_int 0))
1538                  (eq_attr "alternative" "2"))
1539               (const_string "imovx")
1540            ]
1541            (const_string "imov")))
1542    (set (attr "mode")
1543       (cond [(eq_attr "alternative" "3,4,5")
1544                (const_string "SI")
1545              (eq_attr "alternative" "6")
1546                (const_string "QI")
1547              (eq_attr "type" "imovx")
1548                (const_string "SI")
1549              (and (eq_attr "type" "imov")
1550                   (and (eq_attr "alternative" "0,1")
1551                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1552                                 (const_int 0))
1553                             (and (eq (symbol_ref "optimize_size")
1554                                      (const_int 0))
1555                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1556                                      (const_int 0))))))
1557                (const_string "SI")
1558              ;; Avoid partial register stalls when not using QImode arithmetic
1559              (and (eq_attr "type" "imov")
1560                   (and (eq_attr "alternative" "0,1")
1561                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1562                                 (const_int 0))
1563                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1564                                 (const_int 0)))))
1565                (const_string "SI")
1566            ]
1567            (const_string "QI")))])
1568
1569 (define_expand "reload_outqi"
1570   [(parallel [(match_operand:QI 0 "" "=m")
1571               (match_operand:QI 1 "register_operand" "r")
1572               (match_operand:QI 2 "register_operand" "=&q")])]
1573   ""
1574 {
1575   rtx op0, op1, op2;
1576   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1577
1578   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1579   if (! q_regs_operand (op1, QImode))
1580     {
1581       emit_insn (gen_movqi (op2, op1));
1582       op1 = op2;
1583     }
1584   emit_insn (gen_movqi (op0, op1));
1585   DONE;
1586 })
1587
1588 (define_insn "*swapqi_1"
1589   [(set (match_operand:QI 0 "register_operand" "+r")
1590         (match_operand:QI 1 "register_operand" "+r"))
1591    (set (match_dup 1)
1592         (match_dup 0))]
1593   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1594   "xchg{l}\t%k1, %k0"
1595   [(set_attr "type" "imov")
1596    (set_attr "mode" "SI")
1597    (set_attr "pent_pair" "np")
1598    (set_attr "athlon_decode" "vector")
1599    (set_attr "amdfam10_decode" "vector")])   
1600
1601 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1602 (define_insn "*swapqi_2"
1603   [(set (match_operand:QI 0 "register_operand" "+q")
1604         (match_operand:QI 1 "register_operand" "+q"))
1605    (set (match_dup 1)
1606         (match_dup 0))]
1607   "TARGET_PARTIAL_REG_STALL"
1608   "xchg{b}\t%1, %0"
1609   [(set_attr "type" "imov")
1610    (set_attr "mode" "QI")
1611    (set_attr "pent_pair" "np")
1612    (set_attr "athlon_decode" "vector")])
1613
1614 (define_expand "movstrictqi"
1615   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1616         (match_operand:QI 1 "general_operand" ""))]
1617   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1618 {
1619   /* Don't generate memory->memory moves, go through a register.  */
1620   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1621     operands[1] = force_reg (QImode, operands[1]);
1622 })
1623
1624 (define_insn "*movstrictqi_1"
1625   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1626         (match_operand:QI 1 "general_operand" "*qn,m"))]
1627   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1628    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1629   "mov{b}\t{%1, %0|%0, %1}"
1630   [(set_attr "type" "imov")
1631    (set_attr "mode" "QI")])
1632
1633 (define_insn "*movstrictqi_xor"
1634   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1635         (match_operand:QI 1 "const0_operand" "i"))
1636    (clobber (reg:CC FLAGS_REG))]
1637   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1638   "xor{b}\t%0, %0"
1639   [(set_attr "type" "alu1")
1640    (set_attr "mode" "QI")
1641    (set_attr "length_immediate" "0")])
1642
1643 (define_insn "*movsi_extv_1"
1644   [(set (match_operand:SI 0 "register_operand" "=R")
1645         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1646                          (const_int 8)
1647                          (const_int 8)))]
1648   ""
1649   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1650   [(set_attr "type" "imovx")
1651    (set_attr "mode" "SI")])
1652
1653 (define_insn "*movhi_extv_1"
1654   [(set (match_operand:HI 0 "register_operand" "=R")
1655         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1656                          (const_int 8)
1657                          (const_int 8)))]
1658   ""
1659   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1660   [(set_attr "type" "imovx")
1661    (set_attr "mode" "SI")])
1662
1663 (define_insn "*movqi_extv_1"
1664   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1665         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1666                          (const_int 8)
1667                          (const_int 8)))]
1668   "!TARGET_64BIT"
1669 {
1670   switch (get_attr_type (insn))
1671     {
1672     case TYPE_IMOVX:
1673       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1674     default:
1675       return "mov{b}\t{%h1, %0|%0, %h1}";
1676     }
1677 }
1678   [(set (attr "type")
1679      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1680                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1681                              (ne (symbol_ref "TARGET_MOVX")
1682                                  (const_int 0))))
1683         (const_string "imovx")
1684         (const_string "imov")))
1685    (set (attr "mode")
1686      (if_then_else (eq_attr "type" "imovx")
1687         (const_string "SI")
1688         (const_string "QI")))])
1689
1690 (define_insn "*movqi_extv_1_rex64"
1691   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1692         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1693                          (const_int 8)
1694                          (const_int 8)))]
1695   "TARGET_64BIT"
1696 {
1697   switch (get_attr_type (insn))
1698     {
1699     case TYPE_IMOVX:
1700       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1701     default:
1702       return "mov{b}\t{%h1, %0|%0, %h1}";
1703     }
1704 }
1705   [(set (attr "type")
1706      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1707                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1708                              (ne (symbol_ref "TARGET_MOVX")
1709                                  (const_int 0))))
1710         (const_string "imovx")
1711         (const_string "imov")))
1712    (set (attr "mode")
1713      (if_then_else (eq_attr "type" "imovx")
1714         (const_string "SI")
1715         (const_string "QI")))])
1716
1717 ;; Stores and loads of ax to arbitrary constant address.
1718 ;; We fake an second form of instruction to force reload to load address
1719 ;; into register when rax is not available
1720 (define_insn "*movabsqi_1_rex64"
1721   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1722         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1723   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1724   "@
1725    movabs{b}\t{%1, %P0|%P0, %1}
1726    mov{b}\t{%1, %a0|%a0, %1}"
1727   [(set_attr "type" "imov")
1728    (set_attr "modrm" "0,*")
1729    (set_attr "length_address" "8,0")
1730    (set_attr "length_immediate" "0,*")
1731    (set_attr "memory" "store")
1732    (set_attr "mode" "QI")])
1733
1734 (define_insn "*movabsqi_2_rex64"
1735   [(set (match_operand:QI 0 "register_operand" "=a,r")
1736         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1737   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1738   "@
1739    movabs{b}\t{%P1, %0|%0, %P1}
1740    mov{b}\t{%a1, %0|%0, %a1}"
1741   [(set_attr "type" "imov")
1742    (set_attr "modrm" "0,*")
1743    (set_attr "length_address" "8,0")
1744    (set_attr "length_immediate" "0")
1745    (set_attr "memory" "load")
1746    (set_attr "mode" "QI")])
1747
1748 (define_insn "*movdi_extzv_1"
1749   [(set (match_operand:DI 0 "register_operand" "=R")
1750         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1751                          (const_int 8)
1752                          (const_int 8)))]
1753   "TARGET_64BIT"
1754   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1755   [(set_attr "type" "imovx")
1756    (set_attr "mode" "DI")])
1757
1758 (define_insn "*movsi_extzv_1"
1759   [(set (match_operand:SI 0 "register_operand" "=R")
1760         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1761                          (const_int 8)
1762                          (const_int 8)))]
1763   ""
1764   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1765   [(set_attr "type" "imovx")
1766    (set_attr "mode" "SI")])
1767
1768 (define_insn "*movqi_extzv_2"
1769   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1770         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1771                                     (const_int 8)
1772                                     (const_int 8)) 0))]
1773   "!TARGET_64BIT"
1774 {
1775   switch (get_attr_type (insn))
1776     {
1777     case TYPE_IMOVX:
1778       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1779     default:
1780       return "mov{b}\t{%h1, %0|%0, %h1}";
1781     }
1782 }
1783   [(set (attr "type")
1784      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1785                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1786                              (ne (symbol_ref "TARGET_MOVX")
1787                                  (const_int 0))))
1788         (const_string "imovx")
1789         (const_string "imov")))
1790    (set (attr "mode")
1791      (if_then_else (eq_attr "type" "imovx")
1792         (const_string "SI")
1793         (const_string "QI")))])
1794
1795 (define_insn "*movqi_extzv_2_rex64"
1796   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1797         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1798                                     (const_int 8)
1799                                     (const_int 8)) 0))]
1800   "TARGET_64BIT"
1801 {
1802   switch (get_attr_type (insn))
1803     {
1804     case TYPE_IMOVX:
1805       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1806     default:
1807       return "mov{b}\t{%h1, %0|%0, %h1}";
1808     }
1809 }
1810   [(set (attr "type")
1811      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1812                         (ne (symbol_ref "TARGET_MOVX")
1813                             (const_int 0)))
1814         (const_string "imovx")
1815         (const_string "imov")))
1816    (set (attr "mode")
1817      (if_then_else (eq_attr "type" "imovx")
1818         (const_string "SI")
1819         (const_string "QI")))])
1820
1821 (define_insn "movsi_insv_1"
1822   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1823                          (const_int 8)
1824                          (const_int 8))
1825         (match_operand:SI 1 "general_operand" "Qmn"))]
1826   "!TARGET_64BIT"
1827   "mov{b}\t{%b1, %h0|%h0, %b1}"
1828   [(set_attr "type" "imov")
1829    (set_attr "mode" "QI")])
1830
1831 (define_insn "*movsi_insv_1_rex64"
1832   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1833                          (const_int 8)
1834                          (const_int 8))
1835         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1836   "TARGET_64BIT"
1837   "mov{b}\t{%b1, %h0|%h0, %b1}"
1838   [(set_attr "type" "imov")
1839    (set_attr "mode" "QI")])
1840
1841 (define_insn "movdi_insv_1_rex64"
1842   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1843                          (const_int 8)
1844                          (const_int 8))
1845         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1846   "TARGET_64BIT"
1847   "mov{b}\t{%b1, %h0|%h0, %b1}"
1848   [(set_attr "type" "imov")
1849    (set_attr "mode" "QI")])
1850
1851 (define_insn "*movqi_insv_2"
1852   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1853                          (const_int 8)
1854                          (const_int 8))
1855         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1856                      (const_int 8)))]
1857   ""
1858   "mov{b}\t{%h1, %h0|%h0, %h1}"
1859   [(set_attr "type" "imov")
1860    (set_attr "mode" "QI")])
1861
1862 (define_expand "movdi"
1863   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1864         (match_operand:DI 1 "general_operand" ""))]
1865   ""
1866   "ix86_expand_move (DImode, operands); DONE;")
1867
1868 (define_insn "*pushdi"
1869   [(set (match_operand:DI 0 "push_operand" "=<")
1870         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1871   "!TARGET_64BIT"
1872   "#")
1873
1874 (define_insn "*pushdi2_rex64"
1875   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1876         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1877   "TARGET_64BIT"
1878   "@
1879    push{q}\t%1
1880    #"
1881   [(set_attr "type" "push,multi")
1882    (set_attr "mode" "DI")])
1883
1884 ;; Convert impossible pushes of immediate to existing instructions.
1885 ;; First try to get scratch register and go through it.  In case this
1886 ;; fails, push sign extended lower part first and then overwrite
1887 ;; upper part by 32bit move.
1888 (define_peephole2
1889   [(match_scratch:DI 2 "r")
1890    (set (match_operand:DI 0 "push_operand" "")
1891         (match_operand:DI 1 "immediate_operand" ""))]
1892   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1893    && !x86_64_immediate_operand (operands[1], DImode)"
1894   [(set (match_dup 2) (match_dup 1))
1895    (set (match_dup 0) (match_dup 2))]
1896   "")
1897
1898 ;; We need to define this as both peepholer and splitter for case
1899 ;; peephole2 pass is not run.
1900 ;; "&& 1" is needed to keep it from matching the previous pattern.
1901 (define_peephole2
1902   [(set (match_operand:DI 0 "push_operand" "")
1903         (match_operand:DI 1 "immediate_operand" ""))]
1904   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1905    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1906   [(set (match_dup 0) (match_dup 1))
1907    (set (match_dup 2) (match_dup 3))]
1908   "split_di (operands + 1, 1, operands + 2, operands + 3);
1909    operands[1] = gen_lowpart (DImode, operands[2]);
1910    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1911                                                     GEN_INT (4)));
1912   ")
1913
1914 (define_split
1915   [(set (match_operand:DI 0 "push_operand" "")
1916         (match_operand:DI 1 "immediate_operand" ""))]
1917   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1918                     ? flow2_completed : reload_completed)
1919    && !symbolic_operand (operands[1], DImode)
1920    && !x86_64_immediate_operand (operands[1], DImode)"
1921   [(set (match_dup 0) (match_dup 1))
1922    (set (match_dup 2) (match_dup 3))]
1923   "split_di (operands + 1, 1, operands + 2, operands + 3);
1924    operands[1] = gen_lowpart (DImode, operands[2]);
1925    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1926                                                     GEN_INT (4)));
1927   ")
1928
1929 (define_insn "*pushdi2_prologue_rex64"
1930   [(set (match_operand:DI 0 "push_operand" "=<")
1931         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1932    (clobber (mem:BLK (scratch)))]
1933   "TARGET_64BIT"
1934   "push{q}\t%1"
1935   [(set_attr "type" "push")
1936    (set_attr "mode" "DI")])
1937
1938 (define_insn "*popdi1_epilogue_rex64"
1939   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1940         (mem:DI (reg:DI SP_REG)))
1941    (set (reg:DI SP_REG)
1942         (plus:DI (reg:DI SP_REG) (const_int 8)))
1943    (clobber (mem:BLK (scratch)))]
1944   "TARGET_64BIT"
1945   "pop{q}\t%0"
1946   [(set_attr "type" "pop")
1947    (set_attr "mode" "DI")])
1948
1949 (define_insn "popdi1"
1950   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1951         (mem:DI (reg:DI SP_REG)))
1952    (set (reg:DI SP_REG)
1953         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1954   "TARGET_64BIT"
1955   "pop{q}\t%0"
1956   [(set_attr "type" "pop")
1957    (set_attr "mode" "DI")])
1958
1959 (define_insn "*movdi_xor_rex64"
1960   [(set (match_operand:DI 0 "register_operand" "=r")
1961         (match_operand:DI 1 "const0_operand" "i"))
1962    (clobber (reg:CC FLAGS_REG))]
1963   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1964    && reload_completed"
1965   "xor{l}\t%k0, %k0";
1966   [(set_attr "type" "alu1")
1967    (set_attr "mode" "SI")
1968    (set_attr "length_immediate" "0")])
1969
1970 (define_insn "*movdi_or_rex64"
1971   [(set (match_operand:DI 0 "register_operand" "=r")
1972         (match_operand:DI 1 "const_int_operand" "i"))
1973    (clobber (reg:CC FLAGS_REG))]
1974   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1975    && reload_completed
1976    && operands[1] == constm1_rtx"
1977 {
1978   operands[1] = constm1_rtx;
1979   return "or{q}\t{%1, %0|%0, %1}";
1980 }
1981   [(set_attr "type" "alu1")
1982    (set_attr "mode" "DI")
1983    (set_attr "length_immediate" "1")])
1984
1985 (define_insn "*movdi_2"
1986   [(set (match_operand:DI 0 "nonimmediate_operand"
1987                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
1988         (match_operand:DI 1 "general_operand"
1989                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
1990   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1991   "@
1992    #
1993    #
1994    pxor\t%0, %0
1995    movq\t{%1, %0|%0, %1}
1996    movq\t{%1, %0|%0, %1}
1997    pxor\t%0, %0
1998    movq\t{%1, %0|%0, %1}
1999    movdqa\t{%1, %0|%0, %1}
2000    movq\t{%1, %0|%0, %1}
2001    xorps\t%0, %0
2002    movlps\t{%1, %0|%0, %1}
2003    movaps\t{%1, %0|%0, %1}
2004    movlps\t{%1, %0|%0, %1}"
2005   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2006    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2007
2008 (define_split
2009   [(set (match_operand:DI 0 "push_operand" "")
2010         (match_operand:DI 1 "general_operand" ""))]
2011   "!TARGET_64BIT && reload_completed
2012    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2013   [(const_int 0)]
2014   "ix86_split_long_move (operands); DONE;")
2015
2016 ;; %%% This multiword shite has got to go.
2017 (define_split
2018   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2019         (match_operand:DI 1 "general_operand" ""))]
2020   "!TARGET_64BIT && reload_completed
2021    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2022    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2023   [(const_int 0)]
2024   "ix86_split_long_move (operands); DONE;")
2025
2026 (define_insn "*movdi_1_rex64"
2027   [(set (match_operand:DI 0 "nonimmediate_operand"
2028           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2029         (match_operand:DI 1 "general_operand"
2030           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2031   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2032 {
2033   switch (get_attr_type (insn))
2034     {
2035     case TYPE_SSECVT:
2036       if (SSE_REG_P (operands[0]))
2037         return "movq2dq\t{%1, %0|%0, %1}";
2038       else
2039         return "movdq2q\t{%1, %0|%0, %1}";
2040
2041     case TYPE_SSEMOV:
2042       if (get_attr_mode (insn) == MODE_TI)
2043         return "movdqa\t{%1, %0|%0, %1}";
2044       /* FALLTHRU */
2045
2046     case TYPE_MMXMOV:
2047       /* Moves from and into integer register is done using movd
2048          opcode with REX prefix.  */
2049       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2050         return "movd\t{%1, %0|%0, %1}";
2051       return "movq\t{%1, %0|%0, %1}";
2052
2053     case TYPE_SSELOG1:
2054     case TYPE_MMXADD:
2055       return "pxor\t%0, %0";
2056
2057     case TYPE_MULTI:
2058       return "#";
2059
2060     case TYPE_LEA:
2061       return "lea{q}\t{%a1, %0|%0, %a1}";
2062
2063     default:
2064       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2065       if (get_attr_mode (insn) == MODE_SI)
2066         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2067       else if (which_alternative == 2)
2068         return "movabs{q}\t{%1, %0|%0, %1}";
2069       else
2070         return "mov{q}\t{%1, %0|%0, %1}";
2071     }
2072 }
2073   [(set (attr "type")
2074      (cond [(eq_attr "alternative" "5")
2075               (const_string "mmxadd")
2076             (eq_attr "alternative" "6,7,8,9,10")
2077               (const_string "mmxmov")
2078             (eq_attr "alternative" "11")
2079               (const_string "sselog1")
2080             (eq_attr "alternative" "12,13,14,15,16")
2081               (const_string "ssemov")
2082             (eq_attr "alternative" "17,18")
2083               (const_string "ssecvt")
2084             (eq_attr "alternative" "4")
2085               (const_string "multi")
2086             (match_operand:DI 1 "pic_32bit_operand" "")
2087               (const_string "lea")
2088            ]
2089            (const_string "imov")))
2090    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2091    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2092    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2093
2094 ;; Stores and loads of ax to arbitrary constant address.
2095 ;; We fake an second form of instruction to force reload to load address
2096 ;; into register when rax is not available
2097 (define_insn "*movabsdi_1_rex64"
2098   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2099         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2100   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2101   "@
2102    movabs{q}\t{%1, %P0|%P0, %1}
2103    mov{q}\t{%1, %a0|%a0, %1}"
2104   [(set_attr "type" "imov")
2105    (set_attr "modrm" "0,*")
2106    (set_attr "length_address" "8,0")
2107    (set_attr "length_immediate" "0,*")
2108    (set_attr "memory" "store")
2109    (set_attr "mode" "DI")])
2110
2111 (define_insn "*movabsdi_2_rex64"
2112   [(set (match_operand:DI 0 "register_operand" "=a,r")
2113         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2114   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2115   "@
2116    movabs{q}\t{%P1, %0|%0, %P1}
2117    mov{q}\t{%a1, %0|%0, %a1}"
2118   [(set_attr "type" "imov")
2119    (set_attr "modrm" "0,*")
2120    (set_attr "length_address" "8,0")
2121    (set_attr "length_immediate" "0")
2122    (set_attr "memory" "load")
2123    (set_attr "mode" "DI")])
2124
2125 ;; Convert impossible stores of immediate to existing instructions.
2126 ;; First try to get scratch register and go through it.  In case this
2127 ;; fails, move by 32bit parts.
2128 (define_peephole2
2129   [(match_scratch:DI 2 "r")
2130    (set (match_operand:DI 0 "memory_operand" "")
2131         (match_operand:DI 1 "immediate_operand" ""))]
2132   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2133    && !x86_64_immediate_operand (operands[1], DImode)"
2134   [(set (match_dup 2) (match_dup 1))
2135    (set (match_dup 0) (match_dup 2))]
2136   "")
2137
2138 ;; We need to define this as both peepholer and splitter for case
2139 ;; peephole2 pass is not run.
2140 ;; "&& 1" is needed to keep it from matching the previous pattern.
2141 (define_peephole2
2142   [(set (match_operand:DI 0 "memory_operand" "")
2143         (match_operand:DI 1 "immediate_operand" ""))]
2144   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2145    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2146   [(set (match_dup 2) (match_dup 3))
2147    (set (match_dup 4) (match_dup 5))]
2148   "split_di (operands, 2, operands + 2, operands + 4);")
2149
2150 (define_split
2151   [(set (match_operand:DI 0 "memory_operand" "")
2152         (match_operand:DI 1 "immediate_operand" ""))]
2153   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2154                     ? flow2_completed : reload_completed)
2155    && !symbolic_operand (operands[1], DImode)
2156    && !x86_64_immediate_operand (operands[1], DImode)"
2157   [(set (match_dup 2) (match_dup 3))
2158    (set (match_dup 4) (match_dup 5))]
2159   "split_di (operands, 2, operands + 2, operands + 4);")
2160
2161 (define_insn "*swapdi_rex64"
2162   [(set (match_operand:DI 0 "register_operand" "+r")
2163         (match_operand:DI 1 "register_operand" "+r"))
2164    (set (match_dup 1)
2165         (match_dup 0))]
2166   "TARGET_64BIT"
2167   "xchg{q}\t%1, %0"
2168   [(set_attr "type" "imov")
2169    (set_attr "mode" "DI")
2170    (set_attr "pent_pair" "np")
2171    (set_attr "athlon_decode" "vector")
2172    (set_attr "amdfam10_decode" "double")])   
2173
2174 (define_expand "movti"
2175   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2176         (match_operand:TI 1 "nonimmediate_operand" ""))]
2177   "TARGET_SSE || TARGET_64BIT"
2178 {
2179   if (TARGET_64BIT)
2180     ix86_expand_move (TImode, operands);
2181   else
2182     ix86_expand_vector_move (TImode, operands);
2183   DONE;
2184 })
2185
2186 (define_insn "*movti_internal"
2187   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2188         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2189   "TARGET_SSE && !TARGET_64BIT
2190    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2191 {
2192   switch (which_alternative)
2193     {
2194     case 0:
2195       if (get_attr_mode (insn) == MODE_V4SF)
2196         return "xorps\t%0, %0";
2197       else
2198         return "pxor\t%0, %0";
2199     case 1:
2200     case 2:
2201       if (get_attr_mode (insn) == MODE_V4SF)
2202         return "movaps\t{%1, %0|%0, %1}";
2203       else
2204         return "movdqa\t{%1, %0|%0, %1}";
2205     default:
2206       gcc_unreachable ();
2207     }
2208 }
2209   [(set_attr "type" "sselog1,ssemov,ssemov")
2210    (set (attr "mode")
2211         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2212                     (ne (symbol_ref "optimize_size") (const_int 0)))
2213                  (const_string "V4SF")
2214                (and (eq_attr "alternative" "2")
2215                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2216                         (const_int 0)))
2217                  (const_string "V4SF")]
2218               (const_string "TI")))])
2219
2220 (define_insn "*movti_rex64"
2221   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2222         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2223   "TARGET_64BIT
2224    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2225 {
2226   switch (which_alternative)
2227     {
2228     case 0:
2229     case 1:
2230       return "#";
2231     case 2:
2232       if (get_attr_mode (insn) == MODE_V4SF)
2233         return "xorps\t%0, %0";
2234       else
2235         return "pxor\t%0, %0";
2236     case 3:
2237     case 4:
2238       if (get_attr_mode (insn) == MODE_V4SF)
2239         return "movaps\t{%1, %0|%0, %1}";
2240       else
2241         return "movdqa\t{%1, %0|%0, %1}";
2242     default:
2243       gcc_unreachable ();
2244     }
2245 }
2246   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2247    (set (attr "mode")
2248         (cond [(eq_attr "alternative" "2,3")
2249                  (if_then_else
2250                    (ne (symbol_ref "optimize_size")
2251                        (const_int 0))
2252                    (const_string "V4SF")
2253                    (const_string "TI"))
2254                (eq_attr "alternative" "4")
2255                  (if_then_else
2256                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2257                             (const_int 0))
2258                         (ne (symbol_ref "optimize_size")
2259                             (const_int 0)))
2260                    (const_string "V4SF")
2261                    (const_string "TI"))]
2262                (const_string "DI")))])
2263
2264 (define_split
2265   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2266         (match_operand:TI 1 "general_operand" ""))]
2267   "reload_completed && !SSE_REG_P (operands[0])
2268    && !SSE_REG_P (operands[1])"
2269   [(const_int 0)]
2270   "ix86_split_long_move (operands); DONE;")
2271
2272 (define_expand "movsf"
2273   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2274         (match_operand:SF 1 "general_operand" ""))]
2275   ""
2276   "ix86_expand_move (SFmode, operands); DONE;")
2277
2278 (define_insn "*pushsf"
2279   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2280         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2281   "!TARGET_64BIT"
2282 {
2283   /* Anything else should be already split before reg-stack.  */
2284   gcc_assert (which_alternative == 1);
2285   return "push{l}\t%1";
2286 }
2287   [(set_attr "type" "multi,push,multi")
2288    (set_attr "unit" "i387,*,*")
2289    (set_attr "mode" "SF,SI,SF")])
2290
2291 (define_insn "*pushsf_rex64"
2292   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2293         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2294   "TARGET_64BIT"
2295 {
2296   /* Anything else should be already split before reg-stack.  */
2297   gcc_assert (which_alternative == 1);
2298   return "push{q}\t%q1";
2299 }
2300   [(set_attr "type" "multi,push,multi")
2301    (set_attr "unit" "i387,*,*")
2302    (set_attr "mode" "SF,DI,SF")])
2303
2304 (define_split
2305   [(set (match_operand:SF 0 "push_operand" "")
2306         (match_operand:SF 1 "memory_operand" ""))]
2307   "reload_completed
2308    && MEM_P (operands[1])
2309    && constant_pool_reference_p (operands[1])"
2310   [(set (match_dup 0)
2311         (match_dup 1))]
2312   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2313
2314
2315 ;; %%% Kill this when call knows how to work this out.
2316 (define_split
2317   [(set (match_operand:SF 0 "push_operand" "")
2318         (match_operand:SF 1 "any_fp_register_operand" ""))]
2319   "!TARGET_64BIT"
2320   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2321    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2322
2323 (define_split
2324   [(set (match_operand:SF 0 "push_operand" "")
2325         (match_operand:SF 1 "any_fp_register_operand" ""))]
2326   "TARGET_64BIT"
2327   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2328    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2329
2330 (define_insn "*movsf_1"
2331   [(set (match_operand:SF 0 "nonimmediate_operand"
2332           "=f,m,f,r  ,m ,x,x,x ,m,*y,m ,*y,Yi,r ,*Ym,r  ")
2333         (match_operand:SF 1 "general_operand"
2334           "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y,r ,Yi,r  ,*Ym"))]
2335   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2336    && (reload_in_progress || reload_completed
2337        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2338        || (!TARGET_SSE_MATH && optimize_size
2339            && standard_80387_constant_p (operands[1]))
2340        || GET_CODE (operands[1]) != CONST_DOUBLE
2341        || memory_operand (operands[0], SFmode))"
2342 {
2343   switch (which_alternative)
2344     {
2345     case 0:
2346       return output_387_reg_move (insn, operands);
2347
2348     case 1:
2349       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2350         return "fstp%z0\t%y0";
2351       else
2352         return "fst%z0\t%y0";
2353
2354     case 2:
2355       return standard_80387_constant_opcode (operands[1]);
2356
2357     case 3:
2358     case 4:
2359       return "mov{l}\t{%1, %0|%0, %1}";
2360     case 5:
2361       if (get_attr_mode (insn) == MODE_TI)
2362         return "pxor\t%0, %0";
2363       else
2364         return "xorps\t%0, %0";
2365     case 6:
2366       if (get_attr_mode (insn) == MODE_V4SF)
2367         return "movaps\t{%1, %0|%0, %1}";
2368       else
2369         return "movss\t{%1, %0|%0, %1}";
2370     case 7: case 8:
2371       return "movss\t{%1, %0|%0, %1}";
2372
2373     case 9: case 10:
2374     case 12: case 13: case 14: case 15:
2375       return "movd\t{%1, %0|%0, %1}";
2376
2377     case 11:
2378       return "movq\t{%1, %0|%0, %1}";
2379
2380     default:
2381       gcc_unreachable ();
2382     }
2383 }
2384   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2385    (set (attr "mode")
2386         (cond [(eq_attr "alternative" "3,4,9,10")
2387                  (const_string "SI")
2388                (eq_attr "alternative" "5")
2389                  (if_then_else
2390                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2391                                  (const_int 0))
2392                              (ne (symbol_ref "TARGET_SSE2")
2393                                  (const_int 0)))
2394                         (eq (symbol_ref "optimize_size")
2395                             (const_int 0)))
2396                    (const_string "TI")
2397                    (const_string "V4SF"))
2398                /* For architectures resolving dependencies on
2399                   whole SSE registers use APS move to break dependency
2400                   chains, otherwise use short move to avoid extra work.
2401
2402                   Do the same for architectures resolving dependencies on
2403                   the parts.  While in DF mode it is better to always handle
2404                   just register parts, the SF mode is different due to lack
2405                   of instructions to load just part of the register.  It is
2406                   better to maintain the whole registers in single format
2407                   to avoid problems on using packed logical operations.  */
2408                (eq_attr "alternative" "6")
2409                  (if_then_else
2410                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2411                             (const_int 0))
2412                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2413                             (const_int 0)))
2414                    (const_string "V4SF")
2415                    (const_string "SF"))
2416                (eq_attr "alternative" "11")
2417                  (const_string "DI")]
2418                (const_string "SF")))])
2419
2420 (define_insn "*swapsf"
2421   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2422         (match_operand:SF 1 "fp_register_operand" "+f"))
2423    (set (match_dup 1)
2424         (match_dup 0))]
2425   "reload_completed || TARGET_80387"
2426 {
2427   if (STACK_TOP_P (operands[0]))
2428     return "fxch\t%1";
2429   else
2430     return "fxch\t%0";
2431 }
2432   [(set_attr "type" "fxch")
2433    (set_attr "mode" "SF")])
2434
2435 (define_expand "movdf"
2436   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2437         (match_operand:DF 1 "general_operand" ""))]
2438   ""
2439   "ix86_expand_move (DFmode, operands); DONE;")
2440
2441 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2442 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2443 ;; On the average, pushdf using integers can be still shorter.  Allow this
2444 ;; pattern for optimize_size too.
2445
2446 (define_insn "*pushdf_nointeger"
2447   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2448         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2449   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2450 {
2451   /* This insn should be already split before reg-stack.  */
2452   gcc_unreachable ();
2453 }
2454   [(set_attr "type" "multi")
2455    (set_attr "unit" "i387,*,*,*")
2456    (set_attr "mode" "DF,SI,SI,DF")])
2457
2458 (define_insn "*pushdf_integer"
2459   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2460         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2461   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2462 {
2463   /* This insn should be already split before reg-stack.  */
2464   gcc_unreachable ();
2465 }
2466   [(set_attr "type" "multi")
2467    (set_attr "unit" "i387,*,*")
2468    (set_attr "mode" "DF,SI,DF")])
2469
2470 ;; %%% Kill this when call knows how to work this out.
2471 (define_split
2472   [(set (match_operand:DF 0 "push_operand" "")
2473         (match_operand:DF 1 "any_fp_register_operand" ""))]
2474   "!TARGET_64BIT && reload_completed"
2475   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2476    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2477   "")
2478
2479 (define_split
2480   [(set (match_operand:DF 0 "push_operand" "")
2481         (match_operand:DF 1 "any_fp_register_operand" ""))]
2482   "TARGET_64BIT && reload_completed"
2483   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2484    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2485   "")
2486
2487 (define_split
2488   [(set (match_operand:DF 0 "push_operand" "")
2489         (match_operand:DF 1 "general_operand" ""))]
2490   "reload_completed"
2491   [(const_int 0)]
2492   "ix86_split_long_move (operands); DONE;")
2493
2494 ;; Moving is usually shorter when only FP registers are used. This separate
2495 ;; movdf pattern avoids the use of integer registers for FP operations
2496 ;; when optimizing for size.
2497
2498 (define_insn "*movdf_nointeger"
2499   [(set (match_operand:DF 0 "nonimmediate_operand"
2500                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
2501         (match_operand:DF 1 "general_operand"
2502                         "fm,f,G,*roF,F*r,C   ,Y2*x,mY2*x,Y2*x"))]
2503   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2504    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2505    && (reload_in_progress || reload_completed
2506        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2507        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2508            && standard_80387_constant_p (operands[1]))
2509        || GET_CODE (operands[1]) != CONST_DOUBLE
2510        || memory_operand (operands[0], DFmode))"
2511 {
2512   switch (which_alternative)
2513     {
2514     case 0:
2515       return output_387_reg_move (insn, operands);
2516
2517     case 1:
2518       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2519         return "fstp%z0\t%y0";
2520       else
2521         return "fst%z0\t%y0";
2522
2523     case 2:
2524       return standard_80387_constant_opcode (operands[1]);
2525
2526     case 3:
2527     case 4:
2528       return "#";
2529     case 5:
2530       switch (get_attr_mode (insn))
2531         {
2532         case MODE_V4SF:
2533           return "xorps\t%0, %0";
2534         case MODE_V2DF:
2535           return "xorpd\t%0, %0";
2536         case MODE_TI:
2537           return "pxor\t%0, %0";
2538         default:
2539           gcc_unreachable ();
2540         }
2541     case 6:
2542     case 7:
2543     case 8:
2544       switch (get_attr_mode (insn))
2545         {
2546         case MODE_V4SF:
2547           return "movaps\t{%1, %0|%0, %1}";
2548         case MODE_V2DF:
2549           return "movapd\t{%1, %0|%0, %1}";
2550         case MODE_TI:
2551           return "movdqa\t{%1, %0|%0, %1}";
2552         case MODE_DI:
2553           return "movq\t{%1, %0|%0, %1}";
2554         case MODE_DF:
2555           return "movsd\t{%1, %0|%0, %1}";
2556         case MODE_V1DF:
2557           return "movlpd\t{%1, %0|%0, %1}";
2558         case MODE_V2SF:
2559           return "movlps\t{%1, %0|%0, %1}";
2560         default:
2561           gcc_unreachable ();
2562         }
2563
2564     default:
2565       gcc_unreachable ();
2566     }
2567 }
2568   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2569    (set (attr "mode")
2570         (cond [(eq_attr "alternative" "0,1,2")
2571                  (const_string "DF")
2572                (eq_attr "alternative" "3,4")
2573                  (const_string "SI")
2574
2575                /* For SSE1, we have many fewer alternatives.  */
2576                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2577                  (cond [(eq_attr "alternative" "5,6")
2578                           (const_string "V4SF")
2579                        ]
2580                    (const_string "V2SF"))
2581
2582                /* xorps is one byte shorter.  */
2583                (eq_attr "alternative" "5")
2584                  (cond [(ne (symbol_ref "optimize_size")
2585                             (const_int 0))
2586                           (const_string "V4SF")
2587                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2588                             (const_int 0))
2589                           (const_string "TI")
2590                        ]
2591                        (const_string "V2DF"))
2592
2593                /* For architectures resolving dependencies on
2594                   whole SSE registers use APD move to break dependency
2595                   chains, otherwise use short move to avoid extra work.
2596
2597                   movaps encodes one byte shorter.  */
2598                (eq_attr "alternative" "6")
2599                  (cond
2600                    [(ne (symbol_ref "optimize_size")
2601                         (const_int 0))
2602                       (const_string "V4SF")
2603                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2604                         (const_int 0))
2605                       (const_string "V2DF")
2606                    ]
2607                    (const_string "DF"))
2608                /* For architectures resolving dependencies on register
2609                   parts we may avoid extra work to zero out upper part
2610                   of register.  */
2611                (eq_attr "alternative" "7")
2612                  (if_then_else
2613                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2614                        (const_int 0))
2615                    (const_string "V1DF")
2616                    (const_string "DF"))
2617               ]
2618               (const_string "DF")))])
2619
2620 (define_insn "*movdf_integer_rex64"
2621   [(set (match_operand:DF 0 "nonimmediate_operand"
2622                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2623         (match_operand:DF 1 "general_operand"
2624                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2625   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2626    && (reload_in_progress || reload_completed
2627        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2628        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2629            && standard_80387_constant_p (operands[1]))
2630        || GET_CODE (operands[1]) != CONST_DOUBLE
2631        || memory_operand (operands[0], DFmode))"
2632 {
2633   switch (which_alternative)
2634     {
2635     case 0:
2636       return output_387_reg_move (insn, operands);
2637
2638     case 1:
2639       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2640         return "fstp%z0\t%y0";
2641       else
2642         return "fst%z0\t%y0";
2643
2644     case 2:
2645       return standard_80387_constant_opcode (operands[1]);
2646
2647     case 3:
2648     case 4:
2649       return "#";
2650
2651     case 5:
2652       switch (get_attr_mode (insn))
2653         {
2654         case MODE_V4SF:
2655           return "xorps\t%0, %0";
2656         case MODE_V2DF:
2657           return "xorpd\t%0, %0";
2658         case MODE_TI:
2659           return "pxor\t%0, %0";
2660         default:
2661           gcc_unreachable ();
2662         }
2663     case 6:
2664     case 7:
2665     case 8:
2666       switch (get_attr_mode (insn))
2667         {
2668         case MODE_V4SF:
2669           return "movaps\t{%1, %0|%0, %1}";
2670         case MODE_V2DF:
2671           return "movapd\t{%1, %0|%0, %1}";
2672         case MODE_TI:
2673           return "movdqa\t{%1, %0|%0, %1}";
2674         case MODE_DI:
2675           return "movq\t{%1, %0|%0, %1}";
2676         case MODE_DF:
2677           return "movsd\t{%1, %0|%0, %1}";
2678         case MODE_V1DF:
2679           return "movlpd\t{%1, %0|%0, %1}";
2680         case MODE_V2SF:
2681           return "movlps\t{%1, %0|%0, %1}";
2682         default:
2683           gcc_unreachable ();
2684         }
2685
2686     case 9:
2687     case 10:
2688       return "movd\t{%1, %0|%0, %1}";
2689
2690     default:
2691       gcc_unreachable();
2692     }
2693 }
2694   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2695    (set (attr "mode")
2696         (cond [(eq_attr "alternative" "0,1,2")
2697                  (const_string "DF")
2698                (eq_attr "alternative" "3,4,9,10")
2699                  (const_string "DI")
2700
2701                /* For SSE1, we have many fewer alternatives.  */
2702                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2703                  (cond [(eq_attr "alternative" "5,6")
2704                           (const_string "V4SF")
2705                        ]
2706                    (const_string "V2SF"))
2707
2708                /* xorps is one byte shorter.  */
2709                (eq_attr "alternative" "5")
2710                  (cond [(ne (symbol_ref "optimize_size")
2711                             (const_int 0))
2712                           (const_string "V4SF")
2713                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2714                             (const_int 0))
2715                           (const_string "TI")
2716                        ]
2717                        (const_string "V2DF"))
2718
2719                /* For architectures resolving dependencies on
2720                   whole SSE registers use APD move to break dependency
2721                   chains, otherwise use short move to avoid extra work.
2722
2723                   movaps encodes one byte shorter.  */
2724                (eq_attr "alternative" "6")
2725                  (cond
2726                    [(ne (symbol_ref "optimize_size")
2727                         (const_int 0))
2728                       (const_string "V4SF")
2729                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2730                         (const_int 0))
2731                       (const_string "V2DF")
2732                    ]
2733                    (const_string "DF"))
2734                /* For architectures resolving dependencies on register
2735                   parts we may avoid extra work to zero out upper part
2736                   of register.  */
2737                (eq_attr "alternative" "7")
2738                  (if_then_else
2739                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2740                        (const_int 0))
2741                    (const_string "V1DF")
2742                    (const_string "DF"))
2743               ]
2744               (const_string "DF")))])
2745
2746 (define_insn "*movdf_integer"
2747   [(set (match_operand:DF 0 "nonimmediate_operand"
2748                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
2749         (match_operand:DF 1 "general_operand"
2750                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
2751   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2752    && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2753    && (reload_in_progress || reload_completed
2754        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2755        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2756            && standard_80387_constant_p (operands[1]))
2757        || GET_CODE (operands[1]) != CONST_DOUBLE
2758        || memory_operand (operands[0], DFmode))"
2759 {
2760   switch (which_alternative)
2761     {
2762     case 0:
2763       return output_387_reg_move (insn, operands);
2764
2765     case 1:
2766       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2767         return "fstp%z0\t%y0";
2768       else
2769         return "fst%z0\t%y0";
2770
2771     case 2:
2772       return standard_80387_constant_opcode (operands[1]);
2773
2774     case 3:
2775     case 4:
2776       return "#";
2777
2778     case 5:
2779       switch (get_attr_mode (insn))
2780         {
2781         case MODE_V4SF:
2782           return "xorps\t%0, %0";
2783         case MODE_V2DF:
2784           return "xorpd\t%0, %0";
2785         case MODE_TI:
2786           return "pxor\t%0, %0";
2787         default:
2788           gcc_unreachable ();
2789         }
2790     case 6:
2791     case 7:
2792     case 8:
2793       switch (get_attr_mode (insn))
2794         {
2795         case MODE_V4SF:
2796           return "movaps\t{%1, %0|%0, %1}";
2797         case MODE_V2DF:
2798           return "movapd\t{%1, %0|%0, %1}";
2799         case MODE_TI:
2800           return "movdqa\t{%1, %0|%0, %1}";
2801         case MODE_DI:
2802           return "movq\t{%1, %0|%0, %1}";
2803         case MODE_DF:
2804           return "movsd\t{%1, %0|%0, %1}";
2805         case MODE_V1DF:
2806           return "movlpd\t{%1, %0|%0, %1}";
2807         case MODE_V2SF:
2808           return "movlps\t{%1, %0|%0, %1}";
2809         default:
2810           gcc_unreachable ();
2811         }
2812
2813     default:
2814       gcc_unreachable();
2815     }
2816 }
2817   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2818    (set (attr "mode")
2819         (cond [(eq_attr "alternative" "0,1,2")
2820                  (const_string "DF")
2821                (eq_attr "alternative" "3,4")
2822                  (const_string "SI")
2823
2824                /* For SSE1, we have many fewer alternatives.  */
2825                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2826                  (cond [(eq_attr "alternative" "5,6")
2827                           (const_string "V4SF")
2828                        ]
2829                    (const_string "V2SF"))
2830
2831                /* xorps is one byte shorter.  */
2832                (eq_attr "alternative" "5")
2833                  (cond [(ne (symbol_ref "optimize_size")
2834                             (const_int 0))
2835                           (const_string "V4SF")
2836                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2837                             (const_int 0))
2838                           (const_string "TI")
2839                        ]
2840                        (const_string "V2DF"))
2841
2842                /* For architectures resolving dependencies on
2843                   whole SSE registers use APD move to break dependency
2844                   chains, otherwise use short move to avoid extra work.
2845
2846                   movaps encodes one byte shorter.  */
2847                (eq_attr "alternative" "6")
2848                  (cond
2849                    [(ne (symbol_ref "optimize_size")
2850                         (const_int 0))
2851                       (const_string "V4SF")
2852                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2853                         (const_int 0))
2854                       (const_string "V2DF")
2855                    ]
2856                    (const_string "DF"))
2857                /* For architectures resolving dependencies on register
2858                   parts we may avoid extra work to zero out upper part
2859                   of register.  */
2860                (eq_attr "alternative" "7")
2861                  (if_then_else
2862                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2863                        (const_int 0))
2864                    (const_string "V1DF")
2865                    (const_string "DF"))
2866               ]
2867               (const_string "DF")))])
2868
2869 (define_split
2870   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2871         (match_operand:DF 1 "general_operand" ""))]
2872   "reload_completed
2873    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2874    && ! (ANY_FP_REG_P (operands[0]) ||
2875          (GET_CODE (operands[0]) == SUBREG
2876           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2877    && ! (ANY_FP_REG_P (operands[1]) ||
2878          (GET_CODE (operands[1]) == SUBREG
2879           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2880   [(const_int 0)]
2881   "ix86_split_long_move (operands); DONE;")
2882
2883 (define_insn "*swapdf"
2884   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2885         (match_operand:DF 1 "fp_register_operand" "+f"))
2886    (set (match_dup 1)
2887         (match_dup 0))]
2888   "reload_completed || TARGET_80387"
2889 {
2890   if (STACK_TOP_P (operands[0]))
2891     return "fxch\t%1";
2892   else
2893     return "fxch\t%0";
2894 }
2895   [(set_attr "type" "fxch")
2896    (set_attr "mode" "DF")])
2897
2898 (define_expand "movxf"
2899   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2900         (match_operand:XF 1 "general_operand" ""))]
2901   ""
2902   "ix86_expand_move (XFmode, operands); DONE;")
2903
2904 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2905 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2906 ;; Pushing using integer instructions is longer except for constants
2907 ;; and direct memory references.
2908 ;; (assuming that any given constant is pushed only once, but this ought to be
2909 ;;  handled elsewhere).
2910
2911 (define_insn "*pushxf_nointeger"
2912   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2913         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2914   "optimize_size"
2915 {
2916   /* This insn should be already split before reg-stack.  */
2917   gcc_unreachable ();
2918 }
2919   [(set_attr "type" "multi")
2920    (set_attr "unit" "i387,*,*")
2921    (set_attr "mode" "XF,SI,SI")])
2922
2923 (define_insn "*pushxf_integer"
2924   [(set (match_operand:XF 0 "push_operand" "=<,<")
2925         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2926   "!optimize_size"
2927 {
2928   /* This insn should be already split before reg-stack.  */
2929   gcc_unreachable ();
2930 }
2931   [(set_attr "type" "multi")
2932    (set_attr "unit" "i387,*")
2933    (set_attr "mode" "XF,SI")])
2934
2935 (define_split
2936   [(set (match_operand 0 "push_operand" "")
2937         (match_operand 1 "general_operand" ""))]
2938   "reload_completed
2939    && (GET_MODE (operands[0]) == XFmode
2940        || GET_MODE (operands[0]) == DFmode)
2941    && !ANY_FP_REG_P (operands[1])"
2942   [(const_int 0)]
2943   "ix86_split_long_move (operands); DONE;")
2944
2945 (define_split
2946   [(set (match_operand:XF 0 "push_operand" "")
2947         (match_operand:XF 1 "any_fp_register_operand" ""))]
2948   "!TARGET_64BIT"
2949   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2950    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2951   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2952
2953 (define_split
2954   [(set (match_operand:XF 0 "push_operand" "")
2955         (match_operand:XF 1 "any_fp_register_operand" ""))]
2956   "TARGET_64BIT"
2957   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2958    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2959   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2960
2961 ;; Do not use integer registers when optimizing for size
2962 (define_insn "*movxf_nointeger"
2963   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2964         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2965   "optimize_size
2966    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2967    && (reload_in_progress || reload_completed
2968        || (optimize_size && standard_80387_constant_p (operands[1]))
2969        || GET_CODE (operands[1]) != CONST_DOUBLE
2970        || memory_operand (operands[0], XFmode))"
2971 {
2972   switch (which_alternative)
2973     {
2974     case 0:
2975       return output_387_reg_move (insn, operands);
2976
2977     case 1:
2978       /* There is no non-popping store to memory for XFmode.  So if
2979          we need one, follow the store with a load.  */
2980       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2981         return "fstp%z0\t%y0\;fld%z0\t%y0";
2982       else
2983         return "fstp%z0\t%y0";
2984
2985     case 2:
2986       return standard_80387_constant_opcode (operands[1]);
2987
2988     case 3: case 4:
2989       return "#";
2990     default:
2991       gcc_unreachable ();
2992     }
2993 }
2994   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2995    (set_attr "mode" "XF,XF,XF,SI,SI")])
2996
2997 (define_insn "*movxf_integer"
2998   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2999         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3000   "!optimize_size
3001    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3002    && (reload_in_progress || reload_completed
3003        || (optimize_size && standard_80387_constant_p (operands[1]))
3004        || GET_CODE (operands[1]) != CONST_DOUBLE
3005        || memory_operand (operands[0], XFmode))"
3006 {
3007   switch (which_alternative)
3008     {
3009     case 0:
3010       return output_387_reg_move (insn, operands);
3011
3012     case 1:
3013       /* There is no non-popping store to memory for XFmode.  So if
3014          we need one, follow the store with a load.  */
3015       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3016         return "fstp%z0\t%y0\;fld%z0\t%y0";
3017       else
3018         return "fstp%z0\t%y0";
3019
3020     case 2:
3021       return standard_80387_constant_opcode (operands[1]);
3022
3023     case 3: case 4:
3024       return "#";
3025
3026     default:
3027       gcc_unreachable ();
3028     }
3029 }
3030   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3031    (set_attr "mode" "XF,XF,XF,SI,SI")])
3032
3033 (define_split
3034   [(set (match_operand 0 "nonimmediate_operand" "")
3035         (match_operand 1 "general_operand" ""))]
3036   "reload_completed
3037    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3038    && GET_MODE (operands[0]) == XFmode
3039    && ! (ANY_FP_REG_P (operands[0]) ||
3040          (GET_CODE (operands[0]) == SUBREG
3041           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3042    && ! (ANY_FP_REG_P (operands[1]) ||
3043          (GET_CODE (operands[1]) == SUBREG
3044           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3045   [(const_int 0)]
3046   "ix86_split_long_move (operands); DONE;")
3047
3048 (define_split
3049   [(set (match_operand 0 "register_operand" "")
3050         (match_operand 1 "memory_operand" ""))]
3051   "reload_completed
3052    && MEM_P (operands[1])
3053    && (GET_MODE (operands[0]) == XFmode
3054        || GET_MODE (operands[0]) == SFmode
3055        || GET_MODE (operands[0]) == DFmode)
3056    && constant_pool_reference_p (operands[1])"
3057   [(set (match_dup 0) (match_dup 1))]
3058 {
3059   rtx c = avoid_constant_pool_reference (operands[1]);
3060   rtx r = operands[0];
3061
3062   if (GET_CODE (r) == SUBREG)
3063     r = SUBREG_REG (r);
3064
3065   if (SSE_REG_P (r))
3066     {
3067       if (!standard_sse_constant_p (c))
3068         FAIL;
3069     }
3070   else if (FP_REG_P (r))
3071     {
3072       if (!standard_80387_constant_p (c))
3073         FAIL;
3074     }
3075   else if (MMX_REG_P (r))
3076     FAIL;
3077
3078   operands[1] = c;
3079 })
3080
3081 (define_split
3082   [(set (match_operand 0 "register_operand" "")
3083         (float_extend (match_operand 1 "memory_operand" "")))]
3084   "reload_completed
3085    && MEM_P (operands[1])
3086    && (GET_MODE (operands[0]) == XFmode
3087        || GET_MODE (operands[0]) == SFmode
3088        || GET_MODE (operands[0]) == DFmode)
3089    && constant_pool_reference_p (operands[1])"
3090   [(set (match_dup 0) (match_dup 1))]
3091 {
3092   rtx c = avoid_constant_pool_reference (SET_SRC (PATTERN (curr_insn)));
3093   rtx r = operands[0];
3094
3095   if (GET_CODE (r) == SUBREG)
3096     r = SUBREG_REG (r);
3097
3098   if (SSE_REG_P (r))
3099     {
3100       if (!standard_sse_constant_p (c))
3101         FAIL;
3102     }
3103   else if (FP_REG_P (r))
3104     {
3105       if (!standard_80387_constant_p (c))
3106         FAIL;
3107     }
3108   else if (MMX_REG_P (r))
3109     FAIL;
3110
3111   operands[1] = c;
3112 })
3113
3114 (define_insn "swapxf"
3115   [(set (match_operand:XF 0 "register_operand" "+f")
3116         (match_operand:XF 1 "register_operand" "+f"))
3117    (set (match_dup 1)
3118         (match_dup 0))]
3119   "TARGET_80387"
3120 {
3121   if (STACK_TOP_P (operands[0]))
3122     return "fxch\t%1";
3123   else
3124     return "fxch\t%0";
3125 }
3126   [(set_attr "type" "fxch")
3127    (set_attr "mode" "XF")])
3128
3129 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3130 (define_split
3131   [(set (match_operand:X87MODEF 0 "register_operand" "")
3132         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3133   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3134    && (standard_80387_constant_p (operands[1]) == 8
3135        || standard_80387_constant_p (operands[1]) == 9)"
3136   [(set (match_dup 0)(match_dup 1))
3137    (set (match_dup 0)
3138         (neg:X87MODEF (match_dup 0)))]
3139 {
3140   REAL_VALUE_TYPE r;
3141
3142   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3143   if (real_isnegzero (&r))
3144     operands[1] = CONST0_RTX (<MODE>mode);
3145   else
3146     operands[1] = CONST1_RTX (<MODE>mode);
3147 })
3148
3149 (define_expand "movtf"
3150   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3151         (match_operand:TF 1 "nonimmediate_operand" ""))]
3152   "TARGET_64BIT"
3153 {
3154   ix86_expand_move (TFmode, operands);
3155   DONE;
3156 })
3157
3158 (define_insn "*movtf_internal"
3159   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3160         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3161   "TARGET_64BIT
3162    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3163 {
3164   switch (which_alternative)
3165     {
3166     case 0:
3167     case 1:
3168       return "#";
3169     case 2:
3170       if (get_attr_mode (insn) == MODE_V4SF)
3171         return "xorps\t%0, %0";
3172       else
3173         return "pxor\t%0, %0";
3174     case 3:
3175     case 4:
3176       if (get_attr_mode (insn) == MODE_V4SF)
3177         return "movaps\t{%1, %0|%0, %1}";
3178       else
3179         return "movdqa\t{%1, %0|%0, %1}";
3180     default:
3181       gcc_unreachable ();
3182     }
3183 }
3184   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3185    (set (attr "mode")
3186         (cond [(eq_attr "alternative" "2,3")
3187                  (if_then_else
3188                    (ne (symbol_ref "optimize_size")
3189                        (const_int 0))
3190                    (const_string "V4SF")
3191                    (const_string "TI"))
3192                (eq_attr "alternative" "4")
3193                  (if_then_else
3194                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3195                             (const_int 0))
3196                         (ne (symbol_ref "optimize_size")
3197                             (const_int 0)))
3198                    (const_string "V4SF")
3199                    (const_string "TI"))]
3200                (const_string "DI")))])
3201
3202 (define_split
3203   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3204         (match_operand:TF 1 "general_operand" ""))]
3205   "reload_completed && !SSE_REG_P (operands[0])
3206    && !SSE_REG_P (operands[1])"
3207   [(const_int 0)]
3208   "ix86_split_long_move (operands); DONE;")
3209 \f
3210 ;; Zero extension instructions
3211
3212 (define_expand "zero_extendhisi2"
3213   [(set (match_operand:SI 0 "register_operand" "")
3214      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3215   ""
3216 {
3217   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3218     {
3219       operands[1] = force_reg (HImode, operands[1]);
3220       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3221       DONE;
3222     }
3223 })
3224
3225 (define_insn "zero_extendhisi2_and"
3226   [(set (match_operand:SI 0 "register_operand" "=r")
3227      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3228    (clobber (reg:CC FLAGS_REG))]
3229   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3230   "#"
3231   [(set_attr "type" "alu1")
3232    (set_attr "mode" "SI")])
3233
3234 (define_split
3235   [(set (match_operand:SI 0 "register_operand" "")
3236         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3237    (clobber (reg:CC FLAGS_REG))]
3238   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3239   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3240               (clobber (reg:CC FLAGS_REG))])]
3241   "")
3242
3243 (define_insn "*zero_extendhisi2_movzwl"
3244   [(set (match_operand:SI 0 "register_operand" "=r")
3245      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3246   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3247   "movz{wl|x}\t{%1, %0|%0, %1}"
3248   [(set_attr "type" "imovx")
3249    (set_attr "mode" "SI")])
3250
3251 (define_expand "zero_extendqihi2"
3252   [(parallel
3253     [(set (match_operand:HI 0 "register_operand" "")
3254        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3255      (clobber (reg:CC FLAGS_REG))])]
3256   ""
3257   "")
3258
3259 (define_insn "*zero_extendqihi2_and"
3260   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3261      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3262    (clobber (reg:CC FLAGS_REG))]
3263   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3264   "#"
3265   [(set_attr "type" "alu1")
3266    (set_attr "mode" "HI")])
3267
3268 (define_insn "*zero_extendqihi2_movzbw_and"
3269   [(set (match_operand:HI 0 "register_operand" "=r,r")
3270      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3271    (clobber (reg:CC FLAGS_REG))]
3272   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3273   "#"
3274   [(set_attr "type" "imovx,alu1")
3275    (set_attr "mode" "HI")])
3276
3277 ; zero extend to SImode here to avoid partial register stalls
3278 (define_insn "*zero_extendqihi2_movzbl"
3279   [(set (match_operand:HI 0 "register_operand" "=r")
3280      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3281   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3282   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3283   [(set_attr "type" "imovx")
3284    (set_attr "mode" "SI")])
3285
3286 ;; For the movzbw case strip only the clobber
3287 (define_split
3288   [(set (match_operand:HI 0 "register_operand" "")
3289         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3290    (clobber (reg:CC FLAGS_REG))]
3291   "reload_completed
3292    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3293    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3294   [(set (match_operand:HI 0 "register_operand" "")
3295         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3296
3297 ;; When source and destination does not overlap, clear destination
3298 ;; first and then do the movb
3299 (define_split
3300   [(set (match_operand:HI 0 "register_operand" "")
3301         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3302    (clobber (reg:CC FLAGS_REG))]
3303   "reload_completed
3304    && ANY_QI_REG_P (operands[0])
3305    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3306    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3307   [(set (match_dup 0) (const_int 0))
3308    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3309   "operands[2] = gen_lowpart (QImode, operands[0]);")
3310
3311 ;; Rest is handled by single and.
3312 (define_split
3313   [(set (match_operand:HI 0 "register_operand" "")
3314         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3315    (clobber (reg:CC FLAGS_REG))]
3316   "reload_completed
3317    && true_regnum (operands[0]) == true_regnum (operands[1])"
3318   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3319               (clobber (reg:CC FLAGS_REG))])]
3320   "")
3321
3322 (define_expand "zero_extendqisi2"
3323   [(parallel
3324     [(set (match_operand:SI 0 "register_operand" "")
3325        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3326      (clobber (reg:CC FLAGS_REG))])]
3327   ""
3328   "")
3329
3330 (define_insn "*zero_extendqisi2_and"
3331   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3332      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3333    (clobber (reg:CC FLAGS_REG))]
3334   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3335   "#"
3336   [(set_attr "type" "alu1")
3337    (set_attr "mode" "SI")])
3338
3339 (define_insn "*zero_extendqisi2_movzbw_and"
3340   [(set (match_operand:SI 0 "register_operand" "=r,r")
3341      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3342    (clobber (reg:CC FLAGS_REG))]
3343   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3344   "#"
3345   [(set_attr "type" "imovx,alu1")
3346    (set_attr "mode" "SI")])
3347
3348 (define_insn "*zero_extendqisi2_movzbw"
3349   [(set (match_operand:SI 0 "register_operand" "=r")
3350      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3351   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3352   "movz{bl|x}\t{%1, %0|%0, %1}"
3353   [(set_attr "type" "imovx")
3354    (set_attr "mode" "SI")])
3355
3356 ;; For the movzbl case strip only the clobber
3357 (define_split
3358   [(set (match_operand:SI 0 "register_operand" "")
3359         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3360    (clobber (reg:CC FLAGS_REG))]
3361   "reload_completed
3362    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3363    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3364   [(set (match_dup 0)
3365         (zero_extend:SI (match_dup 1)))])
3366
3367 ;; When source and destination does not overlap, clear destination
3368 ;; first and then do the movb
3369 (define_split
3370   [(set (match_operand:SI 0 "register_operand" "")
3371         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3372    (clobber (reg:CC FLAGS_REG))]
3373   "reload_completed
3374    && ANY_QI_REG_P (operands[0])
3375    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3376    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3377    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3378   [(set (match_dup 0) (const_int 0))
3379    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3380   "operands[2] = gen_lowpart (QImode, operands[0]);")
3381
3382 ;; Rest is handled by single and.
3383 (define_split
3384   [(set (match_operand:SI 0 "register_operand" "")
3385         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3386    (clobber (reg:CC FLAGS_REG))]
3387   "reload_completed
3388    && true_regnum (operands[0]) == true_regnum (operands[1])"
3389   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3390               (clobber (reg:CC FLAGS_REG))])]
3391   "")
3392
3393 ;; %%% Kill me once multi-word ops are sane.
3394 (define_expand "zero_extendsidi2"
3395   [(set (match_operand:DI 0 "register_operand" "=r")
3396      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3397   ""
3398 {
3399   if (!TARGET_64BIT)
3400     {
3401       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3402       DONE;
3403     }
3404 })
3405
3406 (define_insn "zero_extendsidi2_32"
3407   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,*y,?*Yi,*Y2")
3408         (zero_extend:DI
3409          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m ,r   ,m")))
3410    (clobber (reg:CC FLAGS_REG))]
3411   "!TARGET_64BIT"
3412   "@
3413    #
3414    #
3415    #
3416    movd\t{%1, %0|%0, %1}
3417    movd\t{%1, %0|%0, %1}
3418    movd\t{%1, %0|%0, %1}
3419    movd\t{%1, %0|%0, %1}"
3420   [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3421    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3422
3423 (define_insn "zero_extendsidi2_rex64"
3424   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,*y,?*Yi,*Y2")
3425      (zero_extend:DI
3426        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m ,r   ,m")))]
3427   "TARGET_64BIT"
3428   "@
3429    mov\t{%k1, %k0|%k0, %k1}
3430    #
3431    movd\t{%1, %0|%0, %1}
3432    movd\t{%1, %0|%0, %1}
3433    movd\t{%1, %0|%0, %1}
3434    movd\t{%1, %0|%0, %1}"
3435   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3436    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3437
3438 (define_split
3439   [(set (match_operand:DI 0 "memory_operand" "")
3440      (zero_extend:DI (match_dup 0)))]
3441   "TARGET_64BIT"
3442   [(set (match_dup 4) (const_int 0))]
3443   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3444
3445 (define_split
3446   [(set (match_operand:DI 0 "register_operand" "")
3447         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3448    (clobber (reg:CC FLAGS_REG))]
3449   "!TARGET_64BIT && reload_completed
3450    && true_regnum (operands[0]) == true_regnum (operands[1])"
3451   [(set (match_dup 4) (const_int 0))]
3452   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3453
3454 (define_split
3455   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3456         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3457    (clobber (reg:CC FLAGS_REG))]
3458   "!TARGET_64BIT && reload_completed
3459    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3460   [(set (match_dup 3) (match_dup 1))
3461    (set (match_dup 4) (const_int 0))]
3462   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3463
3464 (define_insn "zero_extendhidi2"
3465   [(set (match_operand:DI 0 "register_operand" "=r")
3466      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3467   "TARGET_64BIT"
3468   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3469   [(set_attr "type" "imovx")
3470    (set_attr "mode" "DI")])
3471
3472 (define_insn "zero_extendqidi2"
3473   [(set (match_operand:DI 0 "register_operand" "=r")
3474      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3475   "TARGET_64BIT"
3476   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3477   [(set_attr "type" "imovx")
3478    (set_attr "mode" "DI")])
3479 \f
3480 ;; Sign extension instructions
3481
3482 (define_expand "extendsidi2"
3483   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3484                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3485               (clobber (reg:CC FLAGS_REG))
3486               (clobber (match_scratch:SI 2 ""))])]
3487   ""
3488 {
3489   if (TARGET_64BIT)
3490     {
3491       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3492       DONE;
3493     }
3494 })
3495
3496 (define_insn "*extendsidi2_1"
3497   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3498         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3499    (clobber (reg:CC FLAGS_REG))
3500    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3501   "!TARGET_64BIT"
3502   "#")
3503
3504 (define_insn "extendsidi2_rex64"
3505   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3506         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3507   "TARGET_64BIT"
3508   "@
3509    {cltq|cdqe}
3510    movs{lq|x}\t{%1,%0|%0, %1}"
3511   [(set_attr "type" "imovx")
3512    (set_attr "mode" "DI")
3513    (set_attr "prefix_0f" "0")
3514    (set_attr "modrm" "0,1")])
3515
3516 (define_insn "extendhidi2"
3517   [(set (match_operand:DI 0 "register_operand" "=r")
3518         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3519   "TARGET_64BIT"
3520   "movs{wq|x}\t{%1,%0|%0, %1}"
3521   [(set_attr "type" "imovx")
3522    (set_attr "mode" "DI")])
3523
3524 (define_insn "extendqidi2"
3525   [(set (match_operand:DI 0 "register_operand" "=r")
3526         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3527   "TARGET_64BIT"
3528   "movs{bq|x}\t{%1,%0|%0, %1}"
3529    [(set_attr "type" "imovx")
3530     (set_attr "mode" "DI")])
3531
3532 ;; Extend to memory case when source register does die.
3533 (define_split
3534   [(set (match_operand:DI 0 "memory_operand" "")
3535         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3536    (clobber (reg:CC FLAGS_REG))
3537    (clobber (match_operand:SI 2 "register_operand" ""))]
3538   "(reload_completed
3539     && dead_or_set_p (insn, operands[1])
3540     && !reg_mentioned_p (operands[1], operands[0]))"
3541   [(set (match_dup 3) (match_dup 1))
3542    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3543               (clobber (reg:CC FLAGS_REG))])
3544    (set (match_dup 4) (match_dup 1))]
3545   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3546
3547 ;; Extend to memory case when source register does not die.
3548 (define_split
3549   [(set (match_operand:DI 0 "memory_operand" "")
3550         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3551    (clobber (reg:CC FLAGS_REG))
3552    (clobber (match_operand:SI 2 "register_operand" ""))]
3553   "reload_completed"
3554   [(const_int 0)]
3555 {
3556   split_di (&operands[0], 1, &operands[3], &operands[4]);
3557
3558   emit_move_insn (operands[3], operands[1]);
3559
3560   /* Generate a cltd if possible and doing so it profitable.  */
3561   if (true_regnum (operands[1]) == 0
3562       && true_regnum (operands[2]) == 1
3563       && (optimize_size || TARGET_USE_CLTD))
3564     {
3565       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3566     }
3567   else
3568     {
3569       emit_move_insn (operands[2], operands[1]);
3570       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3571     }
3572   emit_move_insn (operands[4], operands[2]);
3573   DONE;
3574 })
3575
3576 ;; Extend to register case.  Optimize case where source and destination
3577 ;; registers match and cases where we can use cltd.
3578 (define_split
3579   [(set (match_operand:DI 0 "register_operand" "")
3580         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3581    (clobber (reg:CC FLAGS_REG))
3582    (clobber (match_scratch:SI 2 ""))]
3583   "reload_completed"
3584   [(const_int 0)]
3585 {
3586   split_di (&operands[0], 1, &operands[3], &operands[4]);
3587
3588   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3589     emit_move_insn (operands[3], operands[1]);
3590
3591   /* Generate a cltd if possible and doing so it profitable.  */
3592   if (true_regnum (operands[3]) == 0
3593       && (optimize_size || TARGET_USE_CLTD))
3594     {
3595       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3596       DONE;
3597     }
3598
3599   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3600     emit_move_insn (operands[4], operands[1]);
3601
3602   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3603   DONE;
3604 })
3605
3606 (define_insn "extendhisi2"
3607   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3608         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3609   ""
3610 {
3611   switch (get_attr_prefix_0f (insn))
3612     {
3613     case 0:
3614       return "{cwtl|cwde}";
3615     default:
3616       return "movs{wl|x}\t{%1,%0|%0, %1}";
3617     }
3618 }
3619   [(set_attr "type" "imovx")
3620    (set_attr "mode" "SI")
3621    (set (attr "prefix_0f")
3622      ;; movsx is short decodable while cwtl is vector decoded.
3623      (if_then_else (and (eq_attr "cpu" "!k6")
3624                         (eq_attr "alternative" "0"))
3625         (const_string "0")
3626         (const_string "1")))
3627    (set (attr "modrm")
3628      (if_then_else (eq_attr "prefix_0f" "0")
3629         (const_string "0")
3630         (const_string "1")))])
3631
3632 (define_insn "*extendhisi2_zext"
3633   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3634         (zero_extend:DI
3635           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3636   "TARGET_64BIT"
3637 {
3638   switch (get_attr_prefix_0f (insn))
3639     {
3640     case 0:
3641       return "{cwtl|cwde}";
3642     default:
3643       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3644     }
3645 }
3646   [(set_attr "type" "imovx")
3647    (set_attr "mode" "SI")
3648    (set (attr "prefix_0f")
3649      ;; movsx is short decodable while cwtl is vector decoded.
3650      (if_then_else (and (eq_attr "cpu" "!k6")
3651                         (eq_attr "alternative" "0"))
3652         (const_string "0")
3653         (const_string "1")))
3654    (set (attr "modrm")
3655      (if_then_else (eq_attr "prefix_0f" "0")
3656         (const_string "0")
3657         (const_string "1")))])
3658
3659 (define_insn "extendqihi2"
3660   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3661         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3662   ""
3663 {
3664   switch (get_attr_prefix_0f (insn))
3665     {
3666     case 0:
3667       return "{cbtw|cbw}";
3668     default:
3669       return "movs{bw|x}\t{%1,%0|%0, %1}";
3670     }
3671 }
3672   [(set_attr "type" "imovx")
3673    (set_attr "mode" "HI")
3674    (set (attr "prefix_0f")
3675      ;; movsx is short decodable while cwtl is vector decoded.
3676      (if_then_else (and (eq_attr "cpu" "!k6")
3677                         (eq_attr "alternative" "0"))
3678         (const_string "0")
3679         (const_string "1")))
3680    (set (attr "modrm")
3681      (if_then_else (eq_attr "prefix_0f" "0")
3682         (const_string "0")
3683         (const_string "1")))])
3684
3685 (define_insn "extendqisi2"
3686   [(set (match_operand:SI 0 "register_operand" "=r")
3687         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3688   ""
3689   "movs{bl|x}\t{%1,%0|%0, %1}"
3690    [(set_attr "type" "imovx")
3691     (set_attr "mode" "SI")])
3692
3693 (define_insn "*extendqisi2_zext"
3694   [(set (match_operand:DI 0 "register_operand" "=r")
3695         (zero_extend:DI
3696           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3697   "TARGET_64BIT"
3698   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3699    [(set_attr "type" "imovx")
3700     (set_attr "mode" "SI")])
3701 \f
3702 ;; Conversions between float and double.
3703
3704 ;; These are all no-ops in the model used for the 80387.  So just
3705 ;; emit moves.
3706
3707 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3708 (define_insn "*dummy_extendsfdf2"
3709   [(set (match_operand:DF 0 "push_operand" "=<")
3710         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3711   "0"
3712   "#")
3713
3714 (define_split
3715   [(set (match_operand:DF 0 "push_operand" "")
3716         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3717   "!TARGET_64BIT"
3718   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3719    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3720
3721 (define_split
3722   [(set (match_operand:DF 0 "push_operand" "")
3723         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3724   "TARGET_64BIT"
3725   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3726    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3727
3728 (define_insn "*dummy_extendsfxf2"
3729   [(set (match_operand:XF 0 "push_operand" "=<")
3730         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3731   "0"
3732   "#")
3733
3734 (define_split
3735   [(set (match_operand:XF 0 "push_operand" "")
3736         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3737   ""
3738   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3739    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3740   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3741
3742 (define_split
3743   [(set (match_operand:XF 0 "push_operand" "")
3744         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3745   "TARGET_64BIT"
3746   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3747    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3748   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3749
3750 (define_split
3751   [(set (match_operand:XF 0 "push_operand" "")
3752         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3753   ""
3754   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3755    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3756   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3757
3758 (define_split
3759   [(set (match_operand:XF 0 "push_operand" "")
3760         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3761   "TARGET_64BIT"
3762   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3763    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3764   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3765
3766 (define_expand "extendsfdf2"
3767   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3768         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3769   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3770 {
3771   /* ??? Needed for compress_float_constant since all fp constants
3772      are LEGITIMATE_CONSTANT_P.  */
3773   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3774     {
3775       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3776           && standard_80387_constant_p (operands[1]) > 0)
3777         {
3778           operands[1] = simplify_const_unary_operation
3779             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3780           emit_move_insn_1 (operands[0], operands[1]);
3781           DONE;
3782         }
3783       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3784     }
3785 })
3786
3787 (define_insn "*extendsfdf2_mixed"
3788   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3789         (float_extend:DF
3790           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3791   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3792 {
3793   switch (which_alternative)
3794     {
3795     case 0:
3796       return output_387_reg_move (insn, operands);
3797
3798     case 1:
3799       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3800         return "fstp%z0\t%y0";
3801       else
3802         return "fst%z0\t%y0";
3803
3804     case 2:
3805       return "cvtss2sd\t{%1, %0|%0, %1}";
3806
3807     default:
3808       gcc_unreachable ();
3809     }
3810 }
3811   [(set_attr "type" "fmov,fmov,ssecvt")
3812    (set_attr "mode" "SF,XF,DF")])
3813
3814 (define_insn "*extendsfdf2_sse"
3815   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3816         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3817   "TARGET_SSE2 && TARGET_SSE_MATH"
3818   "cvtss2sd\t{%1, %0|%0, %1}"
3819   [(set_attr "type" "ssecvt")
3820    (set_attr "mode" "DF")])
3821
3822 (define_insn "*extendsfdf2_i387"
3823   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3824         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3825   "TARGET_80387"
3826 {
3827   switch (which_alternative)
3828     {
3829     case 0:
3830       return output_387_reg_move (insn, operands);
3831
3832     case 1:
3833       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3834         return "fstp%z0\t%y0";
3835       else
3836         return "fst%z0\t%y0";
3837
3838     default:
3839       gcc_unreachable ();
3840     }
3841 }
3842   [(set_attr "type" "fmov")
3843    (set_attr "mode" "SF,XF")])
3844
3845 (define_expand "extendsfxf2"
3846   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3847         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3848   "TARGET_80387"
3849 {
3850   /* ??? Needed for compress_float_constant since all fp constants
3851      are LEGITIMATE_CONSTANT_P.  */
3852   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3853     {
3854       if (standard_80387_constant_p (operands[1]) > 0)
3855         {
3856           operands[1] = simplify_const_unary_operation
3857             (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3858           emit_move_insn_1 (operands[0], operands[1]);
3859           DONE;
3860         }
3861       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3862     }
3863 })
3864
3865 (define_insn "*extendsfxf2_i387"
3866   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3867         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3868   "TARGET_80387"
3869 {
3870   switch (which_alternative)
3871     {
3872     case 0:
3873       return output_387_reg_move (insn, operands);
3874
3875     case 1:
3876       /* There is no non-popping store to memory for XFmode.  So if
3877          we need one, follow the store with a load.  */
3878       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3879         return "fstp%z0\t%y0";
3880       else
3881         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3882
3883     default:
3884       gcc_unreachable ();
3885     }
3886 }
3887   [(set_attr "type" "fmov")
3888    (set_attr "mode" "SF,XF")])
3889
3890 (define_expand "extenddfxf2"
3891   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3892         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3893   "TARGET_80387"
3894 {
3895   /* ??? Needed for compress_float_constant since all fp constants
3896      are LEGITIMATE_CONSTANT_P.  */
3897   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3898     {
3899       if (standard_80387_constant_p (operands[1]) > 0)
3900         {
3901           operands[1] = simplify_const_unary_operation
3902             (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3903           emit_move_insn_1 (operands[0], operands[1]);
3904           DONE;
3905         }
3906       operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3907     }
3908 })
3909
3910 (define_insn "*extenddfxf2_i387"
3911   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3912         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3913   "TARGET_80387"
3914 {
3915   switch (which_alternative)
3916     {
3917     case 0:
3918       return output_387_reg_move (insn, operands);
3919
3920     case 1:
3921       /* There is no non-popping store to memory for XFmode.  So if
3922          we need one, follow the store with a load.  */
3923       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3924         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3925       else
3926         return "fstp%z0\t%y0";
3927
3928     default:
3929       gcc_unreachable ();
3930     }
3931 }
3932   [(set_attr "type" "fmov")
3933    (set_attr "mode" "DF,XF")])
3934
3935 ;; %%% This seems bad bad news.
3936 ;; This cannot output into an f-reg because there is no way to be sure
3937 ;; of truncating in that case.  Otherwise this is just like a simple move
3938 ;; insn.  So we pretend we can output to a reg in order to get better
3939 ;; register preferencing, but we really use a stack slot.
3940
3941 ;; Conversion from DFmode to SFmode.
3942
3943 (define_expand "truncdfsf2"
3944   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3945         (float_truncate:SF
3946           (match_operand:DF 1 "nonimmediate_operand" "")))]
3947   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3948 {
3949   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3950     ;
3951   else if (flag_unsafe_math_optimizations)
3952     ;
3953   else
3954     {
3955       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3956       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3957       DONE;
3958     }
3959 })
3960
3961 (define_expand "truncdfsf2_with_temp"
3962   [(parallel [(set (match_operand:SF 0 "" "")
3963                    (float_truncate:SF (match_operand:DF 1 "" "")))
3964               (clobber (match_operand:SF 2 "" ""))])]
3965   "")
3966
3967 (define_insn "*truncdfsf_fast_mixed"
3968   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,x")
3969         (float_truncate:SF
3970           (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
3971   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3972 {
3973   switch (which_alternative)
3974     {
3975     case 0:
3976       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3977         return "fstp%z0\t%y0";
3978       else
3979         return "fst%z0\t%y0";
3980     case 1:
3981       return output_387_reg_move (insn, operands);
3982     case 2:
3983       return "cvtsd2ss\t{%1, %0|%0, %1}";
3984     default:
3985       gcc_unreachable ();
3986     }
3987 }
3988   [(set_attr "type" "fmov,fmov,ssecvt")
3989    (set_attr "mode" "SF")])
3990
3991 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3992 ;; because nothing we do here is unsafe.
3993 (define_insn "*truncdfsf_fast_sse"
3994   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
3995         (float_truncate:SF
3996           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
3997   "TARGET_SSE2 && TARGET_SSE_MATH"
3998   "cvtsd2ss\t{%1, %0|%0, %1}"
3999   [(set_attr "type" "ssecvt")
4000    (set_attr "mode" "SF")])
4001
4002 (define_insn "*truncdfsf_fast_i387"
4003   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4004         (float_truncate:SF
4005           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4006   "TARGET_80387 && flag_unsafe_math_optimizations"
4007   "* return output_387_reg_move (insn, operands);"
4008   [(set_attr "type" "fmov")
4009    (set_attr "mode" "SF")])
4010
4011 (define_insn "*truncdfsf_mixed"
4012   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y2")
4013         (float_truncate:SF
4014           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Y2m")))
4015    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
4016   "TARGET_MIX_SSE_I387"
4017 {
4018   switch (which_alternative)
4019     {
4020     case 0:
4021       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4022         return "fstp%z0\t%y0";
4023       else
4024         return "fst%z0\t%y0";
4025     case 1:
4026       return "#";
4027     case 2:
4028       return "cvtsd2ss\t{%1, %0|%0, %1}";
4029     default:
4030       gcc_unreachable ();
4031     }
4032 }
4033   [(set_attr "type" "fmov,multi,ssecvt")
4034    (set_attr "unit" "*,i387,*")
4035    (set_attr "mode" "SF")])
4036
4037 (define_insn "*truncdfsf_i387"
4038   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4039         (float_truncate:SF
4040           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4041    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4042   "TARGET_80387"
4043 {
4044   switch (which_alternative)
4045     {
4046     case 0:
4047       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4048         return "fstp%z0\t%y0";
4049       else
4050         return "fst%z0\t%y0";
4051     case 1:
4052       return "#";
4053     default:
4054       gcc_unreachable ();
4055     }
4056 }
4057   [(set_attr "type" "fmov,multi")
4058    (set_attr "unit" "*,i387")
4059    (set_attr "mode" "SF")])
4060
4061 (define_insn "*truncdfsf2_i387_1"
4062   [(set (match_operand:SF 0 "memory_operand" "=m")
4063         (float_truncate:SF
4064           (match_operand:DF 1 "register_operand" "f")))]
4065   "TARGET_80387
4066    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4067    && !TARGET_MIX_SSE_I387"
4068 {
4069   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4070     return "fstp%z0\t%y0";
4071   else
4072     return "fst%z0\t%y0";
4073 }
4074   [(set_attr "type" "fmov")
4075    (set_attr "mode" "SF")])
4076
4077 (define_split
4078   [(set (match_operand:SF 0 "register_operand" "")
4079         (float_truncate:SF
4080          (match_operand:DF 1 "fp_register_operand" "")))
4081    (clobber (match_operand 2 "" ""))]
4082   "reload_completed"
4083   [(set (match_dup 2) (match_dup 1))
4084    (set (match_dup 0) (match_dup 2))]
4085 {
4086   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4087 })
4088
4089 ;; Conversion from XFmode to SFmode.
4090
4091 (define_expand "truncxfsf2"
4092   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4093                    (float_truncate:SF
4094                     (match_operand:XF 1 "register_operand" "")))
4095               (clobber (match_dup 2))])]
4096   "TARGET_80387"
4097 {
4098   if (flag_unsafe_math_optimizations)
4099     {
4100       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
4101       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
4102       if (reg != operands[0])
4103         emit_move_insn (operands[0], reg);
4104       DONE;
4105     }
4106   else
4107     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
4108 })
4109
4110 (define_insn "*truncxfsf2_mixed"
4111   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
4112         (float_truncate:SF
4113          (match_operand:XF 1 "register_operand" "f,f,f,f")))
4114    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4115   "TARGET_80387"
4116 {
4117   gcc_assert (!which_alternative);
4118   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4119     return "fstp%z0\t%y0";
4120   else
4121     return "fst%z0\t%y0";
4122 }
4123   [(set_attr "type" "fmov,multi,multi,multi")
4124    (set_attr "unit" "*,i387,i387,i387")
4125    (set_attr "mode" "SF")])
4126
4127 (define_insn "truncxfsf2_i387_noop"
4128   [(set (match_operand:SF 0 "register_operand" "=f")
4129         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
4130   "TARGET_80387 && flag_unsafe_math_optimizations"
4131   "* return output_387_reg_move (insn, operands);"
4132   [(set_attr "type" "fmov")
4133    (set_attr "mode" "SF")])
4134
4135 (define_insn "*truncxfsf2_i387"
4136   [(set (match_operand:SF 0 "memory_operand" "=m")
4137         (float_truncate:SF
4138          (match_operand:XF 1 "register_operand" "f")))]
4139   "TARGET_80387"
4140 {
4141   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4142     return "fstp%z0\t%y0";
4143   else
4144     return "fst%z0\t%y0";
4145 }
4146   [(set_attr "type" "fmov")
4147    (set_attr "mode" "SF")])
4148
4149 (define_split
4150   [(set (match_operand:SF 0 "register_operand" "")
4151         (float_truncate:SF
4152          (match_operand:XF 1 "register_operand" "")))
4153    (clobber (match_operand:SF 2 "memory_operand" ""))]
4154   "TARGET_80387 && reload_completed"
4155   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4156    (set (match_dup 0) (match_dup 2))]
4157   "")
4158
4159 (define_split
4160   [(set (match_operand:SF 0 "memory_operand" "")
4161         (float_truncate:SF
4162          (match_operand:XF 1 "register_operand" "")))
4163    (clobber (match_operand:SF 2 "memory_operand" ""))]
4164   "TARGET_80387"
4165   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4166   "")
4167
4168 ;; Conversion from XFmode to DFmode.
4169
4170 (define_expand "truncxfdf2"
4171   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4172                    (float_truncate:DF
4173                     (match_operand:XF 1 "register_operand" "")))
4174               (clobber (match_dup 2))])]
4175   "TARGET_80387"
4176 {
4177   if (flag_unsafe_math_optimizations)
4178     {
4179       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
4180       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
4181       if (reg != operands[0])
4182         emit_move_insn (operands[0], reg);
4183       DONE;
4184     }
4185   else
4186     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
4187 })
4188
4189 (define_insn "*truncxfdf2_mixed"
4190   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y2*x")
4191         (float_truncate:DF
4192          (match_operand:XF 1 "register_operand" "f,f,f,f")))
4193    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4194   "TARGET_80387"
4195 {
4196   gcc_assert (!which_alternative);
4197   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4198     return "fstp%z0\t%y0";
4199   else
4200     return "fst%z0\t%y0";
4201 }
4202   [(set_attr "type" "fmov,multi,multi,multi")
4203    (set_attr "unit" "*,i387,i387,i387")
4204    (set_attr "mode" "DF")])
4205
4206 (define_insn "truncxfdf2_i387_noop"
4207   [(set (match_operand:DF 0 "register_operand" "=f")
4208         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4209   "TARGET_80387 && flag_unsafe_math_optimizations"
4210   "* return output_387_reg_move (insn, operands);"
4211   [(set_attr "type" "fmov")
4212    (set_attr "mode" "DF")])
4213
4214 (define_insn "*truncxfdf2_i387"
4215   [(set (match_operand:DF 0 "memory_operand" "=m")
4216         (float_truncate:DF
4217           (match_operand:XF 1 "register_operand" "f")))]
4218   "TARGET_80387"
4219 {
4220   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4221     return "fstp%z0\t%y0";
4222   else
4223     return "fst%z0\t%y0";
4224 }
4225   [(set_attr "type" "fmov")
4226    (set_attr "mode" "DF")])
4227
4228 (define_split
4229   [(set (match_operand:DF 0 "register_operand" "")
4230         (float_truncate:DF
4231          (match_operand:XF 1 "register_operand" "")))
4232    (clobber (match_operand:DF 2 "memory_operand" ""))]
4233   "TARGET_80387 && reload_completed"
4234   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4235    (set (match_dup 0) (match_dup 2))]
4236   "")
4237
4238 (define_split
4239   [(set (match_operand:DF 0 "memory_operand" "")
4240         (float_truncate:DF
4241          (match_operand:XF 1 "register_operand" "")))
4242    (clobber (match_operand:DF 2 "memory_operand" ""))]
4243   "TARGET_80387"
4244   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4245   "")
4246 \f
4247 ;; Signed conversion to DImode.
4248
4249 (define_expand "fix_truncxfdi2"
4250   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4251                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4252               (clobber (reg:CC FLAGS_REG))])]
4253   "TARGET_80387"
4254 {
4255   if (TARGET_FISTTP)
4256    {
4257      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4258      DONE;
4259    }
4260 })
4261
4262 (define_expand "fix_trunc<mode>di2"
4263   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4264                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4265               (clobber (reg:CC FLAGS_REG))])]
4266   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4267 {
4268   if (TARGET_FISTTP
4269       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4270    {
4271      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4272      DONE;
4273    }
4274   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4275    {
4276      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4277      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4278      if (out != operands[0])
4279         emit_move_insn (operands[0], out);
4280      DONE;
4281    }
4282 })
4283
4284 ;; Signed conversion to SImode.
4285
4286 (define_expand "fix_truncxfsi2"
4287   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4288                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4289               (clobber (reg:CC FLAGS_REG))])]
4290   "TARGET_80387"
4291 {
4292   if (TARGET_FISTTP)
4293    {
4294      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4295      DONE;
4296    }
4297 })
4298
4299 (define_expand "fix_trunc<mode>si2"
4300   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4301                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4302               (clobber (reg:CC FLAGS_REG))])]
4303   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4304 {
4305   if (TARGET_FISTTP
4306       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4307    {
4308      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4309      DONE;
4310    }
4311   if (SSE_FLOAT_MODE_P (<MODE>mode))
4312    {
4313      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4314      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4315      if (out != operands[0])
4316         emit_move_insn (operands[0], out);
4317      DONE;
4318    }
4319 })
4320
4321 ;; Signed conversion to HImode.
4322
4323 (define_expand "fix_trunc<mode>hi2"
4324   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4325                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4326               (clobber (reg:CC FLAGS_REG))])]
4327   "TARGET_80387
4328    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4329 {
4330   if (TARGET_FISTTP)
4331    {
4332      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4333      DONE;
4334    }
4335 })
4336
4337 ;; Unsigned conversion to SImode.
4338
4339 (define_expand "fixuns_trunc<mode>si2"
4340   [(parallel
4341     [(set (match_operand:SI 0 "register_operand" "")
4342           (unsigned_fix:SI
4343             (match_operand:SSEMODEF 1 "nonimmediate_operand" "")))
4344      (use (match_dup 2))
4345      (clobber (match_scratch:<ssevecmode> 3 ""))
4346      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4347   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4348 {
4349   enum machine_mode mode = <MODE>mode;
4350   enum machine_mode vecmode = <ssevecmode>mode;
4351   REAL_VALUE_TYPE TWO31r;
4352   rtx two31;
4353
4354   real_ldexp (&TWO31r, &dconst1, 31);
4355   two31 = const_double_from_real_value (TWO31r, mode);
4356   two31 = ix86_build_const_vector (mode, true, two31);
4357   operands[2] = force_reg (vecmode, two31);
4358 })
4359
4360 (define_insn_and_split "*fixuns_trunc<mode>_1"
4361   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4362         (unsigned_fix:SI
4363           (match_operand:SSEMODEF 3 "nonimmediate_operand" "xm,xm")))
4364    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4365    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4366    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4367   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4368   "#"
4369   "&& reload_completed"
4370   [(const_int 0)]
4371 {
4372   ix86_split_convert_uns_si_sse (operands);
4373   DONE;
4374 })
4375
4376 ;; Unsigned conversion to HImode.
4377 ;; Without these patterns, we'll try the unsigned SI conversion which
4378 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4379
4380 (define_expand "fixuns_truncsfhi2"
4381   [(set (match_dup 2)
4382         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "")))
4383    (set (match_operand:HI 0 "nonimmediate_operand" "")
4384         (subreg:HI (match_dup 2) 0))]
4385   "TARGET_SSE_MATH"
4386   "operands[2] = gen_reg_rtx (SImode);")
4387
4388 (define_expand "fixuns_truncdfhi2"
4389   [(set (match_dup 2)
4390         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "")))
4391    (set (match_operand:HI 0 "nonimmediate_operand" "")
4392         (subreg:HI (match_dup 2) 0))]
4393   "TARGET_SSE_MATH"
4394   "operands[2] = gen_reg_rtx (SImode);")
4395
4396 ;; When SSE is available, it is always faster to use it!
4397 (define_insn "fix_truncsfdi_sse"
4398   [(set (match_operand:DI 0 "register_operand" "=r,r")
4399         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4400   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4401   "cvttss2si{q}\t{%1, %0|%0, %1}"
4402   [(set_attr "type" "sseicvt")
4403    (set_attr "mode" "SF")
4404    (set_attr "athlon_decode" "double,vector")
4405    (set_attr "amdfam10_decode" "double,double")])
4406
4407 (define_insn "fix_truncdfdi_sse"
4408   [(set (match_operand:DI 0 "register_operand" "=r,r")
4409         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "x,xm")))]
4410   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4411   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4412   [(set_attr "type" "sseicvt")
4413    (set_attr "mode" "DF")
4414    (set_attr "athlon_decode" "double,vector")
4415    (set_attr "amdfam10_decode" "double,double")])
4416
4417 (define_insn "fix_truncsfsi_sse"
4418   [(set (match_operand:SI 0 "register_operand" "=r,r")
4419         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4420   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4421   "cvttss2si\t{%1, %0|%0, %1}"
4422   [(set_attr "type" "sseicvt")
4423    (set_attr "mode" "DF")
4424    (set_attr "athlon_decode" "double,vector")
4425    (set_attr "amdfam10_decode" "double,double")])
4426
4427 (define_insn "fix_truncdfsi_sse"
4428   [(set (match_operand:SI 0 "register_operand" "=r,r")
4429         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "x,xm")))]
4430   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4431   "cvttsd2si\t{%1, %0|%0, %1}"
4432   [(set_attr "type" "sseicvt")
4433    (set_attr "mode" "DF")
4434    (set_attr "athlon_decode" "double,vector")
4435    (set_attr "amdfam10_decode" "double,double")])
4436
4437 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4438 (define_peephole2
4439   [(set (match_operand:DF 0 "register_operand" "")
4440         (match_operand:DF 1 "memory_operand" ""))
4441    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4442         (fix:SSEMODEI24 (match_dup 0)))]
4443   "!TARGET_K8
4444    && peep2_reg_dead_p (2, operands[0])"
4445   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4446   "")
4447
4448 (define_peephole2
4449   [(set (match_operand:SF 0 "register_operand" "")
4450         (match_operand:SF 1 "memory_operand" ""))
4451    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4452         (fix:SSEMODEI24 (match_dup 0)))]
4453   "!TARGET_K8
4454    && peep2_reg_dead_p (2, operands[0])"
4455   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4456   "")
4457
4458 ;; Avoid vector decoded forms of the instruction.
4459 (define_peephole2
4460   [(match_scratch:DF 2 "Y")
4461    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4462         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4463   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4464   [(set (match_dup 2) (match_dup 1))
4465    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4466   "")
4467
4468 (define_peephole2
4469   [(match_scratch:SF 2 "x")
4470    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4471         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4472   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4473   [(set (match_dup 2) (match_dup 1))
4474    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4475   "")
4476
4477 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4478   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4479         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4480   "TARGET_FISTTP
4481    && FLOAT_MODE_P (GET_MODE (operands[1]))
4482    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4483          && (TARGET_64BIT || <MODE>mode != DImode))
4484         && TARGET_SSE_MATH)
4485    && !(reload_completed || reload_in_progress)"
4486   "#"
4487   "&& 1"
4488   [(const_int 0)]
4489 {
4490   if (memory_operand (operands[0], VOIDmode))
4491     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4492   else
4493     {
4494       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4495       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4496                                                             operands[1],
4497                                                             operands[2]));
4498     }
4499   DONE;
4500 }
4501   [(set_attr "type" "fisttp")
4502    (set_attr "mode" "<MODE>")])
4503
4504 (define_insn "fix_trunc<mode>_i387_fisttp"
4505   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4506         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4507    (clobber (match_scratch:XF 2 "=&1f"))]
4508   "TARGET_FISTTP
4509    && FLOAT_MODE_P (GET_MODE (operands[1]))
4510    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4511          && (TARGET_64BIT || <MODE>mode != DImode))
4512         && TARGET_SSE_MATH)"
4513   "* return output_fix_trunc (insn, operands, 1);"
4514   [(set_attr "type" "fisttp")
4515    (set_attr "mode" "<MODE>")])
4516
4517 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4518   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4519         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4520    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4521    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4522   "TARGET_FISTTP
4523    && FLOAT_MODE_P (GET_MODE (operands[1]))
4524    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4525         && (TARGET_64BIT || <MODE>mode != DImode))
4526         && TARGET_SSE_MATH)"
4527   "#"
4528   [(set_attr "type" "fisttp")
4529    (set_attr "mode" "<MODE>")])
4530
4531 (define_split
4532   [(set (match_operand:X87MODEI 0 "register_operand" "")
4533         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4534    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4535    (clobber (match_scratch 3 ""))]
4536   "reload_completed"
4537   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4538               (clobber (match_dup 3))])
4539    (set (match_dup 0) (match_dup 2))]
4540   "")
4541
4542 (define_split
4543   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4544         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4545    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4546    (clobber (match_scratch 3 ""))]
4547   "reload_completed"
4548   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4549               (clobber (match_dup 3))])]
4550   "")
4551
4552 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4553 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4554 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4555 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4556 ;; function in i386.c.
4557 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4558   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4559         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4560    (clobber (reg:CC FLAGS_REG))]
4561   "TARGET_80387 && !TARGET_FISTTP
4562    && FLOAT_MODE_P (GET_MODE (operands[1]))
4563    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4564          && (TARGET_64BIT || <MODE>mode != DImode))
4565    && !(reload_completed || reload_in_progress)"
4566   "#"
4567   "&& 1"
4568   [(const_int 0)]
4569 {
4570   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4571
4572   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4573   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4574   if (memory_operand (operands[0], VOIDmode))
4575     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4576                                          operands[2], operands[3]));
4577   else
4578     {
4579       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4580       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4581                                                      operands[2], operands[3],
4582                                                      operands[4]));
4583     }
4584   DONE;
4585 }
4586   [(set_attr "type" "fistp")
4587    (set_attr "i387_cw" "trunc")
4588    (set_attr "mode" "<MODE>")])
4589
4590 (define_insn "fix_truncdi_i387"
4591   [(set (match_operand:DI 0 "memory_operand" "=m")
4592         (fix:DI (match_operand 1 "register_operand" "f")))
4593    (use (match_operand:HI 2 "memory_operand" "m"))
4594    (use (match_operand:HI 3 "memory_operand" "m"))
4595    (clobber (match_scratch:XF 4 "=&1f"))]
4596   "TARGET_80387 && !TARGET_FISTTP
4597    && FLOAT_MODE_P (GET_MODE (operands[1]))
4598    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4599   "* return output_fix_trunc (insn, operands, 0);"
4600   [(set_attr "type" "fistp")
4601    (set_attr "i387_cw" "trunc")
4602    (set_attr "mode" "DI")])
4603
4604 (define_insn "fix_truncdi_i387_with_temp"
4605   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4606         (fix:DI (match_operand 1 "register_operand" "f,f")))
4607    (use (match_operand:HI 2 "memory_operand" "m,m"))
4608    (use (match_operand:HI 3 "memory_operand" "m,m"))
4609    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4610    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4611   "TARGET_80387 && !TARGET_FISTTP
4612    && FLOAT_MODE_P (GET_MODE (operands[1]))
4613    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4614   "#"
4615   [(set_attr "type" "fistp")
4616    (set_attr "i387_cw" "trunc")
4617    (set_attr "mode" "DI")])
4618
4619 (define_split
4620   [(set (match_operand:DI 0 "register_operand" "")
4621         (fix:DI (match_operand 1 "register_operand" "")))
4622    (use (match_operand:HI 2 "memory_operand" ""))
4623    (use (match_operand:HI 3 "memory_operand" ""))
4624    (clobber (match_operand:DI 4 "memory_operand" ""))
4625    (clobber (match_scratch 5 ""))]
4626   "reload_completed"
4627   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4628               (use (match_dup 2))
4629               (use (match_dup 3))
4630               (clobber (match_dup 5))])
4631    (set (match_dup 0) (match_dup 4))]
4632   "")
4633
4634 (define_split
4635   [(set (match_operand:DI 0 "memory_operand" "")
4636         (fix:DI (match_operand 1 "register_operand" "")))
4637    (use (match_operand:HI 2 "memory_operand" ""))
4638    (use (match_operand:HI 3 "memory_operand" ""))
4639    (clobber (match_operand:DI 4 "memory_operand" ""))
4640    (clobber (match_scratch 5 ""))]
4641   "reload_completed"
4642   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4643               (use (match_dup 2))
4644               (use (match_dup 3))
4645               (clobber (match_dup 5))])]
4646   "")
4647
4648 (define_insn "fix_trunc<mode>_i387"
4649   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4650         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4651    (use (match_operand:HI 2 "memory_operand" "m"))
4652    (use (match_operand:HI 3 "memory_operand" "m"))]
4653   "TARGET_80387 && !TARGET_FISTTP
4654    && FLOAT_MODE_P (GET_MODE (operands[1]))
4655    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4656   "* return output_fix_trunc (insn, operands, 0);"
4657   [(set_attr "type" "fistp")
4658    (set_attr "i387_cw" "trunc")
4659    (set_attr "mode" "<MODE>")])
4660
4661 (define_insn "fix_trunc<mode>_i387_with_temp"
4662   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4663         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4664    (use (match_operand:HI 2 "memory_operand" "m,m"))
4665    (use (match_operand:HI 3 "memory_operand" "m,m"))
4666    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4667   "TARGET_80387 && !TARGET_FISTTP
4668    && FLOAT_MODE_P (GET_MODE (operands[1]))
4669    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4670   "#"
4671   [(set_attr "type" "fistp")
4672    (set_attr "i387_cw" "trunc")
4673    (set_attr "mode" "<MODE>")])
4674
4675 (define_split
4676   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4677         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4678    (use (match_operand:HI 2 "memory_operand" ""))
4679    (use (match_operand:HI 3 "memory_operand" ""))
4680    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4681   "reload_completed"
4682   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4683               (use (match_dup 2))
4684               (use (match_dup 3))])
4685    (set (match_dup 0) (match_dup 4))]
4686   "")
4687
4688 (define_split
4689   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4690         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4691    (use (match_operand:HI 2 "memory_operand" ""))
4692    (use (match_operand:HI 3 "memory_operand" ""))
4693    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4694   "reload_completed"
4695   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4696               (use (match_dup 2))
4697               (use (match_dup 3))])]
4698   "")
4699
4700 (define_insn "x86_fnstcw_1"
4701   [(set (match_operand:HI 0 "memory_operand" "=m")
4702         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4703   "TARGET_80387"
4704   "fnstcw\t%0"
4705   [(set_attr "length" "2")
4706    (set_attr "mode" "HI")
4707    (set_attr "unit" "i387")])
4708
4709 (define_insn "x86_fldcw_1"
4710   [(set (reg:HI FPCR_REG)
4711         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4712   "TARGET_80387"
4713   "fldcw\t%0"
4714   [(set_attr "length" "2")
4715    (set_attr "mode" "HI")
4716    (set_attr "unit" "i387")
4717    (set_attr "athlon_decode" "vector")
4718    (set_attr "amdfam10_decode" "vector")])   
4719 \f
4720 ;; Conversion between fixed point and floating point.
4721
4722 ;; Even though we only accept memory inputs, the backend _really_
4723 ;; wants to be able to do this between registers.
4724
4725 (define_expand "floathisf2"
4726   [(set (match_operand:SF 0 "register_operand" "")
4727         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4728   "TARGET_80387 || TARGET_SSE_MATH"
4729 {
4730   if (TARGET_SSE_MATH)
4731     {
4732       emit_insn (gen_floatsisf2 (operands[0],
4733                                  convert_to_mode (SImode, operands[1], 0)));
4734       DONE;
4735     }
4736 })
4737
4738 (define_insn "*floathisf2_i387"
4739   [(set (match_operand:SF 0 "register_operand" "=f,f")
4740         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4741   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4742   "@
4743    fild%z1\t%1
4744    #"
4745   [(set_attr "type" "fmov,multi")
4746    (set_attr "mode" "SF")
4747    (set_attr "unit" "*,i387")
4748    (set_attr "fp_int_src" "true")])
4749
4750 (define_expand "floatsisf2"
4751   [(set (match_operand:SF 0 "register_operand" "")
4752         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4753   "TARGET_80387 || TARGET_SSE_MATH"
4754   "")
4755
4756 (define_insn "*floatsisf2_mixed"
4757   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4758         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4759   "TARGET_MIX_SSE_I387"
4760   "@
4761    fild%z1\t%1
4762    #
4763    cvtsi2ss\t{%1, %0|%0, %1}
4764    cvtsi2ss\t{%1, %0|%0, %1}"
4765   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4766    (set_attr "mode" "SF")
4767    (set_attr "unit" "*,i387,*,*")
4768    (set_attr "athlon_decode" "*,*,vector,double")
4769    (set_attr "amdfam10_decode" "*,*,vector,double")
4770    (set_attr "fp_int_src" "true")])
4771
4772 (define_insn "*floatsisf2_sse"
4773   [(set (match_operand:SF 0 "register_operand" "=x,x")
4774         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4775   "TARGET_SSE_MATH"
4776   "cvtsi2ss\t{%1, %0|%0, %1}"
4777   [(set_attr "type" "sseicvt")
4778    (set_attr "mode" "SF")
4779    (set_attr "athlon_decode" "vector,double")
4780    (set_attr "amdfam10_decode" "vector,double")
4781    (set_attr "fp_int_src" "true")])
4782
4783 (define_insn "*floatsisf2_i387"
4784   [(set (match_operand:SF 0 "register_operand" "=f,f")
4785         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4786   "TARGET_80387"
4787   "@
4788    fild%z1\t%1
4789    #"
4790   [(set_attr "type" "fmov,multi")
4791    (set_attr "mode" "SF")
4792    (set_attr "unit" "*,i387")
4793    (set_attr "fp_int_src" "true")])
4794
4795 (define_expand "floatdisf2"
4796   [(set (match_operand:SF 0 "register_operand" "")
4797         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4798   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4799   "")
4800
4801 (define_insn "*floatdisf2_mixed"
4802   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4803         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4804   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4805   "@
4806    fild%z1\t%1
4807    #
4808    cvtsi2ss{q}\t{%1, %0|%0, %1}
4809    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4810   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4811    (set_attr "mode" "SF")
4812    (set_attr "unit" "*,i387,*,*")
4813    (set_attr "athlon_decode" "*,*,vector,double")
4814    (set_attr "amdfam10_decode" "*,*,vector,double")
4815    (set_attr "fp_int_src" "true")])
4816
4817 (define_insn "*floatdisf2_sse"
4818   [(set (match_operand:SF 0 "register_operand" "=x,x")
4819         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4820   "TARGET_64BIT && TARGET_SSE_MATH"
4821   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4822   [(set_attr "type" "sseicvt")
4823    (set_attr "mode" "SF")
4824    (set_attr "athlon_decode" "vector,double")
4825    (set_attr "amdfam10_decode" "vector,double")
4826    (set_attr "fp_int_src" "true")])
4827
4828 (define_insn "*floatdisf2_i387"
4829   [(set (match_operand:SF 0 "register_operand" "=f,f")
4830         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4831   "TARGET_80387"
4832   "@
4833    fild%z1\t%1
4834    #"
4835   [(set_attr "type" "fmov,multi")
4836    (set_attr "mode" "SF")
4837    (set_attr "unit" "*,i387")
4838    (set_attr "fp_int_src" "true")])
4839
4840 (define_expand "floathidf2"
4841   [(set (match_operand:DF 0 "register_operand" "")
4842         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4843   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4844 {
4845   if (TARGET_SSE2 && TARGET_SSE_MATH)
4846     {
4847       emit_insn (gen_floatsidf2 (operands[0],
4848                                  convert_to_mode (SImode, operands[1], 0)));
4849       DONE;
4850     }
4851 })
4852
4853 (define_insn "*floathidf2_i387"
4854   [(set (match_operand:DF 0 "register_operand" "=f,f")
4855         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4856   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4857   "@
4858    fild%z1\t%1
4859    #"
4860   [(set_attr "type" "fmov,multi")
4861    (set_attr "mode" "DF")
4862    (set_attr "unit" "*,i387")
4863    (set_attr "fp_int_src" "true")])
4864
4865 (define_expand "floatsidf2"
4866   [(set (match_operand:DF 0 "register_operand" "")
4867         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4868   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4869   "")
4870
4871 (define_insn "*floatsidf2_mixed"
4872   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4873         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4874   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4875   "@
4876    fild%z1\t%1
4877    #
4878    cvtsi2sd\t{%1, %0|%0, %1}
4879    cvtsi2sd\t{%1, %0|%0, %1}"
4880   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4881    (set_attr "mode" "DF")
4882    (set_attr "unit" "*,i387,*,*")
4883    (set_attr "athlon_decode" "*,*,double,direct")
4884    (set_attr "amdfam10_decode" "*,*,vector,double")
4885    (set_attr "fp_int_src" "true")])
4886
4887 (define_insn "*floatsidf2_sse"
4888   [(set (match_operand:DF 0 "register_operand" "=x,x")
4889         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4890   "TARGET_SSE2 && TARGET_SSE_MATH"
4891   "cvtsi2sd\t{%1, %0|%0, %1}"
4892   [(set_attr "type" "sseicvt")
4893    (set_attr "mode" "DF")
4894    (set_attr "athlon_decode" "double,direct")
4895    (set_attr "amdfam10_decode" "vector,double")
4896    (set_attr "fp_int_src" "true")])
4897
4898 (define_insn "*floatsidf2_i387"
4899   [(set (match_operand:DF 0 "register_operand" "=f,f")
4900         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4901   "TARGET_80387"
4902   "@
4903    fild%z1\t%1
4904    #"
4905   [(set_attr "type" "fmov,multi")
4906    (set_attr "mode" "DF")
4907    (set_attr "unit" "*,i387")
4908    (set_attr "fp_int_src" "true")])
4909
4910 (define_expand "floatdidf2"
4911   [(set (match_operand:DF 0 "register_operand" "")
4912         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4913   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4914 {
4915   if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
4916     {
4917       ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
4918       DONE;
4919     }
4920 })
4921
4922 (define_insn "*floatdidf2_mixed"
4923   [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4924         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4925   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4926   "@
4927    fild%z1\t%1
4928    #
4929    cvtsi2sd{q}\t{%1, %0|%0, %1}
4930    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4931   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4932    (set_attr "mode" "DF")
4933    (set_attr "unit" "*,i387,*,*")
4934    (set_attr "athlon_decode" "*,*,double,direct")
4935    (set_attr "amdfam10_decode" "*,*,vector,double")
4936    (set_attr "fp_int_src" "true")])
4937
4938 (define_insn "*floatdidf2_sse"
4939   [(set (match_operand:DF 0 "register_operand" "=x,x")
4940         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4941   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4942   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4943   [(set_attr "type" "sseicvt")
4944    (set_attr "mode" "DF")
4945    (set_attr "athlon_decode" "double,direct")
4946    (set_attr "amdfam10_decode" "vector,double")
4947    (set_attr "fp_int_src" "true")])
4948
4949 (define_insn "*floatdidf2_i387"
4950   [(set (match_operand:DF 0 "register_operand" "=f,f")
4951         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4952   "TARGET_80387"
4953   "@
4954    fild%z1\t%1
4955    #"
4956   [(set_attr "type" "fmov,multi")
4957    (set_attr "mode" "DF")
4958    (set_attr "unit" "*,i387")
4959    (set_attr "fp_int_src" "true")])
4960
4961 (define_insn "floathixf2"
4962   [(set (match_operand:XF 0 "register_operand" "=f,f")
4963         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4964   "TARGET_80387"
4965   "@
4966    fild%z1\t%1
4967    #"
4968   [(set_attr "type" "fmov,multi")
4969    (set_attr "mode" "XF")
4970    (set_attr "unit" "*,i387")
4971    (set_attr "fp_int_src" "true")])
4972
4973 (define_insn "floatsixf2"
4974   [(set (match_operand:XF 0 "register_operand" "=f,f")
4975         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4976   "TARGET_80387"
4977   "@
4978    fild%z1\t%1
4979    #"
4980   [(set_attr "type" "fmov,multi")
4981    (set_attr "mode" "XF")
4982    (set_attr "unit" "*,i387")
4983    (set_attr "fp_int_src" "true")])
4984
4985 (define_insn "floatdixf2"
4986   [(set (match_operand:XF 0 "register_operand" "=f,f")
4987         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4988   "TARGET_80387"
4989   "@
4990    fild%z1\t%1
4991    #"
4992   [(set_attr "type" "fmov,multi")
4993    (set_attr "mode" "XF")
4994    (set_attr "unit" "*,i387")
4995    (set_attr "fp_int_src" "true")])
4996
4997 ;; %%% Kill these when reload knows how to do it.
4998 (define_split
4999   [(set (match_operand 0 "fp_register_operand" "")
5000         (float (match_operand 1 "register_operand" "")))]
5001   "reload_completed
5002    && TARGET_80387
5003    && FLOAT_MODE_P (GET_MODE (operands[0]))"
5004   [(const_int 0)]
5005 {
5006   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5007   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5008   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5009   ix86_free_from_memory (GET_MODE (operands[1]));
5010   DONE;
5011 })
5012
5013 (define_expand "floatunssisf2"
5014   [(use (match_operand:SF 0 "register_operand" ""))
5015    (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5016   "!TARGET_64BIT"
5017 {
5018   if (TARGET_SSE_MATH && TARGET_SSE2)
5019     ix86_expand_convert_uns_sisf_sse (operands[0], operands[1]);
5020   else
5021     x86_emit_floatuns (operands);
5022   DONE;
5023 })
5024
5025 (define_expand "floatunssidf2"
5026   [(use (match_operand:DF 0 "register_operand" ""))
5027    (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5028   "!TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE2"
5029   "ix86_expand_convert_uns_sidf_sse (operands[0], operands[1]); DONE;")
5030
5031 (define_expand "floatunsdisf2"
5032   [(use (match_operand:SF 0 "register_operand" ""))
5033    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5034   "TARGET_64BIT && TARGET_SSE_MATH"
5035   "x86_emit_floatuns (operands); DONE;")
5036
5037 (define_expand "floatunsdidf2"
5038   [(use (match_operand:DF 0 "register_operand" ""))
5039    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5040   "TARGET_SSE_MATH && TARGET_SSE2
5041    && (TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)"
5042 {
5043   if (TARGET_64BIT)
5044     x86_emit_floatuns (operands);
5045   else
5046     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5047   DONE;
5048 })
5049 \f
5050 ;; SSE extract/set expanders
5051
5052 \f
5053 ;; Add instructions
5054
5055 ;; %%% splits for addditi3
5056
5057 (define_expand "addti3"
5058   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5059         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5060                  (match_operand:TI 2 "x86_64_general_operand" "")))
5061    (clobber (reg:CC FLAGS_REG))]
5062   "TARGET_64BIT"
5063   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5064
5065 (define_insn "*addti3_1"
5066   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5067         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5068                  (match_operand:TI 2 "general_operand" "roiF,riF")))
5069    (clobber (reg:CC FLAGS_REG))]
5070   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5071   "#")
5072
5073 (define_split
5074   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5075         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5076                  (match_operand:TI 2 "general_operand" "")))
5077    (clobber (reg:CC FLAGS_REG))]
5078   "TARGET_64BIT && reload_completed"
5079   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5080                                           UNSPEC_ADD_CARRY))
5081               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5082    (parallel [(set (match_dup 3)
5083                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5084                                      (match_dup 4))
5085                             (match_dup 5)))
5086               (clobber (reg:CC FLAGS_REG))])]
5087   "split_ti (operands+0, 1, operands+0, operands+3);
5088    split_ti (operands+1, 1, operands+1, operands+4);
5089    split_ti (operands+2, 1, operands+2, operands+5);")
5090
5091 ;; %%% splits for addsidi3
5092 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5093 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5094 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5095
5096 (define_expand "adddi3"
5097   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5098         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5099                  (match_operand:DI 2 "x86_64_general_operand" "")))
5100    (clobber (reg:CC FLAGS_REG))]
5101   ""
5102   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5103
5104 (define_insn "*adddi3_1"
5105   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5106         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5107                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5108    (clobber (reg:CC FLAGS_REG))]
5109   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5110   "#")
5111
5112 (define_split
5113   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5114         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5115                  (match_operand:DI 2 "general_operand" "")))
5116    (clobber (reg:CC FLAGS_REG))]
5117   "!TARGET_64BIT && reload_completed"
5118   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5119                                           UNSPEC_ADD_CARRY))
5120               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5121    (parallel [(set (match_dup 3)
5122                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5123                                      (match_dup 4))
5124                             (match_dup 5)))
5125               (clobber (reg:CC FLAGS_REG))])]
5126   "split_di (operands+0, 1, operands+0, operands+3);
5127    split_di (operands+1, 1, operands+1, operands+4);
5128    split_di (operands+2, 1, operands+2, operands+5);")
5129
5130 (define_insn "adddi3_carry_rex64"
5131   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5132           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5133                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5134                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5135    (clobber (reg:CC FLAGS_REG))]
5136   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5137   "adc{q}\t{%2, %0|%0, %2}"
5138   [(set_attr "type" "alu")
5139    (set_attr "pent_pair" "pu")
5140    (set_attr "mode" "DI")])
5141
5142 (define_insn "*adddi3_cc_rex64"
5143   [(set (reg:CC FLAGS_REG)
5144         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5145                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5146                    UNSPEC_ADD_CARRY))
5147    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5148         (plus:DI (match_dup 1) (match_dup 2)))]
5149   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5150   "add{q}\t{%2, %0|%0, %2}"
5151   [(set_attr "type" "alu")
5152    (set_attr "mode" "DI")])
5153
5154 (define_insn "addqi3_carry"
5155   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5156           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5157                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5158                    (match_operand:QI 2 "general_operand" "qi,qm")))
5159    (clobber (reg:CC FLAGS_REG))]
5160   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5161   "adc{b}\t{%2, %0|%0, %2}"
5162   [(set_attr "type" "alu")
5163    (set_attr "pent_pair" "pu")
5164    (set_attr "mode" "QI")])
5165
5166 (define_insn "addhi3_carry"
5167   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5168           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5169                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5170                    (match_operand:HI 2 "general_operand" "ri,rm")))
5171    (clobber (reg:CC FLAGS_REG))]
5172   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5173   "adc{w}\t{%2, %0|%0, %2}"
5174   [(set_attr "type" "alu")
5175    (set_attr "pent_pair" "pu")
5176    (set_attr "mode" "HI")])
5177
5178 (define_insn "addsi3_carry"
5179   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5180           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5181                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5182                    (match_operand:SI 2 "general_operand" "ri,rm")))
5183    (clobber (reg:CC FLAGS_REG))]
5184   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5185   "adc{l}\t{%2, %0|%0, %2}"
5186   [(set_attr "type" "alu")
5187    (set_attr "pent_pair" "pu")
5188    (set_attr "mode" "SI")])
5189
5190 (define_insn "*addsi3_carry_zext"
5191   [(set (match_operand:DI 0 "register_operand" "=r")
5192           (zero_extend:DI
5193             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5194                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5195                      (match_operand:SI 2 "general_operand" "rim"))))
5196    (clobber (reg:CC FLAGS_REG))]
5197   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5198   "adc{l}\t{%2, %k0|%k0, %2}"
5199   [(set_attr "type" "alu")
5200    (set_attr "pent_pair" "pu")
5201    (set_attr "mode" "SI")])
5202
5203 (define_insn "*addsi3_cc"
5204   [(set (reg:CC FLAGS_REG)
5205         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5206                     (match_operand:SI 2 "general_operand" "ri,rm")]
5207                    UNSPEC_ADD_CARRY))
5208    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5209         (plus:SI (match_dup 1) (match_dup 2)))]
5210   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5211   "add{l}\t{%2, %0|%0, %2}"
5212   [(set_attr "type" "alu")
5213    (set_attr "mode" "SI")])
5214
5215 (define_insn "addqi3_cc"
5216   [(set (reg:CC FLAGS_REG)
5217         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5218                     (match_operand:QI 2 "general_operand" "qi,qm")]
5219                    UNSPEC_ADD_CARRY))
5220    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5221         (plus:QI (match_dup 1) (match_dup 2)))]
5222   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5223   "add{b}\t{%2, %0|%0, %2}"
5224   [(set_attr "type" "alu")
5225    (set_attr "mode" "QI")])
5226
5227 (define_expand "addsi3"
5228   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5229                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5230                             (match_operand:SI 2 "general_operand" "")))
5231               (clobber (reg:CC FLAGS_REG))])]
5232   ""
5233   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5234
5235 (define_insn "*lea_1"
5236   [(set (match_operand:SI 0 "register_operand" "=r")
5237         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5238   "!TARGET_64BIT"
5239   "lea{l}\t{%a1, %0|%0, %a1}"
5240   [(set_attr "type" "lea")
5241    (set_attr "mode" "SI")])
5242
5243 (define_insn "*lea_1_rex64"
5244   [(set (match_operand:SI 0 "register_operand" "=r")
5245         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5246   "TARGET_64BIT"
5247   "lea{l}\t{%a1, %0|%0, %a1}"
5248   [(set_attr "type" "lea")
5249    (set_attr "mode" "SI")])
5250
5251 (define_insn "*lea_1_zext"
5252   [(set (match_operand:DI 0 "register_operand" "=r")
5253         (zero_extend:DI
5254          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5255   "TARGET_64BIT"
5256   "lea{l}\t{%a1, %k0|%k0, %a1}"
5257   [(set_attr "type" "lea")
5258    (set_attr "mode" "SI")])
5259
5260 (define_insn "*lea_2_rex64"
5261   [(set (match_operand:DI 0 "register_operand" "=r")
5262         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5263   "TARGET_64BIT"
5264   "lea{q}\t{%a1, %0|%0, %a1}"
5265   [(set_attr "type" "lea")
5266    (set_attr "mode" "DI")])
5267
5268 ;; The lea patterns for non-Pmodes needs to be matched by several
5269 ;; insns converted to real lea by splitters.
5270
5271 (define_insn_and_split "*lea_general_1"
5272   [(set (match_operand 0 "register_operand" "=r")
5273         (plus (plus (match_operand 1 "index_register_operand" "l")
5274                     (match_operand 2 "register_operand" "r"))
5275               (match_operand 3 "immediate_operand" "i")))]
5276   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5277     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5278    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5279    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5280    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5281    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5282        || GET_MODE (operands[3]) == VOIDmode)"
5283   "#"
5284   "&& reload_completed"
5285   [(const_int 0)]
5286 {
5287   rtx pat;
5288   operands[0] = gen_lowpart (SImode, operands[0]);
5289   operands[1] = gen_lowpart (Pmode, operands[1]);
5290   operands[2] = gen_lowpart (Pmode, operands[2]);
5291   operands[3] = gen_lowpart (Pmode, operands[3]);
5292   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5293                       operands[3]);
5294   if (Pmode != SImode)
5295     pat = gen_rtx_SUBREG (SImode, pat, 0);
5296   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5297   DONE;
5298 }
5299   [(set_attr "type" "lea")
5300    (set_attr "mode" "SI")])
5301
5302 (define_insn_and_split "*lea_general_1_zext"
5303   [(set (match_operand:DI 0 "register_operand" "=r")
5304         (zero_extend:DI
5305           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5306                             (match_operand:SI 2 "register_operand" "r"))
5307                    (match_operand:SI 3 "immediate_operand" "i"))))]
5308   "TARGET_64BIT"
5309   "#"
5310   "&& reload_completed"
5311   [(set (match_dup 0)
5312         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5313                                                      (match_dup 2))
5314                                             (match_dup 3)) 0)))]
5315 {
5316   operands[1] = gen_lowpart (Pmode, operands[1]);
5317   operands[2] = gen_lowpart (Pmode, operands[2]);
5318   operands[3] = gen_lowpart (Pmode, operands[3]);
5319 }
5320   [(set_attr "type" "lea")
5321    (set_attr "mode" "SI")])
5322
5323 (define_insn_and_split "*lea_general_2"
5324   [(set (match_operand 0 "register_operand" "=r")
5325         (plus (mult (match_operand 1 "index_register_operand" "l")
5326                     (match_operand 2 "const248_operand" "i"))
5327               (match_operand 3 "nonmemory_operand" "ri")))]
5328   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5329     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5330    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5331    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5332    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5333        || GET_MODE (operands[3]) == VOIDmode)"
5334   "#"
5335   "&& reload_completed"
5336   [(const_int 0)]
5337 {
5338   rtx pat;
5339   operands[0] = gen_lowpart (SImode, operands[0]);
5340   operands[1] = gen_lowpart (Pmode, operands[1]);
5341   operands[3] = gen_lowpart (Pmode, operands[3]);
5342   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5343                       operands[3]);
5344   if (Pmode != SImode)
5345     pat = gen_rtx_SUBREG (SImode, pat, 0);
5346   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5347   DONE;
5348 }
5349   [(set_attr "type" "lea")
5350    (set_attr "mode" "SI")])
5351
5352 (define_insn_and_split "*lea_general_2_zext"
5353   [(set (match_operand:DI 0 "register_operand" "=r")
5354         (zero_extend:DI
5355           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5356                             (match_operand:SI 2 "const248_operand" "n"))
5357                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5358   "TARGET_64BIT"
5359   "#"
5360   "&& reload_completed"
5361   [(set (match_dup 0)
5362         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5363                                                      (match_dup 2))
5364                                             (match_dup 3)) 0)))]
5365 {
5366   operands[1] = gen_lowpart (Pmode, operands[1]);
5367   operands[3] = gen_lowpart (Pmode, operands[3]);
5368 }
5369   [(set_attr "type" "lea")
5370    (set_attr "mode" "SI")])
5371
5372 (define_insn_and_split "*lea_general_3"
5373   [(set (match_operand 0 "register_operand" "=r")
5374         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5375                           (match_operand 2 "const248_operand" "i"))
5376                     (match_operand 3 "register_operand" "r"))
5377               (match_operand 4 "immediate_operand" "i")))]
5378   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5379     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5380    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5381    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5382    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5383   "#"
5384   "&& reload_completed"
5385   [(const_int 0)]
5386 {
5387   rtx pat;
5388   operands[0] = gen_lowpart (SImode, operands[0]);
5389   operands[1] = gen_lowpart (Pmode, operands[1]);
5390   operands[3] = gen_lowpart (Pmode, operands[3]);
5391   operands[4] = gen_lowpart (Pmode, operands[4]);
5392   pat = gen_rtx_PLUS (Pmode,
5393                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5394                                                          operands[2]),
5395                                     operands[3]),
5396                       operands[4]);
5397   if (Pmode != SImode)
5398     pat = gen_rtx_SUBREG (SImode, pat, 0);
5399   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5400   DONE;
5401 }
5402   [(set_attr "type" "lea")
5403    (set_attr "mode" "SI")])
5404
5405 (define_insn_and_split "*lea_general_3_zext"
5406   [(set (match_operand:DI 0 "register_operand" "=r")
5407         (zero_extend:DI
5408           (plus:SI (plus:SI (mult:SI
5409                               (match_operand:SI 1 "index_register_operand" "l")
5410                               (match_operand:SI 2 "const248_operand" "n"))
5411                             (match_operand:SI 3 "register_operand" "r"))
5412                    (match_operand:SI 4 "immediate_operand" "i"))))]
5413   "TARGET_64BIT"
5414   "#"
5415   "&& reload_completed"
5416   [(set (match_dup 0)
5417         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5418                                                               (match_dup 2))
5419                                                      (match_dup 3))
5420                                             (match_dup 4)) 0)))]
5421 {
5422   operands[1] = gen_lowpart (Pmode, operands[1]);
5423   operands[3] = gen_lowpart (Pmode, operands[3]);
5424   operands[4] = gen_lowpart (Pmode, operands[4]);
5425 }
5426   [(set_attr "type" "lea")
5427    (set_attr "mode" "SI")])
5428
5429 (define_insn "*adddi_1_rex64"
5430   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5431         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5432                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5433    (clobber (reg:CC FLAGS_REG))]
5434   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5435 {
5436   switch (get_attr_type (insn))
5437     {
5438     case TYPE_LEA:
5439       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5440       return "lea{q}\t{%a2, %0|%0, %a2}";
5441
5442     case TYPE_INCDEC:
5443       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5444       if (operands[2] == const1_rtx)
5445         return "inc{q}\t%0";
5446       else
5447         {
5448           gcc_assert (operands[2] == constm1_rtx);
5449           return "dec{q}\t%0";
5450         }
5451
5452     default:
5453       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5454
5455       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5456          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5457       if (CONST_INT_P (operands[2])
5458           /* Avoid overflows.  */
5459           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5460           && (INTVAL (operands[2]) == 128
5461               || (INTVAL (operands[2]) < 0
5462                   && INTVAL (operands[2]) != -128)))
5463         {
5464           operands[2] = GEN_INT (-INTVAL (operands[2]));
5465           return "sub{q}\t{%2, %0|%0, %2}";
5466         }
5467       return "add{q}\t{%2, %0|%0, %2}";
5468     }
5469 }
5470   [(set (attr "type")
5471      (cond [(eq_attr "alternative" "2")
5472               (const_string "lea")
5473             ; Current assemblers are broken and do not allow @GOTOFF in
5474             ; ought but a memory context.
5475             (match_operand:DI 2 "pic_symbolic_operand" "")
5476               (const_string "lea")
5477             (match_operand:DI 2 "incdec_operand" "")
5478               (const_string "incdec")
5479            ]
5480            (const_string "alu")))
5481    (set_attr "mode" "DI")])
5482
5483 ;; Convert lea to the lea pattern to avoid flags dependency.
5484 (define_split
5485   [(set (match_operand:DI 0 "register_operand" "")
5486         (plus:DI (match_operand:DI 1 "register_operand" "")
5487                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5488    (clobber (reg:CC FLAGS_REG))]
5489   "TARGET_64BIT && reload_completed
5490    && true_regnum (operands[0]) != true_regnum (operands[1])"
5491   [(set (match_dup 0)
5492         (plus:DI (match_dup 1)
5493                  (match_dup 2)))]
5494   "")
5495
5496 (define_insn "*adddi_2_rex64"
5497   [(set (reg FLAGS_REG)
5498         (compare
5499           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5500                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5501           (const_int 0)))
5502    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5503         (plus:DI (match_dup 1) (match_dup 2)))]
5504   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5505    && ix86_binary_operator_ok (PLUS, DImode, operands)
5506    /* Current assemblers are broken and do not allow @GOTOFF in
5507       ought but a memory context.  */
5508    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5509 {
5510   switch (get_attr_type (insn))
5511     {
5512     case TYPE_INCDEC:
5513       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5514       if (operands[2] == const1_rtx)
5515         return "inc{q}\t%0";
5516       else
5517         {
5518           gcc_assert (operands[2] == constm1_rtx);
5519           return "dec{q}\t%0";
5520         }
5521
5522     default:
5523       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5524       /* ???? We ought to handle there the 32bit case too
5525          - do we need new constraint?  */
5526       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5527          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5528       if (CONST_INT_P (operands[2])
5529           /* Avoid overflows.  */
5530           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5531           && (INTVAL (operands[2]) == 128
5532               || (INTVAL (operands[2]) < 0
5533                   && INTVAL (operands[2]) != -128)))
5534         {
5535           operands[2] = GEN_INT (-INTVAL (operands[2]));
5536           return "sub{q}\t{%2, %0|%0, %2}";
5537         }
5538       return "add{q}\t{%2, %0|%0, %2}";
5539     }
5540 }
5541   [(set (attr "type")
5542      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5543         (const_string "incdec")
5544         (const_string "alu")))
5545    (set_attr "mode" "DI")])
5546
5547 (define_insn "*adddi_3_rex64"
5548   [(set (reg FLAGS_REG)
5549         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5550                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5551    (clobber (match_scratch:DI 0 "=r"))]
5552   "TARGET_64BIT
5553    && ix86_match_ccmode (insn, CCZmode)
5554    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5555    /* Current assemblers are broken and do not allow @GOTOFF in
5556       ought but a memory context.  */
5557    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5558 {
5559   switch (get_attr_type (insn))
5560     {
5561     case TYPE_INCDEC:
5562       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5563       if (operands[2] == const1_rtx)
5564         return "inc{q}\t%0";
5565       else
5566         {
5567           gcc_assert (operands[2] == constm1_rtx);
5568           return "dec{q}\t%0";
5569         }
5570
5571     default:
5572       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5573       /* ???? We ought to handle there the 32bit case too
5574          - do we need new constraint?  */
5575       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5576          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5577       if (CONST_INT_P (operands[2])
5578           /* Avoid overflows.  */
5579           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5580           && (INTVAL (operands[2]) == 128
5581               || (INTVAL (operands[2]) < 0
5582                   && INTVAL (operands[2]) != -128)))
5583         {
5584           operands[2] = GEN_INT (-INTVAL (operands[2]));
5585           return "sub{q}\t{%2, %0|%0, %2}";
5586         }
5587       return "add{q}\t{%2, %0|%0, %2}";
5588     }
5589 }
5590   [(set (attr "type")
5591      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5592         (const_string "incdec")
5593         (const_string "alu")))
5594    (set_attr "mode" "DI")])
5595
5596 ; For comparisons against 1, -1 and 128, we may generate better code
5597 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5598 ; is matched then.  We can't accept general immediate, because for
5599 ; case of overflows,  the result is messed up.
5600 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5601 ; when negated.
5602 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5603 ; only for comparisons not depending on it.
5604 (define_insn "*adddi_4_rex64"
5605   [(set (reg FLAGS_REG)
5606         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5607                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5608    (clobber (match_scratch:DI 0 "=rm"))]
5609   "TARGET_64BIT
5610    &&  ix86_match_ccmode (insn, CCGCmode)"
5611 {
5612   switch (get_attr_type (insn))
5613     {
5614     case TYPE_INCDEC:
5615       if (operands[2] == constm1_rtx)
5616         return "inc{q}\t%0";
5617       else
5618         {
5619           gcc_assert (operands[2] == const1_rtx);
5620           return "dec{q}\t%0";
5621         }
5622
5623     default:
5624       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5625       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5626          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5627       if ((INTVAL (operands[2]) == -128
5628            || (INTVAL (operands[2]) > 0
5629                && INTVAL (operands[2]) != 128))
5630           /* Avoid overflows.  */
5631           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5632         return "sub{q}\t{%2, %0|%0, %2}";
5633       operands[2] = GEN_INT (-INTVAL (operands[2]));
5634       return "add{q}\t{%2, %0|%0, %2}";
5635     }
5636 }
5637   [(set (attr "type")
5638      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5639         (const_string "incdec")
5640         (const_string "alu")))
5641    (set_attr "mode" "DI")])
5642
5643 (define_insn "*adddi_5_rex64"
5644   [(set (reg FLAGS_REG)
5645         (compare
5646           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5647                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5648           (const_int 0)))
5649    (clobber (match_scratch:DI 0 "=r"))]
5650   "TARGET_64BIT
5651    && ix86_match_ccmode (insn, CCGOCmode)
5652    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5653    /* Current assemblers are broken and do not allow @GOTOFF in
5654       ought but a memory context.  */
5655    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5656 {
5657   switch (get_attr_type (insn))
5658     {
5659     case TYPE_INCDEC:
5660       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5661       if (operands[2] == const1_rtx)
5662         return "inc{q}\t%0";
5663       else
5664         {
5665           gcc_assert (operands[2] == constm1_rtx);
5666           return "dec{q}\t%0";
5667         }
5668
5669     default:
5670       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5671       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5672          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5673       if (CONST_INT_P (operands[2])
5674           /* Avoid overflows.  */
5675           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5676           && (INTVAL (operands[2]) == 128
5677               || (INTVAL (operands[2]) < 0
5678                   && INTVAL (operands[2]) != -128)))
5679         {
5680           operands[2] = GEN_INT (-INTVAL (operands[2]));
5681           return "sub{q}\t{%2, %0|%0, %2}";
5682         }
5683       return "add{q}\t{%2, %0|%0, %2}";
5684     }
5685 }
5686   [(set (attr "type")
5687      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5688         (const_string "incdec")
5689         (const_string "alu")))
5690    (set_attr "mode" "DI")])
5691
5692
5693 (define_insn "*addsi_1"
5694   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5695         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5696                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5697    (clobber (reg:CC FLAGS_REG))]
5698   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5699 {
5700   switch (get_attr_type (insn))
5701     {
5702     case TYPE_LEA:
5703       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5704       return "lea{l}\t{%a2, %0|%0, %a2}";
5705
5706     case TYPE_INCDEC:
5707       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5708       if (operands[2] == const1_rtx)
5709         return "inc{l}\t%0";
5710       else
5711         {
5712           gcc_assert (operands[2] == constm1_rtx);
5713           return "dec{l}\t%0";
5714         }
5715
5716     default:
5717       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5718
5719       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5720          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5721       if (CONST_INT_P (operands[2])
5722           && (INTVAL (operands[2]) == 128
5723               || (INTVAL (operands[2]) < 0
5724                   && INTVAL (operands[2]) != -128)))
5725         {
5726           operands[2] = GEN_INT (-INTVAL (operands[2]));
5727           return "sub{l}\t{%2, %0|%0, %2}";
5728         }
5729       return "add{l}\t{%2, %0|%0, %2}";
5730     }
5731 }
5732   [(set (attr "type")
5733      (cond [(eq_attr "alternative" "2")
5734               (const_string "lea")
5735             ; Current assemblers are broken and do not allow @GOTOFF in
5736             ; ought but a memory context.
5737             (match_operand:SI 2 "pic_symbolic_operand" "")
5738               (const_string "lea")
5739             (match_operand:SI 2 "incdec_operand" "")
5740               (const_string "incdec")
5741            ]
5742            (const_string "alu")))
5743    (set_attr "mode" "SI")])
5744
5745 ;; Convert lea to the lea pattern to avoid flags dependency.
5746 (define_split
5747   [(set (match_operand 0 "register_operand" "")
5748         (plus (match_operand 1 "register_operand" "")
5749               (match_operand 2 "nonmemory_operand" "")))
5750    (clobber (reg:CC FLAGS_REG))]
5751   "reload_completed
5752    && true_regnum (operands[0]) != true_regnum (operands[1])"
5753   [(const_int 0)]
5754 {
5755   rtx pat;
5756   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5757      may confuse gen_lowpart.  */
5758   if (GET_MODE (operands[0]) != Pmode)
5759     {
5760       operands[1] = gen_lowpart (Pmode, operands[1]);
5761       operands[2] = gen_lowpart (Pmode, operands[2]);
5762     }
5763   operands[0] = gen_lowpart (SImode, operands[0]);
5764   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5765   if (Pmode != SImode)
5766     pat = gen_rtx_SUBREG (SImode, pat, 0);
5767   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5768   DONE;
5769 })
5770
5771 ;; It may seem that nonimmediate operand is proper one for operand 1.
5772 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5773 ;; we take care in ix86_binary_operator_ok to not allow two memory
5774 ;; operands so proper swapping will be done in reload.  This allow
5775 ;; patterns constructed from addsi_1 to match.
5776 (define_insn "addsi_1_zext"
5777   [(set (match_operand:DI 0 "register_operand" "=r,r")
5778         (zero_extend:DI
5779           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5780                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5781    (clobber (reg:CC FLAGS_REG))]
5782   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5783 {
5784   switch (get_attr_type (insn))
5785     {
5786     case TYPE_LEA:
5787       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5788       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5789
5790     case TYPE_INCDEC:
5791       if (operands[2] == const1_rtx)
5792         return "inc{l}\t%k0";
5793       else
5794         {
5795           gcc_assert (operands[2] == constm1_rtx);
5796           return "dec{l}\t%k0";
5797         }
5798
5799     default:
5800       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5801          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5802       if (CONST_INT_P (operands[2])
5803           && (INTVAL (operands[2]) == 128
5804               || (INTVAL (operands[2]) < 0
5805                   && INTVAL (operands[2]) != -128)))
5806         {
5807           operands[2] = GEN_INT (-INTVAL (operands[2]));
5808           return "sub{l}\t{%2, %k0|%k0, %2}";
5809         }
5810       return "add{l}\t{%2, %k0|%k0, %2}";
5811     }
5812 }
5813   [(set (attr "type")
5814      (cond [(eq_attr "alternative" "1")
5815               (const_string "lea")
5816             ; Current assemblers are broken and do not allow @GOTOFF in
5817             ; ought but a memory context.
5818             (match_operand:SI 2 "pic_symbolic_operand" "")
5819               (const_string "lea")
5820             (match_operand:SI 2 "incdec_operand" "")
5821               (const_string "incdec")
5822            ]
5823            (const_string "alu")))
5824    (set_attr "mode" "SI")])
5825
5826 ;; Convert lea to the lea pattern to avoid flags dependency.
5827 (define_split
5828   [(set (match_operand:DI 0 "register_operand" "")
5829         (zero_extend:DI
5830           (plus:SI (match_operand:SI 1 "register_operand" "")
5831                    (match_operand:SI 2 "nonmemory_operand" ""))))
5832    (clobber (reg:CC FLAGS_REG))]
5833   "TARGET_64BIT && reload_completed
5834    && true_regnum (operands[0]) != true_regnum (operands[1])"
5835   [(set (match_dup 0)
5836         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5837 {
5838   operands[1] = gen_lowpart (Pmode, operands[1]);
5839   operands[2] = gen_lowpart (Pmode, operands[2]);
5840 })
5841
5842 (define_insn "*addsi_2"
5843   [(set (reg FLAGS_REG)
5844         (compare
5845           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5846                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5847           (const_int 0)))
5848    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5849         (plus:SI (match_dup 1) (match_dup 2)))]
5850   "ix86_match_ccmode (insn, CCGOCmode)
5851    && ix86_binary_operator_ok (PLUS, SImode, operands)
5852    /* Current assemblers are broken and do not allow @GOTOFF in
5853       ought but a memory context.  */
5854    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5855 {
5856   switch (get_attr_type (insn))
5857     {
5858     case TYPE_INCDEC:
5859       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5860       if (operands[2] == const1_rtx)
5861         return "inc{l}\t%0";
5862       else
5863         {
5864           gcc_assert (operands[2] == constm1_rtx);
5865           return "dec{l}\t%0";
5866         }
5867
5868     default:
5869       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5870       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5871          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5872       if (CONST_INT_P (operands[2])
5873           && (INTVAL (operands[2]) == 128
5874               || (INTVAL (operands[2]) < 0
5875                   && INTVAL (operands[2]) != -128)))
5876         {
5877           operands[2] = GEN_INT (-INTVAL (operands[2]));
5878           return "sub{l}\t{%2, %0|%0, %2}";
5879         }
5880       return "add{l}\t{%2, %0|%0, %2}";
5881     }
5882 }
5883   [(set (attr "type")
5884      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5885         (const_string "incdec")
5886         (const_string "alu")))
5887    (set_attr "mode" "SI")])
5888
5889 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5890 (define_insn "*addsi_2_zext"
5891   [(set (reg FLAGS_REG)
5892         (compare
5893           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5894                    (match_operand:SI 2 "general_operand" "rmni"))
5895           (const_int 0)))
5896    (set (match_operand:DI 0 "register_operand" "=r")
5897         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5898   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5899    && ix86_binary_operator_ok (PLUS, SImode, operands)
5900    /* Current assemblers are broken and do not allow @GOTOFF in
5901       ought but a memory context.  */
5902    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5903 {
5904   switch (get_attr_type (insn))
5905     {
5906     case TYPE_INCDEC:
5907       if (operands[2] == const1_rtx)
5908         return "inc{l}\t%k0";
5909       else
5910         {
5911           gcc_assert (operands[2] == constm1_rtx);
5912           return "dec{l}\t%k0";
5913         }
5914
5915     default:
5916       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5917          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5918       if (CONST_INT_P (operands[2])
5919           && (INTVAL (operands[2]) == 128
5920               || (INTVAL (operands[2]) < 0
5921                   && INTVAL (operands[2]) != -128)))
5922         {
5923           operands[2] = GEN_INT (-INTVAL (operands[2]));
5924           return "sub{l}\t{%2, %k0|%k0, %2}";
5925         }
5926       return "add{l}\t{%2, %k0|%k0, %2}";
5927     }
5928 }
5929   [(set (attr "type")
5930      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5931         (const_string "incdec")
5932         (const_string "alu")))
5933    (set_attr "mode" "SI")])
5934
5935 (define_insn "*addsi_3"
5936   [(set (reg FLAGS_REG)
5937         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5938                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5939    (clobber (match_scratch:SI 0 "=r"))]
5940   "ix86_match_ccmode (insn, CCZmode)
5941    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5942    /* Current assemblers are broken and do not allow @GOTOFF in
5943       ought but a memory context.  */
5944    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5945 {
5946   switch (get_attr_type (insn))
5947     {
5948     case TYPE_INCDEC:
5949       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5950       if (operands[2] == const1_rtx)
5951         return "inc{l}\t%0";
5952       else
5953         {
5954           gcc_assert (operands[2] == constm1_rtx);
5955           return "dec{l}\t%0";
5956         }
5957
5958     default:
5959       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5960       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5961          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5962       if (CONST_INT_P (operands[2])
5963           && (INTVAL (operands[2]) == 128
5964               || (INTVAL (operands[2]) < 0
5965                   && INTVAL (operands[2]) != -128)))
5966         {
5967           operands[2] = GEN_INT (-INTVAL (operands[2]));
5968           return "sub{l}\t{%2, %0|%0, %2}";
5969         }
5970       return "add{l}\t{%2, %0|%0, %2}";
5971     }
5972 }
5973   [(set (attr "type")
5974      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5975         (const_string "incdec")
5976         (const_string "alu")))
5977    (set_attr "mode" "SI")])
5978
5979 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5980 (define_insn "*addsi_3_zext"
5981   [(set (reg FLAGS_REG)
5982         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5983                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5984    (set (match_operand:DI 0 "register_operand" "=r")
5985         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5986   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5987    && ix86_binary_operator_ok (PLUS, SImode, operands)
5988    /* Current assemblers are broken and do not allow @GOTOFF in
5989       ought but a memory context.  */
5990    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5991 {
5992   switch (get_attr_type (insn))
5993     {
5994     case TYPE_INCDEC:
5995       if (operands[2] == const1_rtx)
5996         return "inc{l}\t%k0";
5997       else
5998         {
5999           gcc_assert (operands[2] == constm1_rtx);
6000           return "dec{l}\t%k0";
6001         }
6002
6003     default:
6004       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6005          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6006       if (CONST_INT_P (operands[2])
6007           && (INTVAL (operands[2]) == 128
6008               || (INTVAL (operands[2]) < 0
6009                   && INTVAL (operands[2]) != -128)))
6010         {
6011           operands[2] = GEN_INT (-INTVAL (operands[2]));
6012           return "sub{l}\t{%2, %k0|%k0, %2}";
6013         }
6014       return "add{l}\t{%2, %k0|%k0, %2}";
6015     }
6016 }
6017   [(set (attr "type")
6018      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6019         (const_string "incdec")
6020         (const_string "alu")))
6021    (set_attr "mode" "SI")])
6022
6023 ; For comparisons against 1, -1 and 128, we may generate better code
6024 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6025 ; is matched then.  We can't accept general immediate, because for
6026 ; case of overflows,  the result is messed up.
6027 ; This pattern also don't hold of 0x80000000, since the value overflows
6028 ; when negated.
6029 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6030 ; only for comparisons not depending on it.
6031 (define_insn "*addsi_4"
6032   [(set (reg FLAGS_REG)
6033         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6034                  (match_operand:SI 2 "const_int_operand" "n")))
6035    (clobber (match_scratch:SI 0 "=rm"))]
6036   "ix86_match_ccmode (insn, CCGCmode)
6037    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6038 {
6039   switch (get_attr_type (insn))
6040     {
6041     case TYPE_INCDEC:
6042       if (operands[2] == constm1_rtx)
6043         return "inc{l}\t%0";
6044       else
6045         {
6046           gcc_assert (operands[2] == const1_rtx);
6047           return "dec{l}\t%0";
6048         }
6049
6050     default:
6051       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6052       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6053          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6054       if ((INTVAL (operands[2]) == -128
6055            || (INTVAL (operands[2]) > 0
6056                && INTVAL (operands[2]) != 128)))
6057         return "sub{l}\t{%2, %0|%0, %2}";
6058       operands[2] = GEN_INT (-INTVAL (operands[2]));
6059       return "add{l}\t{%2, %0|%0, %2}";
6060     }
6061 }
6062   [(set (attr "type")
6063      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6064         (const_string "incdec")
6065         (const_string "alu")))
6066    (set_attr "mode" "SI")])
6067
6068 (define_insn "*addsi_5"
6069   [(set (reg FLAGS_REG)
6070         (compare
6071           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6072                    (match_operand:SI 2 "general_operand" "rmni"))
6073           (const_int 0)))
6074    (clobber (match_scratch:SI 0 "=r"))]
6075   "ix86_match_ccmode (insn, CCGOCmode)
6076    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6077    /* Current assemblers are broken and do not allow @GOTOFF in
6078       ought but a memory context.  */
6079    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6080 {
6081   switch (get_attr_type (insn))
6082     {
6083     case TYPE_INCDEC:
6084       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6085       if (operands[2] == const1_rtx)
6086         return "inc{l}\t%0";
6087       else
6088         {
6089           gcc_assert (operands[2] == constm1_rtx);
6090           return "dec{l}\t%0";
6091         }
6092
6093     default:
6094       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6095       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6096          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6097       if (CONST_INT_P (operands[2])
6098           && (INTVAL (operands[2]) == 128
6099               || (INTVAL (operands[2]) < 0
6100                   && INTVAL (operands[2]) != -128)))
6101         {
6102           operands[2] = GEN_INT (-INTVAL (operands[2]));
6103           return "sub{l}\t{%2, %0|%0, %2}";
6104         }
6105       return "add{l}\t{%2, %0|%0, %2}";
6106     }
6107 }
6108   [(set (attr "type")
6109      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6110         (const_string "incdec")
6111         (const_string "alu")))
6112    (set_attr "mode" "SI")])
6113
6114 (define_expand "addhi3"
6115   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6116                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6117                             (match_operand:HI 2 "general_operand" "")))
6118               (clobber (reg:CC FLAGS_REG))])]
6119   "TARGET_HIMODE_MATH"
6120   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6121
6122 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6123 ;; type optimizations enabled by define-splits.  This is not important
6124 ;; for PII, and in fact harmful because of partial register stalls.
6125
6126 (define_insn "*addhi_1_lea"
6127   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6128         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6129                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6130    (clobber (reg:CC FLAGS_REG))]
6131   "!TARGET_PARTIAL_REG_STALL
6132    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6133 {
6134   switch (get_attr_type (insn))
6135     {
6136     case TYPE_LEA:
6137       return "#";
6138     case TYPE_INCDEC:
6139       if (operands[2] == const1_rtx)
6140         return "inc{w}\t%0";
6141       else
6142         {
6143           gcc_assert (operands[2] == constm1_rtx);
6144           return "dec{w}\t%0";
6145         }
6146
6147     default:
6148       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6149          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6150       if (CONST_INT_P (operands[2])
6151           && (INTVAL (operands[2]) == 128
6152               || (INTVAL (operands[2]) < 0
6153                   && INTVAL (operands[2]) != -128)))
6154         {
6155           operands[2] = GEN_INT (-INTVAL (operands[2]));
6156           return "sub{w}\t{%2, %0|%0, %2}";
6157         }
6158       return "add{w}\t{%2, %0|%0, %2}";
6159     }
6160 }
6161   [(set (attr "type")
6162      (if_then_else (eq_attr "alternative" "2")
6163         (const_string "lea")
6164         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6165            (const_string "incdec")
6166            (const_string "alu"))))
6167    (set_attr "mode" "HI,HI,SI")])
6168
6169 (define_insn "*addhi_1"
6170   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6171         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6172                  (match_operand:HI 2 "general_operand" "ri,rm")))
6173    (clobber (reg:CC FLAGS_REG))]
6174   "TARGET_PARTIAL_REG_STALL
6175    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6176 {
6177   switch (get_attr_type (insn))
6178     {
6179     case TYPE_INCDEC:
6180       if (operands[2] == const1_rtx)
6181         return "inc{w}\t%0";
6182       else
6183         {
6184           gcc_assert (operands[2] == constm1_rtx);
6185           return "dec{w}\t%0";
6186         }
6187
6188     default:
6189       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6190          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6191       if (CONST_INT_P (operands[2])
6192           && (INTVAL (operands[2]) == 128
6193               || (INTVAL (operands[2]) < 0
6194                   && INTVAL (operands[2]) != -128)))
6195         {
6196           operands[2] = GEN_INT (-INTVAL (operands[2]));
6197           return "sub{w}\t{%2, %0|%0, %2}";
6198         }
6199       return "add{w}\t{%2, %0|%0, %2}";
6200     }
6201 }
6202   [(set (attr "type")
6203      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6204         (const_string "incdec")
6205         (const_string "alu")))
6206    (set_attr "mode" "HI")])
6207
6208 (define_insn "*addhi_2"
6209   [(set (reg FLAGS_REG)
6210         (compare
6211           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6212                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6213           (const_int 0)))
6214    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6215         (plus:HI (match_dup 1) (match_dup 2)))]
6216   "ix86_match_ccmode (insn, CCGOCmode)
6217    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6218 {
6219   switch (get_attr_type (insn))
6220     {
6221     case TYPE_INCDEC:
6222       if (operands[2] == const1_rtx)
6223         return "inc{w}\t%0";
6224       else
6225         {
6226           gcc_assert (operands[2] == constm1_rtx);
6227           return "dec{w}\t%0";
6228         }
6229
6230     default:
6231       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6232          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6233       if (CONST_INT_P (operands[2])
6234           && (INTVAL (operands[2]) == 128
6235               || (INTVAL (operands[2]) < 0
6236                   && INTVAL (operands[2]) != -128)))
6237         {
6238           operands[2] = GEN_INT (-INTVAL (operands[2]));
6239           return "sub{w}\t{%2, %0|%0, %2}";
6240         }
6241       return "add{w}\t{%2, %0|%0, %2}";
6242     }
6243 }
6244   [(set (attr "type")
6245      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6246         (const_string "incdec")
6247         (const_string "alu")))
6248    (set_attr "mode" "HI")])
6249
6250 (define_insn "*addhi_3"
6251   [(set (reg FLAGS_REG)
6252         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6253                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6254    (clobber (match_scratch:HI 0 "=r"))]
6255   "ix86_match_ccmode (insn, CCZmode)
6256    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6257 {
6258   switch (get_attr_type (insn))
6259     {
6260     case TYPE_INCDEC:
6261       if (operands[2] == const1_rtx)
6262         return "inc{w}\t%0";
6263       else
6264         {
6265           gcc_assert (operands[2] == constm1_rtx);
6266           return "dec{w}\t%0";
6267         }
6268
6269     default:
6270       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6271          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6272       if (CONST_INT_P (operands[2])
6273           && (INTVAL (operands[2]) == 128
6274               || (INTVAL (operands[2]) < 0
6275                   && INTVAL (operands[2]) != -128)))
6276         {
6277           operands[2] = GEN_INT (-INTVAL (operands[2]));
6278           return "sub{w}\t{%2, %0|%0, %2}";
6279         }
6280       return "add{w}\t{%2, %0|%0, %2}";
6281     }
6282 }
6283   [(set (attr "type")
6284      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6285         (const_string "incdec")
6286         (const_string "alu")))
6287    (set_attr "mode" "HI")])
6288
6289 ; See comments above addsi_4 for details.
6290 (define_insn "*addhi_4"
6291   [(set (reg FLAGS_REG)
6292         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6293                  (match_operand:HI 2 "const_int_operand" "n")))
6294    (clobber (match_scratch:HI 0 "=rm"))]
6295   "ix86_match_ccmode (insn, CCGCmode)
6296    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6297 {
6298   switch (get_attr_type (insn))
6299     {
6300     case TYPE_INCDEC:
6301       if (operands[2] == constm1_rtx)
6302         return "inc{w}\t%0";
6303       else
6304         {
6305           gcc_assert (operands[2] == const1_rtx);
6306           return "dec{w}\t%0";
6307         }
6308
6309     default:
6310       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6311       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6312          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6313       if ((INTVAL (operands[2]) == -128
6314            || (INTVAL (operands[2]) > 0
6315                && INTVAL (operands[2]) != 128)))
6316         return "sub{w}\t{%2, %0|%0, %2}";
6317       operands[2] = GEN_INT (-INTVAL (operands[2]));
6318       return "add{w}\t{%2, %0|%0, %2}";
6319     }
6320 }
6321   [(set (attr "type")
6322      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6323         (const_string "incdec")
6324         (const_string "alu")))
6325    (set_attr "mode" "SI")])
6326
6327
6328 (define_insn "*addhi_5"
6329   [(set (reg FLAGS_REG)
6330         (compare
6331           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6332                    (match_operand:HI 2 "general_operand" "rmni"))
6333           (const_int 0)))
6334    (clobber (match_scratch:HI 0 "=r"))]
6335   "ix86_match_ccmode (insn, CCGOCmode)
6336    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6337 {
6338   switch (get_attr_type (insn))
6339     {
6340     case TYPE_INCDEC:
6341       if (operands[2] == const1_rtx)
6342         return "inc{w}\t%0";
6343       else
6344         {
6345           gcc_assert (operands[2] == constm1_rtx);
6346           return "dec{w}\t%0";
6347         }
6348
6349     default:
6350       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6351          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6352       if (CONST_INT_P (operands[2])
6353           && (INTVAL (operands[2]) == 128
6354               || (INTVAL (operands[2]) < 0
6355                   && INTVAL (operands[2]) != -128)))
6356         {
6357           operands[2] = GEN_INT (-INTVAL (operands[2]));
6358           return "sub{w}\t{%2, %0|%0, %2}";
6359         }
6360       return "add{w}\t{%2, %0|%0, %2}";
6361     }
6362 }
6363   [(set (attr "type")
6364      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6365         (const_string "incdec")
6366         (const_string "alu")))
6367    (set_attr "mode" "HI")])
6368
6369 (define_expand "addqi3"
6370   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6371                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6372                             (match_operand:QI 2 "general_operand" "")))
6373               (clobber (reg:CC FLAGS_REG))])]
6374   "TARGET_QIMODE_MATH"
6375   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6376
6377 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6378 (define_insn "*addqi_1_lea"
6379   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6380         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6381                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6382    (clobber (reg:CC FLAGS_REG))]
6383   "!TARGET_PARTIAL_REG_STALL
6384    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6385 {
6386   int widen = (which_alternative == 2);
6387   switch (get_attr_type (insn))
6388     {
6389     case TYPE_LEA:
6390       return "#";
6391     case TYPE_INCDEC:
6392       if (operands[2] == const1_rtx)
6393         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6394       else
6395         {
6396           gcc_assert (operands[2] == constm1_rtx);
6397           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6398         }
6399
6400     default:
6401       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6402          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6403       if (CONST_INT_P (operands[2])
6404           && (INTVAL (operands[2]) == 128
6405               || (INTVAL (operands[2]) < 0
6406                   && INTVAL (operands[2]) != -128)))
6407         {
6408           operands[2] = GEN_INT (-INTVAL (operands[2]));
6409           if (widen)
6410             return "sub{l}\t{%2, %k0|%k0, %2}";
6411           else
6412             return "sub{b}\t{%2, %0|%0, %2}";
6413         }
6414       if (widen)
6415         return "add{l}\t{%k2, %k0|%k0, %k2}";
6416       else
6417         return "add{b}\t{%2, %0|%0, %2}";
6418     }
6419 }
6420   [(set (attr "type")
6421      (if_then_else (eq_attr "alternative" "3")
6422         (const_string "lea")
6423         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6424            (const_string "incdec")
6425            (const_string "alu"))))
6426    (set_attr "mode" "QI,QI,SI,SI")])
6427
6428 (define_insn "*addqi_1"
6429   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6430         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6431                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6432    (clobber (reg:CC FLAGS_REG))]
6433   "TARGET_PARTIAL_REG_STALL
6434    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6435 {
6436   int widen = (which_alternative == 2);
6437   switch (get_attr_type (insn))
6438     {
6439     case TYPE_INCDEC:
6440       if (operands[2] == const1_rtx)
6441         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6442       else
6443         {
6444           gcc_assert (operands[2] == constm1_rtx);
6445           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6446         }
6447
6448     default:
6449       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6450          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6451       if (CONST_INT_P (operands[2])
6452           && (INTVAL (operands[2]) == 128
6453               || (INTVAL (operands[2]) < 0
6454                   && INTVAL (operands[2]) != -128)))
6455         {
6456           operands[2] = GEN_INT (-INTVAL (operands[2]));
6457           if (widen)
6458             return "sub{l}\t{%2, %k0|%k0, %2}";
6459           else
6460             return "sub{b}\t{%2, %0|%0, %2}";
6461         }
6462       if (widen)
6463         return "add{l}\t{%k2, %k0|%k0, %k2}";
6464       else
6465         return "add{b}\t{%2, %0|%0, %2}";
6466     }
6467 }
6468   [(set (attr "type")
6469      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6470         (const_string "incdec")
6471         (const_string "alu")))
6472    (set_attr "mode" "QI,QI,SI")])
6473
6474 (define_insn "*addqi_1_slp"
6475   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6476         (plus:QI (match_dup 0)
6477                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6478    (clobber (reg:CC FLAGS_REG))]
6479   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6480    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6481 {
6482   switch (get_attr_type (insn))
6483     {
6484     case TYPE_INCDEC:
6485       if (operands[1] == const1_rtx)
6486         return "inc{b}\t%0";
6487       else
6488         {
6489           gcc_assert (operands[1] == constm1_rtx);
6490           return "dec{b}\t%0";
6491         }
6492
6493     default:
6494       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6495       if (CONST_INT_P (operands[1])
6496           && INTVAL (operands[1]) < 0)
6497         {
6498           operands[1] = GEN_INT (-INTVAL (operands[1]));
6499           return "sub{b}\t{%1, %0|%0, %1}";
6500         }
6501       return "add{b}\t{%1, %0|%0, %1}";
6502     }
6503 }
6504   [(set (attr "type")
6505      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6506         (const_string "incdec")
6507         (const_string "alu1")))
6508    (set (attr "memory")
6509      (if_then_else (match_operand 1 "memory_operand" "")
6510         (const_string "load")
6511         (const_string "none")))
6512    (set_attr "mode" "QI")])
6513
6514 (define_insn "*addqi_2"
6515   [(set (reg FLAGS_REG)
6516         (compare
6517           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6518                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6519           (const_int 0)))
6520    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6521         (plus:QI (match_dup 1) (match_dup 2)))]
6522   "ix86_match_ccmode (insn, CCGOCmode)
6523    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6524 {
6525   switch (get_attr_type (insn))
6526     {
6527     case TYPE_INCDEC:
6528       if (operands[2] == const1_rtx)
6529         return "inc{b}\t%0";
6530       else
6531         {
6532           gcc_assert (operands[2] == constm1_rtx
6533                       || (CONST_INT_P (operands[2])
6534                           && INTVAL (operands[2]) == 255));
6535           return "dec{b}\t%0";
6536         }
6537
6538     default:
6539       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6540       if (CONST_INT_P (operands[2])
6541           && INTVAL (operands[2]) < 0)
6542         {
6543           operands[2] = GEN_INT (-INTVAL (operands[2]));
6544           return "sub{b}\t{%2, %0|%0, %2}";
6545         }
6546       return "add{b}\t{%2, %0|%0, %2}";
6547     }
6548 }
6549   [(set (attr "type")
6550      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6551         (const_string "incdec")
6552         (const_string "alu")))
6553    (set_attr "mode" "QI")])
6554
6555 (define_insn "*addqi_3"
6556   [(set (reg FLAGS_REG)
6557         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6558                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6559    (clobber (match_scratch:QI 0 "=q"))]
6560   "ix86_match_ccmode (insn, CCZmode)
6561    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6562 {
6563   switch (get_attr_type (insn))
6564     {
6565     case TYPE_INCDEC:
6566       if (operands[2] == const1_rtx)
6567         return "inc{b}\t%0";
6568       else
6569         {
6570           gcc_assert (operands[2] == constm1_rtx
6571                       || (CONST_INT_P (operands[2])
6572                           && INTVAL (operands[2]) == 255));
6573           return "dec{b}\t%0";
6574         }
6575
6576     default:
6577       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6578       if (CONST_INT_P (operands[2])
6579           && INTVAL (operands[2]) < 0)
6580         {
6581           operands[2] = GEN_INT (-INTVAL (operands[2]));
6582           return "sub{b}\t{%2, %0|%0, %2}";
6583         }
6584       return "add{b}\t{%2, %0|%0, %2}";
6585     }
6586 }
6587   [(set (attr "type")
6588      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6589         (const_string "incdec")
6590         (const_string "alu")))
6591    (set_attr "mode" "QI")])
6592
6593 ; See comments above addsi_4 for details.
6594 (define_insn "*addqi_4"
6595   [(set (reg FLAGS_REG)
6596         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6597                  (match_operand:QI 2 "const_int_operand" "n")))
6598    (clobber (match_scratch:QI 0 "=qm"))]
6599   "ix86_match_ccmode (insn, CCGCmode)
6600    && (INTVAL (operands[2]) & 0xff) != 0x80"
6601 {
6602   switch (get_attr_type (insn))
6603     {
6604     case TYPE_INCDEC:
6605       if (operands[2] == constm1_rtx
6606           || (CONST_INT_P (operands[2])
6607               && INTVAL (operands[2]) == 255))
6608         return "inc{b}\t%0";
6609       else
6610         {
6611           gcc_assert (operands[2] == const1_rtx);
6612           return "dec{b}\t%0";
6613         }
6614
6615     default:
6616       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6617       if (INTVAL (operands[2]) < 0)
6618         {
6619           operands[2] = GEN_INT (-INTVAL (operands[2]));
6620           return "add{b}\t{%2, %0|%0, %2}";
6621         }
6622       return "sub{b}\t{%2, %0|%0, %2}";
6623     }
6624 }
6625   [(set (attr "type")
6626      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6627         (const_string "incdec")
6628         (const_string "alu")))
6629    (set_attr "mode" "QI")])
6630
6631
6632 (define_insn "*addqi_5"
6633   [(set (reg FLAGS_REG)
6634         (compare
6635           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6636                    (match_operand:QI 2 "general_operand" "qmni"))
6637           (const_int 0)))
6638    (clobber (match_scratch:QI 0 "=q"))]
6639   "ix86_match_ccmode (insn, CCGOCmode)
6640    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6641 {
6642   switch (get_attr_type (insn))
6643     {
6644     case TYPE_INCDEC:
6645       if (operands[2] == const1_rtx)
6646         return "inc{b}\t%0";
6647       else
6648         {
6649           gcc_assert (operands[2] == constm1_rtx
6650                       || (CONST_INT_P (operands[2])
6651                           && INTVAL (operands[2]) == 255));
6652           return "dec{b}\t%0";
6653         }
6654
6655     default:
6656       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6657       if (CONST_INT_P (operands[2])
6658           && INTVAL (operands[2]) < 0)
6659         {
6660           operands[2] = GEN_INT (-INTVAL (operands[2]));
6661           return "sub{b}\t{%2, %0|%0, %2}";
6662         }
6663       return "add{b}\t{%2, %0|%0, %2}";
6664     }
6665 }
6666   [(set (attr "type")
6667      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6668         (const_string "incdec")
6669         (const_string "alu")))
6670    (set_attr "mode" "QI")])
6671
6672
6673 (define_insn "addqi_ext_1"
6674   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6675                          (const_int 8)
6676                          (const_int 8))
6677         (plus:SI
6678           (zero_extract:SI
6679             (match_operand 1 "ext_register_operand" "0")
6680             (const_int 8)
6681             (const_int 8))
6682           (match_operand:QI 2 "general_operand" "Qmn")))
6683    (clobber (reg:CC FLAGS_REG))]
6684   "!TARGET_64BIT"
6685 {
6686   switch (get_attr_type (insn))
6687     {
6688     case TYPE_INCDEC:
6689       if (operands[2] == const1_rtx)
6690         return "inc{b}\t%h0";
6691       else
6692         {
6693           gcc_assert (operands[2] == constm1_rtx
6694                       || (CONST_INT_P (operands[2])
6695                           && INTVAL (operands[2]) == 255));
6696           return "dec{b}\t%h0";
6697         }
6698
6699     default:
6700       return "add{b}\t{%2, %h0|%h0, %2}";
6701     }
6702 }
6703   [(set (attr "type")
6704      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6705         (const_string "incdec")
6706         (const_string "alu")))
6707    (set_attr "mode" "QI")])
6708
6709 (define_insn "*addqi_ext_1_rex64"
6710   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6711                          (const_int 8)
6712                          (const_int 8))
6713         (plus:SI
6714           (zero_extract:SI
6715             (match_operand 1 "ext_register_operand" "0")
6716             (const_int 8)
6717             (const_int 8))
6718           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6719    (clobber (reg:CC FLAGS_REG))]
6720   "TARGET_64BIT"
6721 {
6722   switch (get_attr_type (insn))
6723     {
6724     case TYPE_INCDEC:
6725       if (operands[2] == const1_rtx)
6726         return "inc{b}\t%h0";
6727       else
6728         {
6729           gcc_assert (operands[2] == constm1_rtx
6730                       || (CONST_INT_P (operands[2])
6731                           && INTVAL (operands[2]) == 255));
6732           return "dec{b}\t%h0";
6733         }
6734
6735     default:
6736       return "add{b}\t{%2, %h0|%h0, %2}";
6737     }
6738 }
6739   [(set (attr "type")
6740      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6741         (const_string "incdec")
6742         (const_string "alu")))
6743    (set_attr "mode" "QI")])
6744
6745 (define_insn "*addqi_ext_2"
6746   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6747                          (const_int 8)
6748                          (const_int 8))
6749         (plus:SI
6750           (zero_extract:SI
6751             (match_operand 1 "ext_register_operand" "%0")
6752             (const_int 8)
6753             (const_int 8))
6754           (zero_extract:SI
6755             (match_operand 2 "ext_register_operand" "Q")
6756             (const_int 8)
6757             (const_int 8))))
6758    (clobber (reg:CC FLAGS_REG))]
6759   ""
6760   "add{b}\t{%h2, %h0|%h0, %h2}"
6761   [(set_attr "type" "alu")
6762    (set_attr "mode" "QI")])
6763
6764 ;; The patterns that match these are at the end of this file.
6765
6766 (define_expand "addxf3"
6767   [(set (match_operand:XF 0 "register_operand" "")
6768         (plus:XF (match_operand:XF 1 "register_operand" "")
6769                  (match_operand:XF 2 "register_operand" "")))]
6770   "TARGET_80387"
6771   "")
6772
6773 (define_expand "adddf3"
6774   [(set (match_operand:DF 0 "register_operand" "")
6775         (plus:DF (match_operand:DF 1 "register_operand" "")
6776                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6777   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6778   "")
6779
6780 (define_expand "addsf3"
6781   [(set (match_operand:SF 0 "register_operand" "")
6782         (plus:SF (match_operand:SF 1 "register_operand" "")
6783                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6784   "TARGET_80387 || TARGET_SSE_MATH"
6785   "")
6786 \f
6787 ;; Subtract instructions
6788
6789 ;; %%% splits for subditi3
6790
6791 (define_expand "subti3"
6792   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6793                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6794                              (match_operand:TI 2 "x86_64_general_operand" "")))
6795               (clobber (reg:CC FLAGS_REG))])]
6796   "TARGET_64BIT"
6797   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6798
6799 (define_insn "*subti3_1"
6800   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6801         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6802                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6803    (clobber (reg:CC FLAGS_REG))]
6804   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6805   "#")
6806
6807 (define_split
6808   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6809         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6810                   (match_operand:TI 2 "general_operand" "")))
6811    (clobber (reg:CC FLAGS_REG))]
6812   "TARGET_64BIT && reload_completed"
6813   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6814               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6815    (parallel [(set (match_dup 3)
6816                    (minus:DI (match_dup 4)
6817                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6818                                       (match_dup 5))))
6819               (clobber (reg:CC FLAGS_REG))])]
6820   "split_ti (operands+0, 1, operands+0, operands+3);
6821    split_ti (operands+1, 1, operands+1, operands+4);
6822    split_ti (operands+2, 1, operands+2, operands+5);")
6823
6824 ;; %%% splits for subsidi3
6825
6826 (define_expand "subdi3"
6827   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6828                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6829                              (match_operand:DI 2 "x86_64_general_operand" "")))
6830               (clobber (reg:CC FLAGS_REG))])]
6831   ""
6832   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6833
6834 (define_insn "*subdi3_1"
6835   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6836         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6837                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6838    (clobber (reg:CC FLAGS_REG))]
6839   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6840   "#")
6841
6842 (define_split
6843   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6844         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6845                   (match_operand:DI 2 "general_operand" "")))
6846    (clobber (reg:CC FLAGS_REG))]
6847   "!TARGET_64BIT && reload_completed"
6848   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6849               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6850    (parallel [(set (match_dup 3)
6851                    (minus:SI (match_dup 4)
6852                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6853                                       (match_dup 5))))
6854               (clobber (reg:CC FLAGS_REG))])]
6855   "split_di (operands+0, 1, operands+0, operands+3);
6856    split_di (operands+1, 1, operands+1, operands+4);
6857    split_di (operands+2, 1, operands+2, operands+5);")
6858
6859 (define_insn "subdi3_carry_rex64"
6860   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6861           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6862             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6863                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6864    (clobber (reg:CC FLAGS_REG))]
6865   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6866   "sbb{q}\t{%2, %0|%0, %2}"
6867   [(set_attr "type" "alu")
6868    (set_attr "pent_pair" "pu")
6869    (set_attr "mode" "DI")])
6870
6871 (define_insn "*subdi_1_rex64"
6872   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6873         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6874                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6875    (clobber (reg:CC FLAGS_REG))]
6876   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6877   "sub{q}\t{%2, %0|%0, %2}"
6878   [(set_attr "type" "alu")
6879    (set_attr "mode" "DI")])
6880
6881 (define_insn "*subdi_2_rex64"
6882   [(set (reg FLAGS_REG)
6883         (compare
6884           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6885                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6886           (const_int 0)))
6887    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6888         (minus:DI (match_dup 1) (match_dup 2)))]
6889   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6890    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6891   "sub{q}\t{%2, %0|%0, %2}"
6892   [(set_attr "type" "alu")
6893    (set_attr "mode" "DI")])
6894
6895 (define_insn "*subdi_3_rex63"
6896   [(set (reg FLAGS_REG)
6897         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6898                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6899    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6900         (minus:DI (match_dup 1) (match_dup 2)))]
6901   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6902    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6903   "sub{q}\t{%2, %0|%0, %2}"
6904   [(set_attr "type" "alu")
6905    (set_attr "mode" "DI")])
6906
6907 (define_insn "subqi3_carry"
6908   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6909           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6910             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6911                (match_operand:QI 2 "general_operand" "qi,qm"))))
6912    (clobber (reg:CC FLAGS_REG))]
6913   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6914   "sbb{b}\t{%2, %0|%0, %2}"
6915   [(set_attr "type" "alu")
6916    (set_attr "pent_pair" "pu")
6917    (set_attr "mode" "QI")])
6918
6919 (define_insn "subhi3_carry"
6920   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6921           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6922             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6923                (match_operand:HI 2 "general_operand" "ri,rm"))))
6924    (clobber (reg:CC FLAGS_REG))]
6925   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6926   "sbb{w}\t{%2, %0|%0, %2}"
6927   [(set_attr "type" "alu")
6928    (set_attr "pent_pair" "pu")
6929    (set_attr "mode" "HI")])
6930
6931 (define_insn "subsi3_carry"
6932   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6933           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6934             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6935                (match_operand:SI 2 "general_operand" "ri,rm"))))
6936    (clobber (reg:CC FLAGS_REG))]
6937   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6938   "sbb{l}\t{%2, %0|%0, %2}"
6939   [(set_attr "type" "alu")
6940    (set_attr "pent_pair" "pu")
6941    (set_attr "mode" "SI")])
6942
6943 (define_insn "subsi3_carry_zext"
6944   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6945           (zero_extend:DI
6946             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6947               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6948                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6949    (clobber (reg:CC FLAGS_REG))]
6950   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6951   "sbb{l}\t{%2, %k0|%k0, %2}"
6952   [(set_attr "type" "alu")
6953    (set_attr "pent_pair" "pu")
6954    (set_attr "mode" "SI")])
6955
6956 (define_expand "subsi3"
6957   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6958                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6959                              (match_operand:SI 2 "general_operand" "")))
6960               (clobber (reg:CC FLAGS_REG))])]
6961   ""
6962   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6963
6964 (define_insn "*subsi_1"
6965   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6966         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6967                   (match_operand:SI 2 "general_operand" "ri,rm")))
6968    (clobber (reg:CC FLAGS_REG))]
6969   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6970   "sub{l}\t{%2, %0|%0, %2}"
6971   [(set_attr "type" "alu")
6972    (set_attr "mode" "SI")])
6973
6974 (define_insn "*subsi_1_zext"
6975   [(set (match_operand:DI 0 "register_operand" "=r")
6976         (zero_extend:DI
6977           (minus:SI (match_operand:SI 1 "register_operand" "0")
6978                     (match_operand:SI 2 "general_operand" "rim"))))
6979    (clobber (reg:CC FLAGS_REG))]
6980   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6981   "sub{l}\t{%2, %k0|%k0, %2}"
6982   [(set_attr "type" "alu")
6983    (set_attr "mode" "SI")])
6984
6985 (define_insn "*subsi_2"
6986   [(set (reg FLAGS_REG)
6987         (compare
6988           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6989                     (match_operand:SI 2 "general_operand" "ri,rm"))
6990           (const_int 0)))
6991    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6992         (minus:SI (match_dup 1) (match_dup 2)))]
6993   "ix86_match_ccmode (insn, CCGOCmode)
6994    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6995   "sub{l}\t{%2, %0|%0, %2}"
6996   [(set_attr "type" "alu")
6997    (set_attr "mode" "SI")])
6998
6999 (define_insn "*subsi_2_zext"
7000   [(set (reg FLAGS_REG)
7001         (compare
7002           (minus:SI (match_operand:SI 1 "register_operand" "0")
7003                     (match_operand:SI 2 "general_operand" "rim"))
7004           (const_int 0)))
7005    (set (match_operand:DI 0 "register_operand" "=r")
7006         (zero_extend:DI
7007           (minus:SI (match_dup 1)
7008                     (match_dup 2))))]
7009   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7010    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7011   "sub{l}\t{%2, %k0|%k0, %2}"
7012   [(set_attr "type" "alu")
7013    (set_attr "mode" "SI")])
7014
7015 (define_insn "*subsi_3"
7016   [(set (reg FLAGS_REG)
7017         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7018                  (match_operand:SI 2 "general_operand" "ri,rm")))
7019    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7020         (minus:SI (match_dup 1) (match_dup 2)))]
7021   "ix86_match_ccmode (insn, CCmode)
7022    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7023   "sub{l}\t{%2, %0|%0, %2}"
7024   [(set_attr "type" "alu")
7025    (set_attr "mode" "SI")])
7026
7027 (define_insn "*subsi_3_zext"
7028   [(set (reg FLAGS_REG)
7029         (compare (match_operand:SI 1 "register_operand" "0")
7030                  (match_operand:SI 2 "general_operand" "rim")))
7031    (set (match_operand:DI 0 "register_operand" "=r")
7032         (zero_extend:DI
7033           (minus:SI (match_dup 1)
7034                     (match_dup 2))))]
7035   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7036    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7037   "sub{l}\t{%2, %1|%1, %2}"
7038   [(set_attr "type" "alu")
7039    (set_attr "mode" "DI")])
7040
7041 (define_expand "subhi3"
7042   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7043                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7044                              (match_operand:HI 2 "general_operand" "")))
7045               (clobber (reg:CC FLAGS_REG))])]
7046   "TARGET_HIMODE_MATH"
7047   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7048
7049 (define_insn "*subhi_1"
7050   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7051         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7052                   (match_operand:HI 2 "general_operand" "ri,rm")))
7053    (clobber (reg:CC FLAGS_REG))]
7054   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7055   "sub{w}\t{%2, %0|%0, %2}"
7056   [(set_attr "type" "alu")
7057    (set_attr "mode" "HI")])
7058
7059 (define_insn "*subhi_2"
7060   [(set (reg FLAGS_REG)
7061         (compare
7062           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7063                     (match_operand:HI 2 "general_operand" "ri,rm"))
7064           (const_int 0)))
7065    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7066         (minus:HI (match_dup 1) (match_dup 2)))]
7067   "ix86_match_ccmode (insn, CCGOCmode)
7068    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7069   "sub{w}\t{%2, %0|%0, %2}"
7070   [(set_attr "type" "alu")
7071    (set_attr "mode" "HI")])
7072
7073 (define_insn "*subhi_3"
7074   [(set (reg FLAGS_REG)
7075         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7076                  (match_operand:HI 2 "general_operand" "ri,rm")))
7077    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7078         (minus:HI (match_dup 1) (match_dup 2)))]
7079   "ix86_match_ccmode (insn, CCmode)
7080    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7081   "sub{w}\t{%2, %0|%0, %2}"
7082   [(set_attr "type" "alu")
7083    (set_attr "mode" "HI")])
7084
7085 (define_expand "subqi3"
7086   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7087                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7088                              (match_operand:QI 2 "general_operand" "")))
7089               (clobber (reg:CC FLAGS_REG))])]
7090   "TARGET_QIMODE_MATH"
7091   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7092
7093 (define_insn "*subqi_1"
7094   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7095         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7096                   (match_operand:QI 2 "general_operand" "qn,qmn")))
7097    (clobber (reg:CC FLAGS_REG))]
7098   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7099   "sub{b}\t{%2, %0|%0, %2}"
7100   [(set_attr "type" "alu")
7101    (set_attr "mode" "QI")])
7102
7103 (define_insn "*subqi_1_slp"
7104   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7105         (minus:QI (match_dup 0)
7106                   (match_operand:QI 1 "general_operand" "qn,qmn")))
7107    (clobber (reg:CC FLAGS_REG))]
7108   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7109    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7110   "sub{b}\t{%1, %0|%0, %1}"
7111   [(set_attr "type" "alu1")
7112    (set_attr "mode" "QI")])
7113
7114 (define_insn "*subqi_2"
7115   [(set (reg FLAGS_REG)
7116         (compare
7117           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7118                     (match_operand:QI 2 "general_operand" "qi,qm"))
7119           (const_int 0)))
7120    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7121         (minus:HI (match_dup 1) (match_dup 2)))]
7122   "ix86_match_ccmode (insn, CCGOCmode)
7123    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7124   "sub{b}\t{%2, %0|%0, %2}"
7125   [(set_attr "type" "alu")
7126    (set_attr "mode" "QI")])
7127
7128 (define_insn "*subqi_3"
7129   [(set (reg FLAGS_REG)
7130         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7131                  (match_operand:QI 2 "general_operand" "qi,qm")))
7132    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7133         (minus:HI (match_dup 1) (match_dup 2)))]
7134   "ix86_match_ccmode (insn, CCmode)
7135    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7136   "sub{b}\t{%2, %0|%0, %2}"
7137   [(set_attr "type" "alu")
7138    (set_attr "mode" "QI")])
7139
7140 ;; The patterns that match these are at the end of this file.
7141
7142 (define_expand "subxf3"
7143   [(set (match_operand:XF 0 "register_operand" "")
7144         (minus:XF (match_operand:XF 1 "register_operand" "")
7145                   (match_operand:XF 2 "register_operand" "")))]
7146   "TARGET_80387"
7147   "")
7148
7149 (define_expand "subdf3"
7150   [(set (match_operand:DF 0 "register_operand" "")
7151         (minus:DF (match_operand:DF 1 "register_operand" "")
7152                   (match_operand:DF 2 "nonimmediate_operand" "")))]
7153   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7154   "")
7155
7156 (define_expand "subsf3"
7157   [(set (match_operand:SF 0 "register_operand" "")
7158         (minus:SF (match_operand:SF 1 "register_operand" "")
7159                   (match_operand:SF 2 "nonimmediate_operand" "")))]
7160   "TARGET_80387 || TARGET_SSE_MATH"
7161   "")
7162 \f
7163 ;; Multiply instructions
7164
7165 (define_expand "muldi3"
7166   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7167                    (mult:DI (match_operand:DI 1 "register_operand" "")
7168                             (match_operand:DI 2 "x86_64_general_operand" "")))
7169               (clobber (reg:CC FLAGS_REG))])]
7170   "TARGET_64BIT"
7171   "")
7172
7173 ;; On AMDFAM10 
7174 ;; IMUL reg64, reg64, imm8      Direct
7175 ;; IMUL reg64, mem64, imm8      VectorPath
7176 ;; IMUL reg64, reg64, imm32     Direct
7177 ;; IMUL reg64, mem64, imm32     VectorPath 
7178 ;; IMUL reg64, reg64            Direct
7179 ;; IMUL reg64, mem64            Direct
7180
7181 (define_insn "*muldi3_1_rex64"
7182   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7183         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7184                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7185    (clobber (reg:CC FLAGS_REG))]
7186   "TARGET_64BIT
7187    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7188   "@
7189    imul{q}\t{%2, %1, %0|%0, %1, %2}
7190    imul{q}\t{%2, %1, %0|%0, %1, %2}
7191    imul{q}\t{%2, %0|%0, %2}"
7192   [(set_attr "type" "imul")
7193    (set_attr "prefix_0f" "0,0,1")
7194    (set (attr "athlon_decode")
7195         (cond [(eq_attr "cpu" "athlon")
7196                   (const_string "vector")
7197                (eq_attr "alternative" "1")
7198                   (const_string "vector")
7199                (and (eq_attr "alternative" "2")
7200                     (match_operand 1 "memory_operand" ""))
7201                   (const_string "vector")]
7202               (const_string "direct")))
7203    (set (attr "amdfam10_decode")
7204         (cond [(and (eq_attr "alternative" "0,1")
7205                     (match_operand 1 "memory_operand" ""))
7206                   (const_string "vector")]
7207               (const_string "direct")))       
7208    (set_attr "mode" "DI")])
7209
7210 (define_expand "mulsi3"
7211   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7212                    (mult:SI (match_operand:SI 1 "register_operand" "")
7213                             (match_operand:SI 2 "general_operand" "")))
7214               (clobber (reg:CC FLAGS_REG))])]
7215   ""
7216   "")
7217
7218 ;; On AMDFAM10 
7219 ;; IMUL reg32, reg32, imm8      Direct
7220 ;; IMUL reg32, mem32, imm8      VectorPath
7221 ;; IMUL reg32, reg32, imm32     Direct
7222 ;; IMUL reg32, mem32, imm32     VectorPath
7223 ;; IMUL reg32, reg32            Direct
7224 ;; IMUL reg32, mem32            Direct
7225
7226 (define_insn "*mulsi3_1"
7227   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7228         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7229                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7230    (clobber (reg:CC FLAGS_REG))]
7231   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7232   "@
7233    imul{l}\t{%2, %1, %0|%0, %1, %2}
7234    imul{l}\t{%2, %1, %0|%0, %1, %2}
7235    imul{l}\t{%2, %0|%0, %2}"
7236   [(set_attr "type" "imul")
7237    (set_attr "prefix_0f" "0,0,1")
7238    (set (attr "athlon_decode")
7239         (cond [(eq_attr "cpu" "athlon")
7240                   (const_string "vector")
7241                (eq_attr "alternative" "1")
7242                   (const_string "vector")
7243                (and (eq_attr "alternative" "2")
7244                     (match_operand 1 "memory_operand" ""))
7245                   (const_string "vector")]
7246               (const_string "direct")))
7247    (set (attr "amdfam10_decode")
7248         (cond [(and (eq_attr "alternative" "0,1")
7249                     (match_operand 1 "memory_operand" ""))
7250                   (const_string "vector")]
7251               (const_string "direct")))       
7252    (set_attr "mode" "SI")])
7253
7254 (define_insn "*mulsi3_1_zext"
7255   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7256         (zero_extend:DI
7257           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7258                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7259    (clobber (reg:CC FLAGS_REG))]
7260   "TARGET_64BIT
7261    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7262   "@
7263    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7264    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7265    imul{l}\t{%2, %k0|%k0, %2}"
7266   [(set_attr "type" "imul")
7267    (set_attr "prefix_0f" "0,0,1")
7268    (set (attr "athlon_decode")
7269         (cond [(eq_attr "cpu" "athlon")
7270                   (const_string "vector")
7271                (eq_attr "alternative" "1")
7272                   (const_string "vector")
7273                (and (eq_attr "alternative" "2")
7274                     (match_operand 1 "memory_operand" ""))
7275                   (const_string "vector")]
7276               (const_string "direct")))
7277    (set (attr "amdfam10_decode")
7278         (cond [(and (eq_attr "alternative" "0,1")
7279                     (match_operand 1 "memory_operand" ""))
7280                   (const_string "vector")]
7281               (const_string "direct")))       
7282    (set_attr "mode" "SI")])
7283
7284 (define_expand "mulhi3"
7285   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7286                    (mult:HI (match_operand:HI 1 "register_operand" "")
7287                             (match_operand:HI 2 "general_operand" "")))
7288               (clobber (reg:CC FLAGS_REG))])]
7289   "TARGET_HIMODE_MATH"
7290   "")
7291
7292 ;; On AMDFAM10
7293 ;; IMUL reg16, reg16, imm8      VectorPath
7294 ;; IMUL reg16, mem16, imm8      VectorPath
7295 ;; IMUL reg16, reg16, imm16     VectorPath
7296 ;; IMUL reg16, mem16, imm16     VectorPath
7297 ;; IMUL reg16, reg16            Direct
7298 ;; IMUL reg16, mem16            Direct
7299 (define_insn "*mulhi3_1"
7300   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7301         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7302                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7303    (clobber (reg:CC FLAGS_REG))]
7304   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7305   "@
7306    imul{w}\t{%2, %1, %0|%0, %1, %2}
7307    imul{w}\t{%2, %1, %0|%0, %1, %2}
7308    imul{w}\t{%2, %0|%0, %2}"
7309   [(set_attr "type" "imul")
7310    (set_attr "prefix_0f" "0,0,1")
7311    (set (attr "athlon_decode")
7312         (cond [(eq_attr "cpu" "athlon")
7313                   (const_string "vector")
7314                (eq_attr "alternative" "1,2")
7315                   (const_string "vector")]
7316               (const_string "direct")))
7317    (set (attr "amdfam10_decode")
7318         (cond [(eq_attr "alternative" "0,1")
7319                   (const_string "vector")]
7320               (const_string "direct")))
7321    (set_attr "mode" "HI")])
7322
7323 (define_expand "mulqi3"
7324   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7325                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7326                             (match_operand:QI 2 "register_operand" "")))
7327               (clobber (reg:CC FLAGS_REG))])]
7328   "TARGET_QIMODE_MATH"
7329   "")
7330
7331 ;;On AMDFAM10
7332 ;; MUL reg8     Direct
7333 ;; MUL mem8     Direct
7334
7335 (define_insn "*mulqi3_1"
7336   [(set (match_operand:QI 0 "register_operand" "=a")
7337         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7338                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7339    (clobber (reg:CC FLAGS_REG))]
7340   "TARGET_QIMODE_MATH
7341    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7342   "mul{b}\t%2"
7343   [(set_attr "type" "imul")
7344    (set_attr "length_immediate" "0")
7345    (set (attr "athlon_decode")
7346      (if_then_else (eq_attr "cpu" "athlon")
7347         (const_string "vector")
7348         (const_string "direct")))
7349    (set_attr "amdfam10_decode" "direct")        
7350    (set_attr "mode" "QI")])
7351
7352 (define_expand "umulqihi3"
7353   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7354                    (mult:HI (zero_extend:HI
7355                               (match_operand:QI 1 "nonimmediate_operand" ""))
7356                             (zero_extend:HI
7357                               (match_operand:QI 2 "register_operand" ""))))
7358               (clobber (reg:CC FLAGS_REG))])]
7359   "TARGET_QIMODE_MATH"
7360   "")
7361
7362 (define_insn "*umulqihi3_1"
7363   [(set (match_operand:HI 0 "register_operand" "=a")
7364         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7365                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7366    (clobber (reg:CC FLAGS_REG))]
7367   "TARGET_QIMODE_MATH
7368    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7369   "mul{b}\t%2"
7370   [(set_attr "type" "imul")
7371    (set_attr "length_immediate" "0")
7372    (set (attr "athlon_decode")
7373      (if_then_else (eq_attr "cpu" "athlon")
7374         (const_string "vector")
7375         (const_string "direct")))
7376    (set_attr "amdfam10_decode" "direct")        
7377    (set_attr "mode" "QI")])
7378
7379 (define_expand "mulqihi3"
7380   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7381                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7382                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7383               (clobber (reg:CC FLAGS_REG))])]
7384   "TARGET_QIMODE_MATH"
7385   "")
7386
7387 (define_insn "*mulqihi3_insn"
7388   [(set (match_operand:HI 0 "register_operand" "=a")
7389         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7390                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7391    (clobber (reg:CC FLAGS_REG))]
7392   "TARGET_QIMODE_MATH
7393    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7394   "imul{b}\t%2"
7395   [(set_attr "type" "imul")
7396    (set_attr "length_immediate" "0")
7397    (set (attr "athlon_decode")
7398      (if_then_else (eq_attr "cpu" "athlon")
7399         (const_string "vector")
7400         (const_string "direct")))
7401    (set_attr "amdfam10_decode" "direct")        
7402    (set_attr "mode" "QI")])
7403
7404 (define_expand "umulditi3"
7405   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7406                    (mult:TI (zero_extend:TI
7407                               (match_operand:DI 1 "nonimmediate_operand" ""))
7408                             (zero_extend:TI
7409                               (match_operand:DI 2 "register_operand" ""))))
7410               (clobber (reg:CC FLAGS_REG))])]
7411   "TARGET_64BIT"
7412   "")
7413
7414 (define_insn "*umulditi3_insn"
7415   [(set (match_operand:TI 0 "register_operand" "=A")
7416         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7417                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7418    (clobber (reg:CC FLAGS_REG))]
7419   "TARGET_64BIT
7420    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7421   "mul{q}\t%2"
7422   [(set_attr "type" "imul")
7423    (set_attr "length_immediate" "0")
7424    (set (attr "athlon_decode")
7425      (if_then_else (eq_attr "cpu" "athlon")
7426         (const_string "vector")
7427         (const_string "double")))
7428    (set_attr "amdfam10_decode" "double")        
7429    (set_attr "mode" "DI")])
7430
7431 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7432 (define_expand "umulsidi3"
7433   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7434                    (mult:DI (zero_extend:DI
7435                               (match_operand:SI 1 "nonimmediate_operand" ""))
7436                             (zero_extend:DI
7437                               (match_operand:SI 2 "register_operand" ""))))
7438               (clobber (reg:CC FLAGS_REG))])]
7439   "!TARGET_64BIT"
7440   "")
7441
7442 (define_insn "*umulsidi3_insn"
7443   [(set (match_operand:DI 0 "register_operand" "=A")
7444         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7445                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7446    (clobber (reg:CC FLAGS_REG))]
7447   "!TARGET_64BIT
7448    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7449   "mul{l}\t%2"
7450   [(set_attr "type" "imul")
7451    (set_attr "length_immediate" "0")
7452    (set (attr "athlon_decode")
7453      (if_then_else (eq_attr "cpu" "athlon")
7454         (const_string "vector")
7455         (const_string "double")))
7456    (set_attr "amdfam10_decode" "double")        
7457    (set_attr "mode" "SI")])
7458
7459 (define_expand "mulditi3"
7460   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7461                    (mult:TI (sign_extend:TI
7462                               (match_operand:DI 1 "nonimmediate_operand" ""))
7463                             (sign_extend:TI
7464                               (match_operand:DI 2 "register_operand" ""))))
7465               (clobber (reg:CC FLAGS_REG))])]
7466   "TARGET_64BIT"
7467   "")
7468
7469 (define_insn "*mulditi3_insn"
7470   [(set (match_operand:TI 0 "register_operand" "=A")
7471         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7472                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7473    (clobber (reg:CC FLAGS_REG))]
7474   "TARGET_64BIT
7475    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7476   "imul{q}\t%2"
7477   [(set_attr "type" "imul")
7478    (set_attr "length_immediate" "0")
7479    (set (attr "athlon_decode")
7480      (if_then_else (eq_attr "cpu" "athlon")
7481         (const_string "vector")
7482         (const_string "double")))
7483    (set_attr "amdfam10_decode" "double")
7484    (set_attr "mode" "DI")])
7485
7486 (define_expand "mulsidi3"
7487   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7488                    (mult:DI (sign_extend:DI
7489                               (match_operand:SI 1 "nonimmediate_operand" ""))
7490                             (sign_extend:DI
7491                               (match_operand:SI 2 "register_operand" ""))))
7492               (clobber (reg:CC FLAGS_REG))])]
7493   "!TARGET_64BIT"
7494   "")
7495
7496 (define_insn "*mulsidi3_insn"
7497   [(set (match_operand:DI 0 "register_operand" "=A")
7498         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7499                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7500    (clobber (reg:CC FLAGS_REG))]
7501   "!TARGET_64BIT
7502    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7503   "imul{l}\t%2"
7504   [(set_attr "type" "imul")
7505    (set_attr "length_immediate" "0")
7506    (set (attr "athlon_decode")
7507      (if_then_else (eq_attr "cpu" "athlon")
7508         (const_string "vector")
7509         (const_string "double")))
7510    (set_attr "amdfam10_decode" "double")        
7511    (set_attr "mode" "SI")])
7512
7513 (define_expand "umuldi3_highpart"
7514   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7515                    (truncate:DI
7516                      (lshiftrt:TI
7517                        (mult:TI (zero_extend:TI
7518                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7519                                 (zero_extend:TI
7520                                   (match_operand:DI 2 "register_operand" "")))
7521                        (const_int 64))))
7522               (clobber (match_scratch:DI 3 ""))
7523               (clobber (reg:CC FLAGS_REG))])]
7524   "TARGET_64BIT"
7525   "")
7526
7527 (define_insn "*umuldi3_highpart_rex64"
7528   [(set (match_operand:DI 0 "register_operand" "=d")
7529         (truncate:DI
7530           (lshiftrt:TI
7531             (mult:TI (zero_extend:TI
7532                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7533                      (zero_extend:TI
7534                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7535             (const_int 64))))
7536    (clobber (match_scratch:DI 3 "=1"))
7537    (clobber (reg:CC FLAGS_REG))]
7538   "TARGET_64BIT
7539    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7540   "mul{q}\t%2"
7541   [(set_attr "type" "imul")
7542    (set_attr "length_immediate" "0")
7543    (set (attr "athlon_decode")
7544      (if_then_else (eq_attr "cpu" "athlon")
7545         (const_string "vector")
7546         (const_string "double")))
7547    (set_attr "amdfam10_decode" "double")        
7548    (set_attr "mode" "DI")])
7549
7550 (define_expand "umulsi3_highpart"
7551   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7552                    (truncate:SI
7553                      (lshiftrt:DI
7554                        (mult:DI (zero_extend:DI
7555                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7556                                 (zero_extend:DI
7557                                   (match_operand:SI 2 "register_operand" "")))
7558                        (const_int 32))))
7559               (clobber (match_scratch:SI 3 ""))
7560               (clobber (reg:CC FLAGS_REG))])]
7561   ""
7562   "")
7563
7564 (define_insn "*umulsi3_highpart_insn"
7565   [(set (match_operand:SI 0 "register_operand" "=d")
7566         (truncate:SI
7567           (lshiftrt:DI
7568             (mult:DI (zero_extend:DI
7569                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7570                      (zero_extend:DI
7571                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7572             (const_int 32))))
7573    (clobber (match_scratch:SI 3 "=1"))
7574    (clobber (reg:CC FLAGS_REG))]
7575   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7576   "mul{l}\t%2"
7577   [(set_attr "type" "imul")
7578    (set_attr "length_immediate" "0")
7579    (set (attr "athlon_decode")
7580      (if_then_else (eq_attr "cpu" "athlon")
7581         (const_string "vector")
7582         (const_string "double")))
7583    (set_attr "amdfam10_decode" "double")
7584    (set_attr "mode" "SI")])
7585
7586 (define_insn "*umulsi3_highpart_zext"
7587   [(set (match_operand:DI 0 "register_operand" "=d")
7588         (zero_extend:DI (truncate:SI
7589           (lshiftrt:DI
7590             (mult:DI (zero_extend:DI
7591                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7592                      (zero_extend:DI
7593                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7594             (const_int 32)))))
7595    (clobber (match_scratch:SI 3 "=1"))
7596    (clobber (reg:CC FLAGS_REG))]
7597   "TARGET_64BIT
7598    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7599   "mul{l}\t%2"
7600   [(set_attr "type" "imul")
7601    (set_attr "length_immediate" "0")
7602    (set (attr "athlon_decode")
7603      (if_then_else (eq_attr "cpu" "athlon")
7604         (const_string "vector")
7605         (const_string "double")))
7606    (set_attr "amdfam10_decode" "double")
7607    (set_attr "mode" "SI")])
7608
7609 (define_expand "smuldi3_highpart"
7610   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7611                    (truncate:DI
7612                      (lshiftrt:TI
7613                        (mult:TI (sign_extend:TI
7614                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7615                                 (sign_extend:TI
7616                                   (match_operand:DI 2 "register_operand" "")))
7617                        (const_int 64))))
7618               (clobber (match_scratch:DI 3 ""))
7619               (clobber (reg:CC FLAGS_REG))])]
7620   "TARGET_64BIT"
7621   "")
7622
7623 (define_insn "*smuldi3_highpart_rex64"
7624   [(set (match_operand:DI 0 "register_operand" "=d")
7625         (truncate:DI
7626           (lshiftrt:TI
7627             (mult:TI (sign_extend:TI
7628                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7629                      (sign_extend:TI
7630                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7631             (const_int 64))))
7632    (clobber (match_scratch:DI 3 "=1"))
7633    (clobber (reg:CC FLAGS_REG))]
7634   "TARGET_64BIT
7635    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7636   "imul{q}\t%2"
7637   [(set_attr "type" "imul")
7638    (set (attr "athlon_decode")
7639      (if_then_else (eq_attr "cpu" "athlon")
7640         (const_string "vector")
7641         (const_string "double")))
7642    (set_attr "amdfam10_decode" "double")
7643    (set_attr "mode" "DI")])
7644
7645 (define_expand "smulsi3_highpart"
7646   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7647                    (truncate:SI
7648                      (lshiftrt:DI
7649                        (mult:DI (sign_extend:DI
7650                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7651                                 (sign_extend:DI
7652                                   (match_operand:SI 2 "register_operand" "")))
7653                        (const_int 32))))
7654               (clobber (match_scratch:SI 3 ""))
7655               (clobber (reg:CC FLAGS_REG))])]
7656   ""
7657   "")
7658
7659 (define_insn "*smulsi3_highpart_insn"
7660   [(set (match_operand:SI 0 "register_operand" "=d")
7661         (truncate:SI
7662           (lshiftrt:DI
7663             (mult:DI (sign_extend:DI
7664                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7665                      (sign_extend:DI
7666                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7667             (const_int 32))))
7668    (clobber (match_scratch:SI 3 "=1"))
7669    (clobber (reg:CC FLAGS_REG))]
7670   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7671   "imul{l}\t%2"
7672   [(set_attr "type" "imul")
7673    (set (attr "athlon_decode")
7674      (if_then_else (eq_attr "cpu" "athlon")
7675         (const_string "vector")
7676         (const_string "double")))
7677    (set_attr "amdfam10_decode" "double")
7678    (set_attr "mode" "SI")])
7679
7680 (define_insn "*smulsi3_highpart_zext"
7681   [(set (match_operand:DI 0 "register_operand" "=d")
7682         (zero_extend:DI (truncate:SI
7683           (lshiftrt:DI
7684             (mult:DI (sign_extend:DI
7685                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7686                      (sign_extend:DI
7687                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7688             (const_int 32)))))
7689    (clobber (match_scratch:SI 3 "=1"))
7690    (clobber (reg:CC FLAGS_REG))]
7691   "TARGET_64BIT
7692    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7693   "imul{l}\t%2"
7694   [(set_attr "type" "imul")
7695    (set (attr "athlon_decode")
7696      (if_then_else (eq_attr "cpu" "athlon")
7697         (const_string "vector")
7698         (const_string "double")))
7699    (set_attr "amdfam10_decode" "double")
7700    (set_attr "mode" "SI")])
7701
7702 ;; The patterns that match these are at the end of this file.
7703
7704 (define_expand "mulxf3"
7705   [(set (match_operand:XF 0 "register_operand" "")
7706         (mult:XF (match_operand:XF 1 "register_operand" "")
7707                  (match_operand:XF 2 "register_operand" "")))]
7708   "TARGET_80387"
7709   "")
7710
7711 (define_expand "muldf3"
7712   [(set (match_operand:DF 0 "register_operand" "")
7713         (mult:DF (match_operand:DF 1 "register_operand" "")
7714                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7715   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7716   "")
7717
7718 (define_expand "mulsf3"
7719   [(set (match_operand:SF 0 "register_operand" "")
7720         (mult:SF (match_operand:SF 1 "register_operand" "")
7721                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7722   "TARGET_80387 || TARGET_SSE_MATH"
7723   "")
7724 \f
7725 ;; Divide instructions
7726
7727 (define_insn "divqi3"
7728   [(set (match_operand:QI 0 "register_operand" "=a")
7729         (div:QI (match_operand:HI 1 "register_operand" "0")
7730                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7731    (clobber (reg:CC FLAGS_REG))]
7732   "TARGET_QIMODE_MATH"
7733   "idiv{b}\t%2"
7734   [(set_attr "type" "idiv")
7735    (set_attr "mode" "QI")])
7736
7737 (define_insn "udivqi3"
7738   [(set (match_operand:QI 0 "register_operand" "=a")
7739         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7740                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7741    (clobber (reg:CC FLAGS_REG))]
7742   "TARGET_QIMODE_MATH"
7743   "div{b}\t%2"
7744   [(set_attr "type" "idiv")
7745    (set_attr "mode" "QI")])
7746
7747 ;; The patterns that match these are at the end of this file.
7748
7749 (define_expand "divxf3"
7750   [(set (match_operand:XF 0 "register_operand" "")
7751         (div:XF (match_operand:XF 1 "register_operand" "")
7752                 (match_operand:XF 2 "register_operand" "")))]
7753   "TARGET_80387"
7754   "")
7755
7756 (define_expand "divdf3"
7757   [(set (match_operand:DF 0 "register_operand" "")
7758         (div:DF (match_operand:DF 1 "register_operand" "")
7759                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7760    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7761    "")
7762
7763 (define_expand "divsf3"
7764   [(set (match_operand:SF 0 "register_operand" "")
7765         (div:SF (match_operand:SF 1 "register_operand" "")
7766                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7767   "TARGET_80387 || TARGET_SSE_MATH"
7768   "")
7769 \f
7770 ;; Remainder instructions.
7771
7772 (define_expand "divmoddi4"
7773   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7774                    (div:DI (match_operand:DI 1 "register_operand" "")
7775                            (match_operand:DI 2 "nonimmediate_operand" "")))
7776               (set (match_operand:DI 3 "register_operand" "")
7777                    (mod:DI (match_dup 1) (match_dup 2)))
7778               (clobber (reg:CC FLAGS_REG))])]
7779   "TARGET_64BIT"
7780   "")
7781
7782 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7783 ;; Penalize eax case slightly because it results in worse scheduling
7784 ;; of code.
7785 (define_insn "*divmoddi4_nocltd_rex64"
7786   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7787         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7788                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7789    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7790         (mod:DI (match_dup 2) (match_dup 3)))
7791    (clobber (reg:CC FLAGS_REG))]
7792   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7793   "#"
7794   [(set_attr "type" "multi")])
7795
7796 (define_insn "*divmoddi4_cltd_rex64"
7797   [(set (match_operand:DI 0 "register_operand" "=a")
7798         (div:DI (match_operand:DI 2 "register_operand" "a")
7799                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7800    (set (match_operand:DI 1 "register_operand" "=&d")
7801         (mod:DI (match_dup 2) (match_dup 3)))
7802    (clobber (reg:CC FLAGS_REG))]
7803   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7804   "#"
7805   [(set_attr "type" "multi")])
7806
7807 (define_insn "*divmoddi_noext_rex64"
7808   [(set (match_operand:DI 0 "register_operand" "=a")
7809         (div:DI (match_operand:DI 1 "register_operand" "0")
7810                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7811    (set (match_operand:DI 3 "register_operand" "=d")
7812         (mod:DI (match_dup 1) (match_dup 2)))
7813    (use (match_operand:DI 4 "register_operand" "3"))
7814    (clobber (reg:CC FLAGS_REG))]
7815   "TARGET_64BIT"
7816   "idiv{q}\t%2"
7817   [(set_attr "type" "idiv")
7818    (set_attr "mode" "DI")])
7819
7820 (define_split
7821   [(set (match_operand:DI 0 "register_operand" "")
7822         (div:DI (match_operand:DI 1 "register_operand" "")
7823                 (match_operand:DI 2 "nonimmediate_operand" "")))
7824    (set (match_operand:DI 3 "register_operand" "")
7825         (mod:DI (match_dup 1) (match_dup 2)))
7826    (clobber (reg:CC FLAGS_REG))]
7827   "TARGET_64BIT && reload_completed"
7828   [(parallel [(set (match_dup 3)
7829                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7830               (clobber (reg:CC FLAGS_REG))])
7831    (parallel [(set (match_dup 0)
7832                    (div:DI (reg:DI 0) (match_dup 2)))
7833               (set (match_dup 3)
7834                    (mod:DI (reg:DI 0) (match_dup 2)))
7835               (use (match_dup 3))
7836               (clobber (reg:CC FLAGS_REG))])]
7837 {
7838   /* Avoid use of cltd in favor of a mov+shift.  */
7839   if (!TARGET_USE_CLTD && !optimize_size)
7840     {
7841       if (true_regnum (operands[1]))
7842         emit_move_insn (operands[0], operands[1]);
7843       else
7844         emit_move_insn (operands[3], operands[1]);
7845       operands[4] = operands[3];
7846     }
7847   else
7848     {
7849       gcc_assert (!true_regnum (operands[1]));
7850       operands[4] = operands[1];
7851     }
7852 })
7853
7854
7855 (define_expand "divmodsi4"
7856   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7857                    (div:SI (match_operand:SI 1 "register_operand" "")
7858                            (match_operand:SI 2 "nonimmediate_operand" "")))
7859               (set (match_operand:SI 3 "register_operand" "")
7860                    (mod:SI (match_dup 1) (match_dup 2)))
7861               (clobber (reg:CC FLAGS_REG))])]
7862   ""
7863   "")
7864
7865 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7866 ;; Penalize eax case slightly because it results in worse scheduling
7867 ;; of code.
7868 (define_insn "*divmodsi4_nocltd"
7869   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7870         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7871                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7872    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7873         (mod:SI (match_dup 2) (match_dup 3)))
7874    (clobber (reg:CC FLAGS_REG))]
7875   "!optimize_size && !TARGET_USE_CLTD"
7876   "#"
7877   [(set_attr "type" "multi")])
7878
7879 (define_insn "*divmodsi4_cltd"
7880   [(set (match_operand:SI 0 "register_operand" "=a")
7881         (div:SI (match_operand:SI 2 "register_operand" "a")
7882                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7883    (set (match_operand:SI 1 "register_operand" "=&d")
7884         (mod:SI (match_dup 2) (match_dup 3)))
7885    (clobber (reg:CC FLAGS_REG))]
7886   "optimize_size || TARGET_USE_CLTD"
7887   "#"
7888   [(set_attr "type" "multi")])
7889
7890 (define_insn "*divmodsi_noext"
7891   [(set (match_operand:SI 0 "register_operand" "=a")
7892         (div:SI (match_operand:SI 1 "register_operand" "0")
7893                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7894    (set (match_operand:SI 3 "register_operand" "=d")
7895         (mod:SI (match_dup 1) (match_dup 2)))
7896    (use (match_operand:SI 4 "register_operand" "3"))
7897    (clobber (reg:CC FLAGS_REG))]
7898   ""
7899   "idiv{l}\t%2"
7900   [(set_attr "type" "idiv")
7901    (set_attr "mode" "SI")])
7902
7903 (define_split
7904   [(set (match_operand:SI 0 "register_operand" "")
7905         (div:SI (match_operand:SI 1 "register_operand" "")
7906                 (match_operand:SI 2 "nonimmediate_operand" "")))
7907    (set (match_operand:SI 3 "register_operand" "")
7908         (mod:SI (match_dup 1) (match_dup 2)))
7909    (clobber (reg:CC FLAGS_REG))]
7910   "reload_completed"
7911   [(parallel [(set (match_dup 3)
7912                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7913               (clobber (reg:CC FLAGS_REG))])
7914    (parallel [(set (match_dup 0)
7915                    (div:SI (reg:SI 0) (match_dup 2)))
7916               (set (match_dup 3)
7917                    (mod:SI (reg:SI 0) (match_dup 2)))
7918               (use (match_dup 3))
7919               (clobber (reg:CC FLAGS_REG))])]
7920 {
7921   /* Avoid use of cltd in favor of a mov+shift.  */
7922   if (!TARGET_USE_CLTD && !optimize_size)
7923     {
7924       if (true_regnum (operands[1]))
7925         emit_move_insn (operands[0], operands[1]);
7926       else
7927         emit_move_insn (operands[3], operands[1]);
7928       operands[4] = operands[3];
7929     }
7930   else
7931     {
7932       gcc_assert (!true_regnum (operands[1]));
7933       operands[4] = operands[1];
7934     }
7935 })
7936 ;; %%% Split me.
7937 (define_insn "divmodhi4"
7938   [(set (match_operand:HI 0 "register_operand" "=a")
7939         (div:HI (match_operand:HI 1 "register_operand" "0")
7940                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7941    (set (match_operand:HI 3 "register_operand" "=&d")
7942         (mod:HI (match_dup 1) (match_dup 2)))
7943    (clobber (reg:CC FLAGS_REG))]
7944   "TARGET_HIMODE_MATH"
7945   "cwtd\;idiv{w}\t%2"
7946   [(set_attr "type" "multi")
7947    (set_attr "length_immediate" "0")
7948    (set_attr "mode" "SI")])
7949
7950 (define_insn "udivmoddi4"
7951   [(set (match_operand:DI 0 "register_operand" "=a")
7952         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7953                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7954    (set (match_operand:DI 3 "register_operand" "=&d")
7955         (umod:DI (match_dup 1) (match_dup 2)))
7956    (clobber (reg:CC FLAGS_REG))]
7957   "TARGET_64BIT"
7958   "xor{q}\t%3, %3\;div{q}\t%2"
7959   [(set_attr "type" "multi")
7960    (set_attr "length_immediate" "0")
7961    (set_attr "mode" "DI")])
7962
7963 (define_insn "*udivmoddi4_noext"
7964   [(set (match_operand:DI 0 "register_operand" "=a")
7965         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7966                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7967    (set (match_operand:DI 3 "register_operand" "=d")
7968         (umod:DI (match_dup 1) (match_dup 2)))
7969    (use (match_dup 3))
7970    (clobber (reg:CC FLAGS_REG))]
7971   "TARGET_64BIT"
7972   "div{q}\t%2"
7973   [(set_attr "type" "idiv")
7974    (set_attr "mode" "DI")])
7975
7976 (define_split
7977   [(set (match_operand:DI 0 "register_operand" "")
7978         (udiv:DI (match_operand:DI 1 "register_operand" "")
7979                  (match_operand:DI 2 "nonimmediate_operand" "")))
7980    (set (match_operand:DI 3 "register_operand" "")
7981         (umod:DI (match_dup 1) (match_dup 2)))
7982    (clobber (reg:CC FLAGS_REG))]
7983   "TARGET_64BIT && reload_completed"
7984   [(set (match_dup 3) (const_int 0))
7985    (parallel [(set (match_dup 0)
7986                    (udiv:DI (match_dup 1) (match_dup 2)))
7987               (set (match_dup 3)
7988                    (umod:DI (match_dup 1) (match_dup 2)))
7989               (use (match_dup 3))
7990               (clobber (reg:CC FLAGS_REG))])]
7991   "")
7992
7993 (define_insn "udivmodsi4"
7994   [(set (match_operand:SI 0 "register_operand" "=a")
7995         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7996                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7997    (set (match_operand:SI 3 "register_operand" "=&d")
7998         (umod:SI (match_dup 1) (match_dup 2)))
7999    (clobber (reg:CC FLAGS_REG))]
8000   ""
8001   "xor{l}\t%3, %3\;div{l}\t%2"
8002   [(set_attr "type" "multi")
8003    (set_attr "length_immediate" "0")
8004    (set_attr "mode" "SI")])
8005
8006 (define_insn "*udivmodsi4_noext"
8007   [(set (match_operand:SI 0 "register_operand" "=a")
8008         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8009                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8010    (set (match_operand:SI 3 "register_operand" "=d")
8011         (umod:SI (match_dup 1) (match_dup 2)))
8012    (use (match_dup 3))
8013    (clobber (reg:CC FLAGS_REG))]
8014   ""
8015   "div{l}\t%2"
8016   [(set_attr "type" "idiv")
8017    (set_attr "mode" "SI")])
8018
8019 (define_split
8020   [(set (match_operand:SI 0 "register_operand" "")
8021         (udiv:SI (match_operand:SI 1 "register_operand" "")
8022                  (match_operand:SI 2 "nonimmediate_operand" "")))
8023    (set (match_operand:SI 3 "register_operand" "")
8024         (umod:SI (match_dup 1) (match_dup 2)))
8025    (clobber (reg:CC FLAGS_REG))]
8026   "reload_completed"
8027   [(set (match_dup 3) (const_int 0))
8028    (parallel [(set (match_dup 0)
8029                    (udiv:SI (match_dup 1) (match_dup 2)))
8030               (set (match_dup 3)
8031                    (umod:SI (match_dup 1) (match_dup 2)))
8032               (use (match_dup 3))
8033               (clobber (reg:CC FLAGS_REG))])]
8034   "")
8035
8036 (define_expand "udivmodhi4"
8037   [(set (match_dup 4) (const_int 0))
8038    (parallel [(set (match_operand:HI 0 "register_operand" "")
8039                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8040                             (match_operand:HI 2 "nonimmediate_operand" "")))
8041               (set (match_operand:HI 3 "register_operand" "")
8042                    (umod:HI (match_dup 1) (match_dup 2)))
8043               (use (match_dup 4))
8044               (clobber (reg:CC FLAGS_REG))])]
8045   "TARGET_HIMODE_MATH"
8046   "operands[4] = gen_reg_rtx (HImode);")
8047
8048 (define_insn "*udivmodhi_noext"
8049   [(set (match_operand:HI 0 "register_operand" "=a")
8050         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8051                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8052    (set (match_operand:HI 3 "register_operand" "=d")
8053         (umod:HI (match_dup 1) (match_dup 2)))
8054    (use (match_operand:HI 4 "register_operand" "3"))
8055    (clobber (reg:CC FLAGS_REG))]
8056   ""
8057   "div{w}\t%2"
8058   [(set_attr "type" "idiv")
8059    (set_attr "mode" "HI")])
8060
8061 ;; We cannot use div/idiv for double division, because it causes
8062 ;; "division by zero" on the overflow and that's not what we expect
8063 ;; from truncate.  Because true (non truncating) double division is
8064 ;; never generated, we can't create this insn anyway.
8065 ;
8066 ;(define_insn ""
8067 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8068 ;       (truncate:SI
8069 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8070 ;                  (zero_extend:DI
8071 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8072 ;   (set (match_operand:SI 3 "register_operand" "=d")
8073 ;       (truncate:SI
8074 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8075 ;   (clobber (reg:CC FLAGS_REG))]
8076 ;  ""
8077 ;  "div{l}\t{%2, %0|%0, %2}"
8078 ;  [(set_attr "type" "idiv")])
8079 \f
8080 ;;- Logical AND instructions
8081
8082 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8083 ;; Note that this excludes ah.
8084
8085 (define_insn "*testdi_1_rex64"
8086   [(set (reg FLAGS_REG)
8087         (compare
8088           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8089                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8090           (const_int 0)))]
8091   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8092    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8093   "@
8094    test{l}\t{%k1, %k0|%k0, %k1}
8095    test{l}\t{%k1, %k0|%k0, %k1}
8096    test{q}\t{%1, %0|%0, %1}
8097    test{q}\t{%1, %0|%0, %1}
8098    test{q}\t{%1, %0|%0, %1}"
8099   [(set_attr "type" "test")
8100    (set_attr "modrm" "0,1,0,1,1")
8101    (set_attr "mode" "SI,SI,DI,DI,DI")
8102    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8103
8104 (define_insn "testsi_1"
8105   [(set (reg FLAGS_REG)
8106         (compare
8107           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8108                   (match_operand:SI 1 "general_operand" "in,in,rin"))
8109           (const_int 0)))]
8110   "ix86_match_ccmode (insn, CCNOmode)
8111    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8112   "test{l}\t{%1, %0|%0, %1}"
8113   [(set_attr "type" "test")
8114    (set_attr "modrm" "0,1,1")
8115    (set_attr "mode" "SI")
8116    (set_attr "pent_pair" "uv,np,uv")])
8117
8118 (define_expand "testsi_ccno_1"
8119   [(set (reg:CCNO FLAGS_REG)
8120         (compare:CCNO
8121           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8122                   (match_operand:SI 1 "nonmemory_operand" ""))
8123           (const_int 0)))]
8124   ""
8125   "")
8126
8127 (define_insn "*testhi_1"
8128   [(set (reg FLAGS_REG)
8129         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8130                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8131                  (const_int 0)))]
8132   "ix86_match_ccmode (insn, CCNOmode)
8133    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8134   "test{w}\t{%1, %0|%0, %1}"
8135   [(set_attr "type" "test")
8136    (set_attr "modrm" "0,1,1")
8137    (set_attr "mode" "HI")
8138    (set_attr "pent_pair" "uv,np,uv")])
8139
8140 (define_expand "testqi_ccz_1"
8141   [(set (reg:CCZ FLAGS_REG)
8142         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8143                              (match_operand:QI 1 "nonmemory_operand" ""))
8144                  (const_int 0)))]
8145   ""
8146   "")
8147
8148 (define_insn "*testqi_1_maybe_si"
8149   [(set (reg FLAGS_REG)
8150         (compare
8151           (and:QI
8152             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8153             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8154           (const_int 0)))]
8155    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8156     && ix86_match_ccmode (insn,
8157                          CONST_INT_P (operands[1])
8158                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8159 {
8160   if (which_alternative == 3)
8161     {
8162       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8163         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8164       return "test{l}\t{%1, %k0|%k0, %1}";
8165     }
8166   return "test{b}\t{%1, %0|%0, %1}";
8167 }
8168   [(set_attr "type" "test")
8169    (set_attr "modrm" "0,1,1,1")
8170    (set_attr "mode" "QI,QI,QI,SI")
8171    (set_attr "pent_pair" "uv,np,uv,np")])
8172
8173 (define_insn "*testqi_1"
8174   [(set (reg FLAGS_REG)
8175         (compare
8176           (and:QI
8177             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8178             (match_operand:QI 1 "general_operand" "n,n,qn"))
8179           (const_int 0)))]
8180   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8181    && ix86_match_ccmode (insn, CCNOmode)"
8182   "test{b}\t{%1, %0|%0, %1}"
8183   [(set_attr "type" "test")
8184    (set_attr "modrm" "0,1,1")
8185    (set_attr "mode" "QI")
8186    (set_attr "pent_pair" "uv,np,uv")])
8187
8188 (define_expand "testqi_ext_ccno_0"
8189   [(set (reg:CCNO FLAGS_REG)
8190         (compare:CCNO
8191           (and:SI
8192             (zero_extract:SI
8193               (match_operand 0 "ext_register_operand" "")
8194               (const_int 8)
8195               (const_int 8))
8196             (match_operand 1 "const_int_operand" ""))
8197           (const_int 0)))]
8198   ""
8199   "")
8200
8201 (define_insn "*testqi_ext_0"
8202   [(set (reg FLAGS_REG)
8203         (compare
8204           (and:SI
8205             (zero_extract:SI
8206               (match_operand 0 "ext_register_operand" "Q")
8207               (const_int 8)
8208               (const_int 8))
8209             (match_operand 1 "const_int_operand" "n"))
8210           (const_int 0)))]
8211   "ix86_match_ccmode (insn, CCNOmode)"
8212   "test{b}\t{%1, %h0|%h0, %1}"
8213   [(set_attr "type" "test")
8214    (set_attr "mode" "QI")
8215    (set_attr "length_immediate" "1")
8216    (set_attr "pent_pair" "np")])
8217
8218 (define_insn "*testqi_ext_1"
8219   [(set (reg FLAGS_REG)
8220         (compare
8221           (and:SI
8222             (zero_extract:SI
8223               (match_operand 0 "ext_register_operand" "Q")
8224               (const_int 8)
8225               (const_int 8))
8226             (zero_extend:SI
8227               (match_operand:QI 1 "general_operand" "Qm")))
8228           (const_int 0)))]
8229   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8230    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8231   "test{b}\t{%1, %h0|%h0, %1}"
8232   [(set_attr "type" "test")
8233    (set_attr "mode" "QI")])
8234
8235 (define_insn "*testqi_ext_1_rex64"
8236   [(set (reg FLAGS_REG)
8237         (compare
8238           (and:SI
8239             (zero_extract:SI
8240               (match_operand 0 "ext_register_operand" "Q")
8241               (const_int 8)
8242               (const_int 8))
8243             (zero_extend:SI
8244               (match_operand:QI 1 "register_operand" "Q")))
8245           (const_int 0)))]
8246   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8247   "test{b}\t{%1, %h0|%h0, %1}"
8248   [(set_attr "type" "test")
8249    (set_attr "mode" "QI")])
8250
8251 (define_insn "*testqi_ext_2"
8252   [(set (reg FLAGS_REG)
8253         (compare
8254           (and:SI
8255             (zero_extract:SI
8256               (match_operand 0 "ext_register_operand" "Q")
8257               (const_int 8)
8258               (const_int 8))
8259             (zero_extract:SI
8260               (match_operand 1 "ext_register_operand" "Q")
8261               (const_int 8)
8262               (const_int 8)))
8263           (const_int 0)))]
8264   "ix86_match_ccmode (insn, CCNOmode)"
8265   "test{b}\t{%h1, %h0|%h0, %h1}"
8266   [(set_attr "type" "test")
8267    (set_attr "mode" "QI")])
8268
8269 ;; Combine likes to form bit extractions for some tests.  Humor it.
8270 (define_insn "*testqi_ext_3"
8271   [(set (reg FLAGS_REG)
8272         (compare (zero_extract:SI
8273                    (match_operand 0 "nonimmediate_operand" "rm")
8274                    (match_operand:SI 1 "const_int_operand" "")
8275                    (match_operand:SI 2 "const_int_operand" ""))
8276                  (const_int 0)))]
8277   "ix86_match_ccmode (insn, CCNOmode)
8278    && INTVAL (operands[1]) > 0
8279    && INTVAL (operands[2]) >= 0
8280    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8281    && (GET_MODE (operands[0]) == SImode
8282        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8283        || GET_MODE (operands[0]) == HImode
8284        || GET_MODE (operands[0]) == QImode)"
8285   "#")
8286
8287 (define_insn "*testqi_ext_3_rex64"
8288   [(set (reg FLAGS_REG)
8289         (compare (zero_extract:DI
8290                    (match_operand 0 "nonimmediate_operand" "rm")
8291                    (match_operand:DI 1 "const_int_operand" "")
8292                    (match_operand:DI 2 "const_int_operand" ""))
8293                  (const_int 0)))]
8294   "TARGET_64BIT
8295    && ix86_match_ccmode (insn, CCNOmode)
8296    && INTVAL (operands[1]) > 0
8297    && INTVAL (operands[2]) >= 0
8298    /* Ensure that resulting mask is zero or sign extended operand.  */
8299    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8300        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8301            && INTVAL (operands[1]) > 32))
8302    && (GET_MODE (operands[0]) == SImode
8303        || GET_MODE (operands[0]) == DImode
8304        || GET_MODE (operands[0]) == HImode
8305        || GET_MODE (operands[0]) == QImode)"
8306   "#")
8307
8308 (define_split
8309   [(set (match_operand 0 "flags_reg_operand" "")
8310         (match_operator 1 "compare_operator"
8311           [(zero_extract
8312              (match_operand 2 "nonimmediate_operand" "")
8313              (match_operand 3 "const_int_operand" "")
8314              (match_operand 4 "const_int_operand" ""))
8315            (const_int 0)]))]
8316   "ix86_match_ccmode (insn, CCNOmode)"
8317   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8318 {
8319   rtx val = operands[2];
8320   HOST_WIDE_INT len = INTVAL (operands[3]);
8321   HOST_WIDE_INT pos = INTVAL (operands[4]);
8322   HOST_WIDE_INT mask;
8323   enum machine_mode mode, submode;
8324
8325   mode = GET_MODE (val);
8326   if (MEM_P (val))
8327     {
8328       /* ??? Combine likes to put non-volatile mem extractions in QImode
8329          no matter the size of the test.  So find a mode that works.  */
8330       if (! MEM_VOLATILE_P (val))
8331         {
8332           mode = smallest_mode_for_size (pos + len, MODE_INT);
8333           val = adjust_address (val, mode, 0);
8334         }
8335     }
8336   else if (GET_CODE (val) == SUBREG
8337            && (submode = GET_MODE (SUBREG_REG (val)),
8338                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8339            && pos + len <= GET_MODE_BITSIZE (submode))
8340     {
8341       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8342       mode = submode;
8343       val = SUBREG_REG (val);
8344     }
8345   else if (mode == HImode && pos + len <= 8)
8346     {
8347       /* Small HImode tests can be converted to QImode.  */
8348       mode = QImode;
8349       val = gen_lowpart (QImode, val);
8350     }
8351
8352   if (len == HOST_BITS_PER_WIDE_INT)
8353     mask = -1;
8354   else
8355     mask = ((HOST_WIDE_INT)1 << len) - 1;
8356   mask <<= pos;
8357
8358   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8359 })
8360
8361 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8362 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8363 ;; this is relatively important trick.
8364 ;; Do the conversion only post-reload to avoid limiting of the register class
8365 ;; to QI regs.
8366 (define_split
8367   [(set (match_operand 0 "flags_reg_operand" "")
8368         (match_operator 1 "compare_operator"
8369           [(and (match_operand 2 "register_operand" "")
8370                 (match_operand 3 "const_int_operand" ""))
8371            (const_int 0)]))]
8372    "reload_completed
8373     && QI_REG_P (operands[2])
8374     && GET_MODE (operands[2]) != QImode
8375     && ((ix86_match_ccmode (insn, CCZmode)
8376          && !(INTVAL (operands[3]) & ~(255 << 8)))
8377         || (ix86_match_ccmode (insn, CCNOmode)
8378             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8379   [(set (match_dup 0)
8380         (match_op_dup 1
8381           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8382                    (match_dup 3))
8383            (const_int 0)]))]
8384   "operands[2] = gen_lowpart (SImode, operands[2]);
8385    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8386
8387 (define_split
8388   [(set (match_operand 0 "flags_reg_operand" "")
8389         (match_operator 1 "compare_operator"
8390           [(and (match_operand 2 "nonimmediate_operand" "")
8391                 (match_operand 3 "const_int_operand" ""))
8392            (const_int 0)]))]
8393    "reload_completed
8394     && GET_MODE (operands[2]) != QImode
8395     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8396     && ((ix86_match_ccmode (insn, CCZmode)
8397          && !(INTVAL (operands[3]) & ~255))
8398         || (ix86_match_ccmode (insn, CCNOmode)
8399             && !(INTVAL (operands[3]) & ~127)))"
8400   [(set (match_dup 0)
8401         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8402                          (const_int 0)]))]
8403   "operands[2] = gen_lowpart (QImode, operands[2]);
8404    operands[3] = gen_lowpart (QImode, operands[3]);")
8405
8406
8407 ;; %%% This used to optimize known byte-wide and operations to memory,
8408 ;; and sometimes to QImode registers.  If this is considered useful,
8409 ;; it should be done with splitters.
8410
8411 (define_expand "anddi3"
8412   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8413         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8414                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8415    (clobber (reg:CC FLAGS_REG))]
8416   "TARGET_64BIT"
8417   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8418
8419 (define_insn "*anddi_1_rex64"
8420   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8421         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8422                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8423    (clobber (reg:CC FLAGS_REG))]
8424   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8425 {
8426   switch (get_attr_type (insn))
8427     {
8428     case TYPE_IMOVX:
8429       {
8430         enum machine_mode mode;
8431
8432         gcc_assert (CONST_INT_P (operands[2]));
8433         if (INTVAL (operands[2]) == 0xff)
8434           mode = QImode;
8435         else
8436           {
8437             gcc_assert (INTVAL (operands[2]) == 0xffff);
8438             mode = HImode;
8439           }
8440
8441         operands[1] = gen_lowpart (mode, operands[1]);
8442         if (mode == QImode)
8443           return "movz{bq|x}\t{%1,%0|%0, %1}";
8444         else
8445           return "movz{wq|x}\t{%1,%0|%0, %1}";
8446       }
8447
8448     default:
8449       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8450       if (get_attr_mode (insn) == MODE_SI)
8451         return "and{l}\t{%k2, %k0|%k0, %k2}";
8452       else
8453         return "and{q}\t{%2, %0|%0, %2}";
8454     }
8455 }
8456   [(set_attr "type" "alu,alu,alu,imovx")
8457    (set_attr "length_immediate" "*,*,*,0")
8458    (set_attr "mode" "SI,DI,DI,DI")])
8459
8460 (define_insn "*anddi_2"
8461   [(set (reg FLAGS_REG)
8462         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8463                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8464                  (const_int 0)))
8465    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8466         (and:DI (match_dup 1) (match_dup 2)))]
8467   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8468    && ix86_binary_operator_ok (AND, DImode, operands)"
8469   "@
8470    and{l}\t{%k2, %k0|%k0, %k2}
8471    and{q}\t{%2, %0|%0, %2}
8472    and{q}\t{%2, %0|%0, %2}"
8473   [(set_attr "type" "alu")
8474    (set_attr "mode" "SI,DI,DI")])
8475
8476 (define_expand "andsi3"
8477   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8478         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8479                 (match_operand:SI 2 "general_operand" "")))
8480    (clobber (reg:CC FLAGS_REG))]
8481   ""
8482   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8483
8484 (define_insn "*andsi_1"
8485   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8486         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8487                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8488    (clobber (reg:CC FLAGS_REG))]
8489   "ix86_binary_operator_ok (AND, SImode, operands)"
8490 {
8491   switch (get_attr_type (insn))
8492     {
8493     case TYPE_IMOVX:
8494       {
8495         enum machine_mode mode;
8496
8497         gcc_assert (CONST_INT_P (operands[2]));
8498         if (INTVAL (operands[2]) == 0xff)
8499           mode = QImode;
8500         else
8501           {
8502             gcc_assert (INTVAL (operands[2]) == 0xffff);
8503             mode = HImode;
8504           }
8505
8506         operands[1] = gen_lowpart (mode, operands[1]);
8507         if (mode == QImode)
8508           return "movz{bl|x}\t{%1,%0|%0, %1}";
8509         else
8510           return "movz{wl|x}\t{%1,%0|%0, %1}";
8511       }
8512
8513     default:
8514       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8515       return "and{l}\t{%2, %0|%0, %2}";
8516     }
8517 }
8518   [(set_attr "type" "alu,alu,imovx")
8519    (set_attr "length_immediate" "*,*,0")
8520    (set_attr "mode" "SI")])
8521
8522 (define_split
8523   [(set (match_operand 0 "register_operand" "")
8524         (and (match_dup 0)
8525              (const_int -65536)))
8526    (clobber (reg:CC FLAGS_REG))]
8527   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8528   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8529   "operands[1] = gen_lowpart (HImode, operands[0]);")
8530
8531 (define_split
8532   [(set (match_operand 0 "ext_register_operand" "")
8533         (and (match_dup 0)
8534              (const_int -256)))
8535    (clobber (reg:CC FLAGS_REG))]
8536   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8537   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8538   "operands[1] = gen_lowpart (QImode, operands[0]);")
8539
8540 (define_split
8541   [(set (match_operand 0 "ext_register_operand" "")
8542         (and (match_dup 0)
8543              (const_int -65281)))
8544    (clobber (reg:CC FLAGS_REG))]
8545   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8546   [(parallel [(set (zero_extract:SI (match_dup 0)
8547                                     (const_int 8)
8548                                     (const_int 8))
8549                    (xor:SI
8550                      (zero_extract:SI (match_dup 0)
8551                                       (const_int 8)
8552                                       (const_int 8))
8553                      (zero_extract:SI (match_dup 0)
8554                                       (const_int 8)
8555                                       (const_int 8))))
8556               (clobber (reg:CC FLAGS_REG))])]
8557   "operands[0] = gen_lowpart (SImode, operands[0]);")
8558
8559 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8560 (define_insn "*andsi_1_zext"
8561   [(set (match_operand:DI 0 "register_operand" "=r")
8562         (zero_extend:DI
8563           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8564                   (match_operand:SI 2 "general_operand" "rim"))))
8565    (clobber (reg:CC FLAGS_REG))]
8566   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8567   "and{l}\t{%2, %k0|%k0, %2}"
8568   [(set_attr "type" "alu")
8569    (set_attr "mode" "SI")])
8570
8571 (define_insn "*andsi_2"
8572   [(set (reg FLAGS_REG)
8573         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8574                          (match_operand:SI 2 "general_operand" "rim,ri"))
8575                  (const_int 0)))
8576    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8577         (and:SI (match_dup 1) (match_dup 2)))]
8578   "ix86_match_ccmode (insn, CCNOmode)
8579    && ix86_binary_operator_ok (AND, SImode, operands)"
8580   "and{l}\t{%2, %0|%0, %2}"
8581   [(set_attr "type" "alu")
8582    (set_attr "mode" "SI")])
8583
8584 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8585 (define_insn "*andsi_2_zext"
8586   [(set (reg FLAGS_REG)
8587         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8588                          (match_operand:SI 2 "general_operand" "rim"))
8589                  (const_int 0)))
8590    (set (match_operand:DI 0 "register_operand" "=r")
8591         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8592   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8593    && ix86_binary_operator_ok (AND, SImode, operands)"
8594   "and{l}\t{%2, %k0|%k0, %2}"
8595   [(set_attr "type" "alu")
8596    (set_attr "mode" "SI")])
8597
8598 (define_expand "andhi3"
8599   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8600         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8601                 (match_operand:HI 2 "general_operand" "")))
8602    (clobber (reg:CC FLAGS_REG))]
8603   "TARGET_HIMODE_MATH"
8604   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8605
8606 (define_insn "*andhi_1"
8607   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8608         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8609                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8610    (clobber (reg:CC FLAGS_REG))]
8611   "ix86_binary_operator_ok (AND, HImode, operands)"
8612 {
8613   switch (get_attr_type (insn))
8614     {
8615     case TYPE_IMOVX:
8616       gcc_assert (CONST_INT_P (operands[2]));
8617       gcc_assert (INTVAL (operands[2]) == 0xff);
8618       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8619
8620     default:
8621       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8622
8623       return "and{w}\t{%2, %0|%0, %2}";
8624     }
8625 }
8626   [(set_attr "type" "alu,alu,imovx")
8627    (set_attr "length_immediate" "*,*,0")
8628    (set_attr "mode" "HI,HI,SI")])
8629
8630 (define_insn "*andhi_2"
8631   [(set (reg FLAGS_REG)
8632         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8633                          (match_operand:HI 2 "general_operand" "rim,ri"))
8634                  (const_int 0)))
8635    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8636         (and:HI (match_dup 1) (match_dup 2)))]
8637   "ix86_match_ccmode (insn, CCNOmode)
8638    && ix86_binary_operator_ok (AND, HImode, operands)"
8639   "and{w}\t{%2, %0|%0, %2}"
8640   [(set_attr "type" "alu")
8641    (set_attr "mode" "HI")])
8642
8643 (define_expand "andqi3"
8644   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8645         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8646                 (match_operand:QI 2 "general_operand" "")))
8647    (clobber (reg:CC FLAGS_REG))]
8648   "TARGET_QIMODE_MATH"
8649   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8650
8651 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8652 (define_insn "*andqi_1"
8653   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8654         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8655                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8656    (clobber (reg:CC FLAGS_REG))]
8657   "ix86_binary_operator_ok (AND, QImode, operands)"
8658   "@
8659    and{b}\t{%2, %0|%0, %2}
8660    and{b}\t{%2, %0|%0, %2}
8661    and{l}\t{%k2, %k0|%k0, %k2}"
8662   [(set_attr "type" "alu")
8663    (set_attr "mode" "QI,QI,SI")])
8664
8665 (define_insn "*andqi_1_slp"
8666   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8667         (and:QI (match_dup 0)
8668                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8669    (clobber (reg:CC FLAGS_REG))]
8670   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8671    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8672   "and{b}\t{%1, %0|%0, %1}"
8673   [(set_attr "type" "alu1")
8674    (set_attr "mode" "QI")])
8675
8676 (define_insn "*andqi_2_maybe_si"
8677   [(set (reg FLAGS_REG)
8678         (compare (and:QI
8679                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8680                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8681                  (const_int 0)))
8682    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8683         (and:QI (match_dup 1) (match_dup 2)))]
8684   "ix86_binary_operator_ok (AND, QImode, operands)
8685    && ix86_match_ccmode (insn,
8686                          CONST_INT_P (operands[2])
8687                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8688 {
8689   if (which_alternative == 2)
8690     {
8691       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8692         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8693       return "and{l}\t{%2, %k0|%k0, %2}";
8694     }
8695   return "and{b}\t{%2, %0|%0, %2}";
8696 }
8697   [(set_attr "type" "alu")
8698    (set_attr "mode" "QI,QI,SI")])
8699
8700 (define_insn "*andqi_2"
8701   [(set (reg FLAGS_REG)
8702         (compare (and:QI
8703                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8704                    (match_operand:QI 2 "general_operand" "qim,qi"))
8705                  (const_int 0)))
8706    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8707         (and:QI (match_dup 1) (match_dup 2)))]
8708   "ix86_match_ccmode (insn, CCNOmode)
8709    && ix86_binary_operator_ok (AND, QImode, operands)"
8710   "and{b}\t{%2, %0|%0, %2}"
8711   [(set_attr "type" "alu")
8712    (set_attr "mode" "QI")])
8713
8714 (define_insn "*andqi_2_slp"
8715   [(set (reg FLAGS_REG)
8716         (compare (and:QI
8717                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8718                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8719                  (const_int 0)))
8720    (set (strict_low_part (match_dup 0))
8721         (and:QI (match_dup 0) (match_dup 1)))]
8722   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8723    && ix86_match_ccmode (insn, CCNOmode)
8724    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8725   "and{b}\t{%1, %0|%0, %1}"
8726   [(set_attr "type" "alu1")
8727    (set_attr "mode" "QI")])
8728
8729 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8730 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8731 ;; for a QImode operand, which of course failed.
8732
8733 (define_insn "andqi_ext_0"
8734   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8735                          (const_int 8)
8736                          (const_int 8))
8737         (and:SI
8738           (zero_extract:SI
8739             (match_operand 1 "ext_register_operand" "0")
8740             (const_int 8)
8741             (const_int 8))
8742           (match_operand 2 "const_int_operand" "n")))
8743    (clobber (reg:CC FLAGS_REG))]
8744   ""
8745   "and{b}\t{%2, %h0|%h0, %2}"
8746   [(set_attr "type" "alu")
8747    (set_attr "length_immediate" "1")
8748    (set_attr "mode" "QI")])
8749
8750 ;; Generated by peephole translating test to and.  This shows up
8751 ;; often in fp comparisons.
8752
8753 (define_insn "*andqi_ext_0_cc"
8754   [(set (reg FLAGS_REG)
8755         (compare
8756           (and:SI
8757             (zero_extract:SI
8758               (match_operand 1 "ext_register_operand" "0")
8759               (const_int 8)
8760               (const_int 8))
8761             (match_operand 2 "const_int_operand" "n"))
8762           (const_int 0)))
8763    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8764                          (const_int 8)
8765                          (const_int 8))
8766         (and:SI
8767           (zero_extract:SI
8768             (match_dup 1)
8769             (const_int 8)
8770             (const_int 8))
8771           (match_dup 2)))]
8772   "ix86_match_ccmode (insn, CCNOmode)"
8773   "and{b}\t{%2, %h0|%h0, %2}"
8774   [(set_attr "type" "alu")
8775    (set_attr "length_immediate" "1")
8776    (set_attr "mode" "QI")])
8777
8778 (define_insn "*andqi_ext_1"
8779   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8780                          (const_int 8)
8781                          (const_int 8))
8782         (and:SI
8783           (zero_extract:SI
8784             (match_operand 1 "ext_register_operand" "0")
8785             (const_int 8)
8786             (const_int 8))
8787           (zero_extend:SI
8788             (match_operand:QI 2 "general_operand" "Qm"))))
8789    (clobber (reg:CC FLAGS_REG))]
8790   "!TARGET_64BIT"
8791   "and{b}\t{%2, %h0|%h0, %2}"
8792   [(set_attr "type" "alu")
8793    (set_attr "length_immediate" "0")
8794    (set_attr "mode" "QI")])
8795
8796 (define_insn "*andqi_ext_1_rex64"
8797   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8798                          (const_int 8)
8799                          (const_int 8))
8800         (and:SI
8801           (zero_extract:SI
8802             (match_operand 1 "ext_register_operand" "0")
8803             (const_int 8)
8804             (const_int 8))
8805           (zero_extend:SI
8806             (match_operand 2 "ext_register_operand" "Q"))))
8807    (clobber (reg:CC FLAGS_REG))]
8808   "TARGET_64BIT"
8809   "and{b}\t{%2, %h0|%h0, %2}"
8810   [(set_attr "type" "alu")
8811    (set_attr "length_immediate" "0")
8812    (set_attr "mode" "QI")])
8813
8814 (define_insn "*andqi_ext_2"
8815   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8816                          (const_int 8)
8817                          (const_int 8))
8818         (and:SI
8819           (zero_extract:SI
8820             (match_operand 1 "ext_register_operand" "%0")
8821             (const_int 8)
8822             (const_int 8))
8823           (zero_extract:SI
8824             (match_operand 2 "ext_register_operand" "Q")
8825             (const_int 8)
8826             (const_int 8))))
8827    (clobber (reg:CC FLAGS_REG))]
8828   ""
8829   "and{b}\t{%h2, %h0|%h0, %h2}"
8830   [(set_attr "type" "alu")
8831    (set_attr "length_immediate" "0")
8832    (set_attr "mode" "QI")])
8833
8834 ;; Convert wide AND instructions with immediate operand to shorter QImode
8835 ;; equivalents when possible.
8836 ;; Don't do the splitting with memory operands, since it introduces risk
8837 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8838 ;; for size, but that can (should?) be handled by generic code instead.
8839 (define_split
8840   [(set (match_operand 0 "register_operand" "")
8841         (and (match_operand 1 "register_operand" "")
8842              (match_operand 2 "const_int_operand" "")))
8843    (clobber (reg:CC FLAGS_REG))]
8844    "reload_completed
8845     && QI_REG_P (operands[0])
8846     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8847     && !(~INTVAL (operands[2]) & ~(255 << 8))
8848     && GET_MODE (operands[0]) != QImode"
8849   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8850                    (and:SI (zero_extract:SI (match_dup 1)
8851                                             (const_int 8) (const_int 8))
8852                            (match_dup 2)))
8853               (clobber (reg:CC FLAGS_REG))])]
8854   "operands[0] = gen_lowpart (SImode, operands[0]);
8855    operands[1] = gen_lowpart (SImode, operands[1]);
8856    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8857
8858 ;; Since AND can be encoded with sign extended immediate, this is only
8859 ;; profitable when 7th bit is not set.
8860 (define_split
8861   [(set (match_operand 0 "register_operand" "")
8862         (and (match_operand 1 "general_operand" "")
8863              (match_operand 2 "const_int_operand" "")))
8864    (clobber (reg:CC FLAGS_REG))]
8865    "reload_completed
8866     && ANY_QI_REG_P (operands[0])
8867     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8868     && !(~INTVAL (operands[2]) & ~255)
8869     && !(INTVAL (operands[2]) & 128)
8870     && GET_MODE (operands[0]) != QImode"
8871   [(parallel [(set (strict_low_part (match_dup 0))
8872                    (and:QI (match_dup 1)
8873                            (match_dup 2)))
8874               (clobber (reg:CC FLAGS_REG))])]
8875   "operands[0] = gen_lowpart (QImode, operands[0]);
8876    operands[1] = gen_lowpart (QImode, operands[1]);
8877    operands[2] = gen_lowpart (QImode, operands[2]);")
8878 \f
8879 ;; Logical inclusive OR instructions
8880
8881 ;; %%% This used to optimize known byte-wide and operations to memory.
8882 ;; If this is considered useful, it should be done with splitters.
8883
8884 (define_expand "iordi3"
8885   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8886         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8887                 (match_operand:DI 2 "x86_64_general_operand" "")))
8888    (clobber (reg:CC FLAGS_REG))]
8889   "TARGET_64BIT"
8890   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8891
8892 (define_insn "*iordi_1_rex64"
8893   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8894         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8895                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8896    (clobber (reg:CC FLAGS_REG))]
8897   "TARGET_64BIT
8898    && ix86_binary_operator_ok (IOR, DImode, operands)"
8899   "or{q}\t{%2, %0|%0, %2}"
8900   [(set_attr "type" "alu")
8901    (set_attr "mode" "DI")])
8902
8903 (define_insn "*iordi_2_rex64"
8904   [(set (reg FLAGS_REG)
8905         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8906                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8907                  (const_int 0)))
8908    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8909         (ior:DI (match_dup 1) (match_dup 2)))]
8910   "TARGET_64BIT
8911    && ix86_match_ccmode (insn, CCNOmode)
8912    && ix86_binary_operator_ok (IOR, DImode, operands)"
8913   "or{q}\t{%2, %0|%0, %2}"
8914   [(set_attr "type" "alu")
8915    (set_attr "mode" "DI")])
8916
8917 (define_insn "*iordi_3_rex64"
8918   [(set (reg FLAGS_REG)
8919         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8920                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8921                  (const_int 0)))
8922    (clobber (match_scratch:DI 0 "=r"))]
8923   "TARGET_64BIT
8924    && ix86_match_ccmode (insn, CCNOmode)
8925    && ix86_binary_operator_ok (IOR, DImode, operands)"
8926   "or{q}\t{%2, %0|%0, %2}"
8927   [(set_attr "type" "alu")
8928    (set_attr "mode" "DI")])
8929
8930
8931 (define_expand "iorsi3"
8932   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8933         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8934                 (match_operand:SI 2 "general_operand" "")))
8935    (clobber (reg:CC FLAGS_REG))]
8936   ""
8937   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8938
8939 (define_insn "*iorsi_1"
8940   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8941         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8942                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8943    (clobber (reg:CC FLAGS_REG))]
8944   "ix86_binary_operator_ok (IOR, SImode, operands)"
8945   "or{l}\t{%2, %0|%0, %2}"
8946   [(set_attr "type" "alu")
8947    (set_attr "mode" "SI")])
8948
8949 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8950 (define_insn "*iorsi_1_zext"
8951   [(set (match_operand:DI 0 "register_operand" "=rm")
8952         (zero_extend:DI
8953           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8954                   (match_operand:SI 2 "general_operand" "rim"))))
8955    (clobber (reg:CC FLAGS_REG))]
8956   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8957   "or{l}\t{%2, %k0|%k0, %2}"
8958   [(set_attr "type" "alu")
8959    (set_attr "mode" "SI")])
8960
8961 (define_insn "*iorsi_1_zext_imm"
8962   [(set (match_operand:DI 0 "register_operand" "=rm")
8963         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8964                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8965    (clobber (reg:CC FLAGS_REG))]
8966   "TARGET_64BIT"
8967   "or{l}\t{%2, %k0|%k0, %2}"
8968   [(set_attr "type" "alu")
8969    (set_attr "mode" "SI")])
8970
8971 (define_insn "*iorsi_2"
8972   [(set (reg FLAGS_REG)
8973         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8974                          (match_operand:SI 2 "general_operand" "rim,ri"))
8975                  (const_int 0)))
8976    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8977         (ior:SI (match_dup 1) (match_dup 2)))]
8978   "ix86_match_ccmode (insn, CCNOmode)
8979    && ix86_binary_operator_ok (IOR, SImode, operands)"
8980   "or{l}\t{%2, %0|%0, %2}"
8981   [(set_attr "type" "alu")
8982    (set_attr "mode" "SI")])
8983
8984 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8985 ;; ??? Special case for immediate operand is missing - it is tricky.
8986 (define_insn "*iorsi_2_zext"
8987   [(set (reg FLAGS_REG)
8988         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8989                          (match_operand:SI 2 "general_operand" "rim"))
8990                  (const_int 0)))
8991    (set (match_operand:DI 0 "register_operand" "=r")
8992         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8993   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8994    && ix86_binary_operator_ok (IOR, SImode, operands)"
8995   "or{l}\t{%2, %k0|%k0, %2}"
8996   [(set_attr "type" "alu")
8997    (set_attr "mode" "SI")])
8998
8999 (define_insn "*iorsi_2_zext_imm"
9000   [(set (reg FLAGS_REG)
9001         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9002                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9003                  (const_int 0)))
9004    (set (match_operand:DI 0 "register_operand" "=r")
9005         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9006   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9007    && ix86_binary_operator_ok (IOR, SImode, operands)"
9008   "or{l}\t{%2, %k0|%k0, %2}"
9009   [(set_attr "type" "alu")
9010    (set_attr "mode" "SI")])
9011
9012 (define_insn "*iorsi_3"
9013   [(set (reg FLAGS_REG)
9014         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9015                          (match_operand:SI 2 "general_operand" "rim"))
9016                  (const_int 0)))
9017    (clobber (match_scratch:SI 0 "=r"))]
9018   "ix86_match_ccmode (insn, CCNOmode)
9019    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9020   "or{l}\t{%2, %0|%0, %2}"
9021   [(set_attr "type" "alu")
9022    (set_attr "mode" "SI")])
9023
9024 (define_expand "iorhi3"
9025   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9026         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9027                 (match_operand:HI 2 "general_operand" "")))
9028    (clobber (reg:CC FLAGS_REG))]
9029   "TARGET_HIMODE_MATH"
9030   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9031
9032 (define_insn "*iorhi_1"
9033   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9034         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9035                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9036    (clobber (reg:CC FLAGS_REG))]
9037   "ix86_binary_operator_ok (IOR, HImode, operands)"
9038   "or{w}\t{%2, %0|%0, %2}"
9039   [(set_attr "type" "alu")
9040    (set_attr "mode" "HI")])
9041
9042 (define_insn "*iorhi_2"
9043   [(set (reg FLAGS_REG)
9044         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9045                          (match_operand:HI 2 "general_operand" "rim,ri"))
9046                  (const_int 0)))
9047    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9048         (ior:HI (match_dup 1) (match_dup 2)))]
9049   "ix86_match_ccmode (insn, CCNOmode)
9050    && ix86_binary_operator_ok (IOR, HImode, operands)"
9051   "or{w}\t{%2, %0|%0, %2}"
9052   [(set_attr "type" "alu")
9053    (set_attr "mode" "HI")])
9054
9055 (define_insn "*iorhi_3"
9056   [(set (reg FLAGS_REG)
9057         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9058                          (match_operand:HI 2 "general_operand" "rim"))
9059                  (const_int 0)))
9060    (clobber (match_scratch:HI 0 "=r"))]
9061   "ix86_match_ccmode (insn, CCNOmode)
9062    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9063   "or{w}\t{%2, %0|%0, %2}"
9064   [(set_attr "type" "alu")
9065    (set_attr "mode" "HI")])
9066
9067 (define_expand "iorqi3"
9068   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9069         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9070                 (match_operand:QI 2 "general_operand" "")))
9071    (clobber (reg:CC FLAGS_REG))]
9072   "TARGET_QIMODE_MATH"
9073   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9074
9075 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9076 (define_insn "*iorqi_1"
9077   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9078         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9079                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9080    (clobber (reg:CC FLAGS_REG))]
9081   "ix86_binary_operator_ok (IOR, QImode, operands)"
9082   "@
9083    or{b}\t{%2, %0|%0, %2}
9084    or{b}\t{%2, %0|%0, %2}
9085    or{l}\t{%k2, %k0|%k0, %k2}"
9086   [(set_attr "type" "alu")
9087    (set_attr "mode" "QI,QI,SI")])
9088
9089 (define_insn "*iorqi_1_slp"
9090   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9091         (ior:QI (match_dup 0)
9092                 (match_operand:QI 1 "general_operand" "qmi,qi")))
9093    (clobber (reg:CC FLAGS_REG))]
9094   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9095    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9096   "or{b}\t{%1, %0|%0, %1}"
9097   [(set_attr "type" "alu1")
9098    (set_attr "mode" "QI")])
9099
9100 (define_insn "*iorqi_2"
9101   [(set (reg FLAGS_REG)
9102         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9103                          (match_operand:QI 2 "general_operand" "qim,qi"))
9104                  (const_int 0)))
9105    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9106         (ior:QI (match_dup 1) (match_dup 2)))]
9107   "ix86_match_ccmode (insn, CCNOmode)
9108    && ix86_binary_operator_ok (IOR, QImode, operands)"
9109   "or{b}\t{%2, %0|%0, %2}"
9110   [(set_attr "type" "alu")
9111    (set_attr "mode" "QI")])
9112
9113 (define_insn "*iorqi_2_slp"
9114   [(set (reg FLAGS_REG)
9115         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9116                          (match_operand:QI 1 "general_operand" "qim,qi"))
9117                  (const_int 0)))
9118    (set (strict_low_part (match_dup 0))
9119         (ior:QI (match_dup 0) (match_dup 1)))]
9120   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9121    && ix86_match_ccmode (insn, CCNOmode)
9122    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9123   "or{b}\t{%1, %0|%0, %1}"
9124   [(set_attr "type" "alu1")
9125    (set_attr "mode" "QI")])
9126
9127 (define_insn "*iorqi_3"
9128   [(set (reg FLAGS_REG)
9129         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9130                          (match_operand:QI 2 "general_operand" "qim"))
9131                  (const_int 0)))
9132    (clobber (match_scratch:QI 0 "=q"))]
9133   "ix86_match_ccmode (insn, CCNOmode)
9134    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9135   "or{b}\t{%2, %0|%0, %2}"
9136   [(set_attr "type" "alu")
9137    (set_attr "mode" "QI")])
9138
9139 (define_insn "iorqi_ext_0"
9140   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9141                          (const_int 8)
9142                          (const_int 8))
9143         (ior:SI
9144           (zero_extract:SI
9145             (match_operand 1 "ext_register_operand" "0")
9146             (const_int 8)
9147             (const_int 8))
9148           (match_operand 2 "const_int_operand" "n")))
9149    (clobber (reg:CC FLAGS_REG))]
9150   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9151   "or{b}\t{%2, %h0|%h0, %2}"
9152   [(set_attr "type" "alu")
9153    (set_attr "length_immediate" "1")
9154    (set_attr "mode" "QI")])
9155
9156 (define_insn "*iorqi_ext_1"
9157   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9158                          (const_int 8)
9159                          (const_int 8))
9160         (ior:SI
9161           (zero_extract:SI
9162             (match_operand 1 "ext_register_operand" "0")
9163             (const_int 8)
9164             (const_int 8))
9165           (zero_extend:SI
9166             (match_operand:QI 2 "general_operand" "Qm"))))
9167    (clobber (reg:CC FLAGS_REG))]
9168   "!TARGET_64BIT
9169    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9170   "or{b}\t{%2, %h0|%h0, %2}"
9171   [(set_attr "type" "alu")
9172    (set_attr "length_immediate" "0")
9173    (set_attr "mode" "QI")])
9174
9175 (define_insn "*iorqi_ext_1_rex64"
9176   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9177                          (const_int 8)
9178                          (const_int 8))
9179         (ior:SI
9180           (zero_extract:SI
9181             (match_operand 1 "ext_register_operand" "0")
9182             (const_int 8)
9183             (const_int 8))
9184           (zero_extend:SI
9185             (match_operand 2 "ext_register_operand" "Q"))))
9186    (clobber (reg:CC FLAGS_REG))]
9187   "TARGET_64BIT
9188    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9189   "or{b}\t{%2, %h0|%h0, %2}"
9190   [(set_attr "type" "alu")
9191    (set_attr "length_immediate" "0")
9192    (set_attr "mode" "QI")])
9193
9194 (define_insn "*iorqi_ext_2"
9195   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9196                          (const_int 8)
9197                          (const_int 8))
9198         (ior:SI
9199           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9200                            (const_int 8)
9201                            (const_int 8))
9202           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9203                            (const_int 8)
9204                            (const_int 8))))
9205    (clobber (reg:CC FLAGS_REG))]
9206   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9207   "ior{b}\t{%h2, %h0|%h0, %h2}"
9208   [(set_attr "type" "alu")
9209    (set_attr "length_immediate" "0")
9210    (set_attr "mode" "QI")])
9211
9212 (define_split
9213   [(set (match_operand 0 "register_operand" "")
9214         (ior (match_operand 1 "register_operand" "")
9215              (match_operand 2 "const_int_operand" "")))
9216    (clobber (reg:CC FLAGS_REG))]
9217    "reload_completed
9218     && QI_REG_P (operands[0])
9219     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9220     && !(INTVAL (operands[2]) & ~(255 << 8))
9221     && GET_MODE (operands[0]) != QImode"
9222   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9223                    (ior:SI (zero_extract:SI (match_dup 1)
9224                                             (const_int 8) (const_int 8))
9225                            (match_dup 2)))
9226               (clobber (reg:CC FLAGS_REG))])]
9227   "operands[0] = gen_lowpart (SImode, operands[0]);
9228    operands[1] = gen_lowpart (SImode, operands[1]);
9229    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9230
9231 ;; Since OR can be encoded with sign extended immediate, this is only
9232 ;; profitable when 7th bit is set.
9233 (define_split
9234   [(set (match_operand 0 "register_operand" "")
9235         (ior (match_operand 1 "general_operand" "")
9236              (match_operand 2 "const_int_operand" "")))
9237    (clobber (reg:CC FLAGS_REG))]
9238    "reload_completed
9239     && ANY_QI_REG_P (operands[0])
9240     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9241     && !(INTVAL (operands[2]) & ~255)
9242     && (INTVAL (operands[2]) & 128)
9243     && GET_MODE (operands[0]) != QImode"
9244   [(parallel [(set (strict_low_part (match_dup 0))
9245                    (ior:QI (match_dup 1)
9246                            (match_dup 2)))
9247               (clobber (reg:CC FLAGS_REG))])]
9248   "operands[0] = gen_lowpart (QImode, operands[0]);
9249    operands[1] = gen_lowpart (QImode, operands[1]);
9250    operands[2] = gen_lowpart (QImode, operands[2]);")
9251 \f
9252 ;; Logical XOR instructions
9253
9254 ;; %%% This used to optimize known byte-wide and operations to memory.
9255 ;; If this is considered useful, it should be done with splitters.
9256
9257 (define_expand "xordi3"
9258   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9259         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9260                 (match_operand:DI 2 "x86_64_general_operand" "")))
9261    (clobber (reg:CC FLAGS_REG))]
9262   "TARGET_64BIT"
9263   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9264
9265 (define_insn "*xordi_1_rex64"
9266   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9267         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9268                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9269    (clobber (reg:CC FLAGS_REG))]
9270   "TARGET_64BIT
9271    && ix86_binary_operator_ok (XOR, DImode, operands)"
9272   "@
9273    xor{q}\t{%2, %0|%0, %2}
9274    xor{q}\t{%2, %0|%0, %2}"
9275   [(set_attr "type" "alu")
9276    (set_attr "mode" "DI,DI")])
9277
9278 (define_insn "*xordi_2_rex64"
9279   [(set (reg FLAGS_REG)
9280         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9281                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9282                  (const_int 0)))
9283    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9284         (xor:DI (match_dup 1) (match_dup 2)))]
9285   "TARGET_64BIT
9286    && ix86_match_ccmode (insn, CCNOmode)
9287    && ix86_binary_operator_ok (XOR, DImode, operands)"
9288   "@
9289    xor{q}\t{%2, %0|%0, %2}
9290    xor{q}\t{%2, %0|%0, %2}"
9291   [(set_attr "type" "alu")
9292    (set_attr "mode" "DI,DI")])
9293
9294 (define_insn "*xordi_3_rex64"
9295   [(set (reg FLAGS_REG)
9296         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9297                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9298                  (const_int 0)))
9299    (clobber (match_scratch:DI 0 "=r"))]
9300   "TARGET_64BIT
9301    && ix86_match_ccmode (insn, CCNOmode)
9302    && ix86_binary_operator_ok (XOR, DImode, operands)"
9303   "xor{q}\t{%2, %0|%0, %2}"
9304   [(set_attr "type" "alu")
9305    (set_attr "mode" "DI")])
9306
9307 (define_expand "xorsi3"
9308   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9309         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9310                 (match_operand:SI 2 "general_operand" "")))
9311    (clobber (reg:CC FLAGS_REG))]
9312   ""
9313   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9314
9315 (define_insn "*xorsi_1"
9316   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9317         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9318                 (match_operand:SI 2 "general_operand" "ri,rm")))
9319    (clobber (reg:CC FLAGS_REG))]
9320   "ix86_binary_operator_ok (XOR, SImode, operands)"
9321   "xor{l}\t{%2, %0|%0, %2}"
9322   [(set_attr "type" "alu")
9323    (set_attr "mode" "SI")])
9324
9325 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9326 ;; Add speccase for immediates
9327 (define_insn "*xorsi_1_zext"
9328   [(set (match_operand:DI 0 "register_operand" "=r")
9329         (zero_extend:DI
9330           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9331                   (match_operand:SI 2 "general_operand" "rim"))))
9332    (clobber (reg:CC FLAGS_REG))]
9333   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9334   "xor{l}\t{%2, %k0|%k0, %2}"
9335   [(set_attr "type" "alu")
9336    (set_attr "mode" "SI")])
9337
9338 (define_insn "*xorsi_1_zext_imm"
9339   [(set (match_operand:DI 0 "register_operand" "=r")
9340         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9341                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9342    (clobber (reg:CC FLAGS_REG))]
9343   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9344   "xor{l}\t{%2, %k0|%k0, %2}"
9345   [(set_attr "type" "alu")
9346    (set_attr "mode" "SI")])
9347
9348 (define_insn "*xorsi_2"
9349   [(set (reg FLAGS_REG)
9350         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9351                          (match_operand:SI 2 "general_operand" "rim,ri"))
9352                  (const_int 0)))
9353    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9354         (xor:SI (match_dup 1) (match_dup 2)))]
9355   "ix86_match_ccmode (insn, CCNOmode)
9356    && ix86_binary_operator_ok (XOR, SImode, operands)"
9357   "xor{l}\t{%2, %0|%0, %2}"
9358   [(set_attr "type" "alu")
9359    (set_attr "mode" "SI")])
9360
9361 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9362 ;; ??? Special case for immediate operand is missing - it is tricky.
9363 (define_insn "*xorsi_2_zext"
9364   [(set (reg FLAGS_REG)
9365         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9366                          (match_operand:SI 2 "general_operand" "rim"))
9367                  (const_int 0)))
9368    (set (match_operand:DI 0 "register_operand" "=r")
9369         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9370   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9371    && ix86_binary_operator_ok (XOR, SImode, operands)"
9372   "xor{l}\t{%2, %k0|%k0, %2}"
9373   [(set_attr "type" "alu")
9374    (set_attr "mode" "SI")])
9375
9376 (define_insn "*xorsi_2_zext_imm"
9377   [(set (reg FLAGS_REG)
9378         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9379                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9380                  (const_int 0)))
9381    (set (match_operand:DI 0 "register_operand" "=r")
9382         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9383   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9384    && ix86_binary_operator_ok (XOR, SImode, operands)"
9385   "xor{l}\t{%2, %k0|%k0, %2}"
9386   [(set_attr "type" "alu")
9387    (set_attr "mode" "SI")])
9388
9389 (define_insn "*xorsi_3"
9390   [(set (reg FLAGS_REG)
9391         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9392                          (match_operand:SI 2 "general_operand" "rim"))
9393                  (const_int 0)))
9394    (clobber (match_scratch:SI 0 "=r"))]
9395   "ix86_match_ccmode (insn, CCNOmode)
9396    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9397   "xor{l}\t{%2, %0|%0, %2}"
9398   [(set_attr "type" "alu")
9399    (set_attr "mode" "SI")])
9400
9401 (define_expand "xorhi3"
9402   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9403         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9404                 (match_operand:HI 2 "general_operand" "")))
9405    (clobber (reg:CC FLAGS_REG))]
9406   "TARGET_HIMODE_MATH"
9407   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9408
9409 (define_insn "*xorhi_1"
9410   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9411         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9412                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9413    (clobber (reg:CC FLAGS_REG))]
9414   "ix86_binary_operator_ok (XOR, HImode, operands)"
9415   "xor{w}\t{%2, %0|%0, %2}"
9416   [(set_attr "type" "alu")
9417    (set_attr "mode" "HI")])
9418
9419 (define_insn "*xorhi_2"
9420   [(set (reg FLAGS_REG)
9421         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9422                          (match_operand:HI 2 "general_operand" "rim,ri"))
9423                  (const_int 0)))
9424    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9425         (xor:HI (match_dup 1) (match_dup 2)))]
9426   "ix86_match_ccmode (insn, CCNOmode)
9427    && ix86_binary_operator_ok (XOR, HImode, operands)"
9428   "xor{w}\t{%2, %0|%0, %2}"
9429   [(set_attr "type" "alu")
9430    (set_attr "mode" "HI")])
9431
9432 (define_insn "*xorhi_3"
9433   [(set (reg FLAGS_REG)
9434         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9435                          (match_operand:HI 2 "general_operand" "rim"))
9436                  (const_int 0)))
9437    (clobber (match_scratch:HI 0 "=r"))]
9438   "ix86_match_ccmode (insn, CCNOmode)
9439    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9440   "xor{w}\t{%2, %0|%0, %2}"
9441   [(set_attr "type" "alu")
9442    (set_attr "mode" "HI")])
9443
9444 (define_expand "xorqi3"
9445   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9446         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9447                 (match_operand:QI 2 "general_operand" "")))
9448    (clobber (reg:CC FLAGS_REG))]
9449   "TARGET_QIMODE_MATH"
9450   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9451
9452 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9453 (define_insn "*xorqi_1"
9454   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9455         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9456                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9457    (clobber (reg:CC FLAGS_REG))]
9458   "ix86_binary_operator_ok (XOR, QImode, operands)"
9459   "@
9460    xor{b}\t{%2, %0|%0, %2}
9461    xor{b}\t{%2, %0|%0, %2}
9462    xor{l}\t{%k2, %k0|%k0, %k2}"
9463   [(set_attr "type" "alu")
9464    (set_attr "mode" "QI,QI,SI")])
9465
9466 (define_insn "*xorqi_1_slp"
9467   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9468         (xor:QI (match_dup 0)
9469                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9470    (clobber (reg:CC FLAGS_REG))]
9471   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9472    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9473   "xor{b}\t{%1, %0|%0, %1}"
9474   [(set_attr "type" "alu1")
9475    (set_attr "mode" "QI")])
9476
9477 (define_insn "xorqi_ext_0"
9478   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9479                          (const_int 8)
9480                          (const_int 8))
9481         (xor:SI
9482           (zero_extract:SI
9483             (match_operand 1 "ext_register_operand" "0")
9484             (const_int 8)
9485             (const_int 8))
9486           (match_operand 2 "const_int_operand" "n")))
9487    (clobber (reg:CC FLAGS_REG))]
9488   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9489   "xor{b}\t{%2, %h0|%h0, %2}"
9490   [(set_attr "type" "alu")
9491    (set_attr "length_immediate" "1")
9492    (set_attr "mode" "QI")])
9493
9494 (define_insn "*xorqi_ext_1"
9495   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9496                          (const_int 8)
9497                          (const_int 8))
9498         (xor:SI
9499           (zero_extract:SI
9500             (match_operand 1 "ext_register_operand" "0")
9501             (const_int 8)
9502             (const_int 8))
9503           (zero_extend:SI
9504             (match_operand:QI 2 "general_operand" "Qm"))))
9505    (clobber (reg:CC FLAGS_REG))]
9506   "!TARGET_64BIT
9507    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9508   "xor{b}\t{%2, %h0|%h0, %2}"
9509   [(set_attr "type" "alu")
9510    (set_attr "length_immediate" "0")
9511    (set_attr "mode" "QI")])
9512
9513 (define_insn "*xorqi_ext_1_rex64"
9514   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9515                          (const_int 8)
9516                          (const_int 8))
9517         (xor:SI
9518           (zero_extract:SI
9519             (match_operand 1 "ext_register_operand" "0")
9520             (const_int 8)
9521             (const_int 8))
9522           (zero_extend:SI
9523             (match_operand 2 "ext_register_operand" "Q"))))
9524    (clobber (reg:CC FLAGS_REG))]
9525   "TARGET_64BIT
9526    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9527   "xor{b}\t{%2, %h0|%h0, %2}"
9528   [(set_attr "type" "alu")
9529    (set_attr "length_immediate" "0")
9530    (set_attr "mode" "QI")])
9531
9532 (define_insn "*xorqi_ext_2"
9533   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9534                          (const_int 8)
9535                          (const_int 8))
9536         (xor:SI
9537           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9538                            (const_int 8)
9539                            (const_int 8))
9540           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9541                            (const_int 8)
9542                            (const_int 8))))
9543    (clobber (reg:CC FLAGS_REG))]
9544   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9545   "xor{b}\t{%h2, %h0|%h0, %h2}"
9546   [(set_attr "type" "alu")
9547    (set_attr "length_immediate" "0")
9548    (set_attr "mode" "QI")])
9549
9550 (define_insn "*xorqi_cc_1"
9551   [(set (reg FLAGS_REG)
9552         (compare
9553           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9554                   (match_operand:QI 2 "general_operand" "qim,qi"))
9555           (const_int 0)))
9556    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9557         (xor:QI (match_dup 1) (match_dup 2)))]
9558   "ix86_match_ccmode (insn, CCNOmode)
9559    && ix86_binary_operator_ok (XOR, QImode, operands)"
9560   "xor{b}\t{%2, %0|%0, %2}"
9561   [(set_attr "type" "alu")
9562    (set_attr "mode" "QI")])
9563
9564 (define_insn "*xorqi_2_slp"
9565   [(set (reg FLAGS_REG)
9566         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9567                          (match_operand:QI 1 "general_operand" "qim,qi"))
9568                  (const_int 0)))
9569    (set (strict_low_part (match_dup 0))
9570         (xor:QI (match_dup 0) (match_dup 1)))]
9571   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9572    && ix86_match_ccmode (insn, CCNOmode)
9573    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9574   "xor{b}\t{%1, %0|%0, %1}"
9575   [(set_attr "type" "alu1")
9576    (set_attr "mode" "QI")])
9577
9578 (define_insn "*xorqi_cc_2"
9579   [(set (reg FLAGS_REG)
9580         (compare
9581           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9582                   (match_operand:QI 2 "general_operand" "qim"))
9583           (const_int 0)))
9584    (clobber (match_scratch:QI 0 "=q"))]
9585   "ix86_match_ccmode (insn, CCNOmode)
9586    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9587   "xor{b}\t{%2, %0|%0, %2}"
9588   [(set_attr "type" "alu")
9589    (set_attr "mode" "QI")])
9590
9591 (define_insn "*xorqi_cc_ext_1"
9592   [(set (reg FLAGS_REG)
9593         (compare
9594           (xor:SI
9595             (zero_extract:SI
9596               (match_operand 1 "ext_register_operand" "0")
9597               (const_int 8)
9598               (const_int 8))
9599             (match_operand:QI 2 "general_operand" "qmn"))
9600           (const_int 0)))
9601    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9602                          (const_int 8)
9603                          (const_int 8))
9604         (xor:SI
9605           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9606           (match_dup 2)))]
9607   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9608   "xor{b}\t{%2, %h0|%h0, %2}"
9609   [(set_attr "type" "alu")
9610    (set_attr "mode" "QI")])
9611
9612 (define_insn "*xorqi_cc_ext_1_rex64"
9613   [(set (reg FLAGS_REG)
9614         (compare
9615           (xor:SI
9616             (zero_extract:SI
9617               (match_operand 1 "ext_register_operand" "0")
9618               (const_int 8)
9619               (const_int 8))
9620             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9621           (const_int 0)))
9622    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9623                          (const_int 8)
9624                          (const_int 8))
9625         (xor:SI
9626           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9627           (match_dup 2)))]
9628   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9629   "xor{b}\t{%2, %h0|%h0, %2}"
9630   [(set_attr "type" "alu")
9631    (set_attr "mode" "QI")])
9632
9633 (define_expand "xorqi_cc_ext_1"
9634   [(parallel [
9635      (set (reg:CCNO FLAGS_REG)
9636           (compare:CCNO
9637             (xor:SI
9638               (zero_extract:SI
9639                 (match_operand 1 "ext_register_operand" "")
9640                 (const_int 8)
9641                 (const_int 8))
9642               (match_operand:QI 2 "general_operand" ""))
9643             (const_int 0)))
9644      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9645                            (const_int 8)
9646                            (const_int 8))
9647           (xor:SI
9648             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9649             (match_dup 2)))])]
9650   ""
9651   "")
9652
9653 (define_split
9654   [(set (match_operand 0 "register_operand" "")
9655         (xor (match_operand 1 "register_operand" "")
9656              (match_operand 2 "const_int_operand" "")))
9657    (clobber (reg:CC FLAGS_REG))]
9658    "reload_completed
9659     && QI_REG_P (operands[0])
9660     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9661     && !(INTVAL (operands[2]) & ~(255 << 8))
9662     && GET_MODE (operands[0]) != QImode"
9663   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9664                    (xor:SI (zero_extract:SI (match_dup 1)
9665                                             (const_int 8) (const_int 8))
9666                            (match_dup 2)))
9667               (clobber (reg:CC FLAGS_REG))])]
9668   "operands[0] = gen_lowpart (SImode, operands[0]);
9669    operands[1] = gen_lowpart (SImode, operands[1]);
9670    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9671
9672 ;; Since XOR can be encoded with sign extended immediate, this is only
9673 ;; profitable when 7th bit is set.
9674 (define_split
9675   [(set (match_operand 0 "register_operand" "")
9676         (xor (match_operand 1 "general_operand" "")
9677              (match_operand 2 "const_int_operand" "")))
9678    (clobber (reg:CC FLAGS_REG))]
9679    "reload_completed
9680     && ANY_QI_REG_P (operands[0])
9681     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9682     && !(INTVAL (operands[2]) & ~255)
9683     && (INTVAL (operands[2]) & 128)
9684     && GET_MODE (operands[0]) != QImode"
9685   [(parallel [(set (strict_low_part (match_dup 0))
9686                    (xor:QI (match_dup 1)
9687                            (match_dup 2)))
9688               (clobber (reg:CC FLAGS_REG))])]
9689   "operands[0] = gen_lowpart (QImode, operands[0]);
9690    operands[1] = gen_lowpart (QImode, operands[1]);
9691    operands[2] = gen_lowpart (QImode, operands[2]);")
9692 \f
9693 ;; Negation instructions
9694
9695 (define_expand "negti2"
9696   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9697                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9698               (clobber (reg:CC FLAGS_REG))])]
9699   "TARGET_64BIT"
9700   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9701
9702 (define_insn "*negti2_1"
9703   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9704         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9705    (clobber (reg:CC FLAGS_REG))]
9706   "TARGET_64BIT
9707    && ix86_unary_operator_ok (NEG, TImode, operands)"
9708   "#")
9709
9710 (define_split
9711   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9712         (neg:TI (match_operand:TI 1 "general_operand" "")))
9713    (clobber (reg:CC FLAGS_REG))]
9714   "TARGET_64BIT && reload_completed"
9715   [(parallel
9716     [(set (reg:CCZ FLAGS_REG)
9717           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9718      (set (match_dup 0) (neg:DI (match_dup 2)))])
9719    (parallel
9720     [(set (match_dup 1)
9721           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9722                             (match_dup 3))
9723                    (const_int 0)))
9724      (clobber (reg:CC FLAGS_REG))])
9725    (parallel
9726     [(set (match_dup 1)
9727           (neg:DI (match_dup 1)))
9728      (clobber (reg:CC FLAGS_REG))])]
9729   "split_ti (operands+1, 1, operands+2, operands+3);
9730    split_ti (operands+0, 1, operands+0, operands+1);")
9731
9732 (define_expand "negdi2"
9733   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9734                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9735               (clobber (reg:CC FLAGS_REG))])]
9736   ""
9737   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9738
9739 (define_insn "*negdi2_1"
9740   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9741         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9742    (clobber (reg:CC FLAGS_REG))]
9743   "!TARGET_64BIT
9744    && ix86_unary_operator_ok (NEG, DImode, operands)"
9745   "#")
9746
9747 (define_split
9748   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9749         (neg:DI (match_operand:DI 1 "general_operand" "")))
9750    (clobber (reg:CC FLAGS_REG))]
9751   "!TARGET_64BIT && reload_completed"
9752   [(parallel
9753     [(set (reg:CCZ FLAGS_REG)
9754           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9755      (set (match_dup 0) (neg:SI (match_dup 2)))])
9756    (parallel
9757     [(set (match_dup 1)
9758           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9759                             (match_dup 3))
9760                    (const_int 0)))
9761      (clobber (reg:CC FLAGS_REG))])
9762    (parallel
9763     [(set (match_dup 1)
9764           (neg:SI (match_dup 1)))
9765      (clobber (reg:CC FLAGS_REG))])]
9766   "split_di (operands+1, 1, operands+2, operands+3);
9767    split_di (operands+0, 1, operands+0, operands+1);")
9768
9769 (define_insn "*negdi2_1_rex64"
9770   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9771         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9772    (clobber (reg:CC FLAGS_REG))]
9773   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9774   "neg{q}\t%0"
9775   [(set_attr "type" "negnot")
9776    (set_attr "mode" "DI")])
9777
9778 ;; The problem with neg is that it does not perform (compare x 0),
9779 ;; it really performs (compare 0 x), which leaves us with the zero
9780 ;; flag being the only useful item.
9781
9782 (define_insn "*negdi2_cmpz_rex64"
9783   [(set (reg:CCZ FLAGS_REG)
9784         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9785                      (const_int 0)))
9786    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9787         (neg:DI (match_dup 1)))]
9788   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9789   "neg{q}\t%0"
9790   [(set_attr "type" "negnot")
9791    (set_attr "mode" "DI")])
9792
9793
9794 (define_expand "negsi2"
9795   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9796                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9797               (clobber (reg:CC FLAGS_REG))])]
9798   ""
9799   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9800
9801 (define_insn "*negsi2_1"
9802   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9803         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9804    (clobber (reg:CC FLAGS_REG))]
9805   "ix86_unary_operator_ok (NEG, SImode, operands)"
9806   "neg{l}\t%0"
9807   [(set_attr "type" "negnot")
9808    (set_attr "mode" "SI")])
9809
9810 ;; Combine is quite creative about this pattern.
9811 (define_insn "*negsi2_1_zext"
9812   [(set (match_operand:DI 0 "register_operand" "=r")
9813         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9814                                         (const_int 32)))
9815                      (const_int 32)))
9816    (clobber (reg:CC FLAGS_REG))]
9817   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9818   "neg{l}\t%k0"
9819   [(set_attr "type" "negnot")
9820    (set_attr "mode" "SI")])
9821
9822 ;; The problem with neg is that it does not perform (compare x 0),
9823 ;; it really performs (compare 0 x), which leaves us with the zero
9824 ;; flag being the only useful item.
9825
9826 (define_insn "*negsi2_cmpz"
9827   [(set (reg:CCZ FLAGS_REG)
9828         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9829                      (const_int 0)))
9830    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9831         (neg:SI (match_dup 1)))]
9832   "ix86_unary_operator_ok (NEG, SImode, operands)"
9833   "neg{l}\t%0"
9834   [(set_attr "type" "negnot")
9835    (set_attr "mode" "SI")])
9836
9837 (define_insn "*negsi2_cmpz_zext"
9838   [(set (reg:CCZ FLAGS_REG)
9839         (compare:CCZ (lshiftrt:DI
9840                        (neg:DI (ashift:DI
9841                                  (match_operand:DI 1 "register_operand" "0")
9842                                  (const_int 32)))
9843                        (const_int 32))
9844                      (const_int 0)))
9845    (set (match_operand:DI 0 "register_operand" "=r")
9846         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9847                                         (const_int 32)))
9848                      (const_int 32)))]
9849   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9850   "neg{l}\t%k0"
9851   [(set_attr "type" "negnot")
9852    (set_attr "mode" "SI")])
9853
9854 (define_expand "neghi2"
9855   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9856                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9857               (clobber (reg:CC FLAGS_REG))])]
9858   "TARGET_HIMODE_MATH"
9859   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9860
9861 (define_insn "*neghi2_1"
9862   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9863         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9864    (clobber (reg:CC FLAGS_REG))]
9865   "ix86_unary_operator_ok (NEG, HImode, operands)"
9866   "neg{w}\t%0"
9867   [(set_attr "type" "negnot")
9868    (set_attr "mode" "HI")])
9869
9870 (define_insn "*neghi2_cmpz"
9871   [(set (reg:CCZ FLAGS_REG)
9872         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9873                      (const_int 0)))
9874    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9875         (neg:HI (match_dup 1)))]
9876   "ix86_unary_operator_ok (NEG, HImode, operands)"
9877   "neg{w}\t%0"
9878   [(set_attr "type" "negnot")
9879    (set_attr "mode" "HI")])
9880
9881 (define_expand "negqi2"
9882   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9883                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9884               (clobber (reg:CC FLAGS_REG))])]
9885   "TARGET_QIMODE_MATH"
9886   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9887
9888 (define_insn "*negqi2_1"
9889   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9890         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9891    (clobber (reg:CC FLAGS_REG))]
9892   "ix86_unary_operator_ok (NEG, QImode, operands)"
9893   "neg{b}\t%0"
9894   [(set_attr "type" "negnot")
9895    (set_attr "mode" "QI")])
9896
9897 (define_insn "*negqi2_cmpz"
9898   [(set (reg:CCZ FLAGS_REG)
9899         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9900                      (const_int 0)))
9901    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9902         (neg:QI (match_dup 1)))]
9903   "ix86_unary_operator_ok (NEG, QImode, operands)"
9904   "neg{b}\t%0"
9905   [(set_attr "type" "negnot")
9906    (set_attr "mode" "QI")])
9907
9908 ;; Changing of sign for FP values is doable using integer unit too.
9909
9910 (define_expand "negsf2"
9911   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9912         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9913   "TARGET_80387 || TARGET_SSE_MATH"
9914   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9915
9916 (define_expand "abssf2"
9917   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9918         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9919   "TARGET_80387 || TARGET_SSE_MATH"
9920   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9921
9922 (define_insn "*absnegsf2_mixed"
9923   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9924         (match_operator:SF 3 "absneg_operator"
9925           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9926    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9927    (clobber (reg:CC FLAGS_REG))]
9928   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9929    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9930   "#")
9931
9932 (define_insn "*absnegsf2_sse"
9933   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9934         (match_operator:SF 3 "absneg_operator"
9935           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9936    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9937    (clobber (reg:CC FLAGS_REG))]
9938   "TARGET_SSE_MATH
9939    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9940   "#")
9941
9942 (define_insn "*absnegsf2_i387"
9943   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9944         (match_operator:SF 3 "absneg_operator"
9945           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9946    (use (match_operand 2 "" ""))
9947    (clobber (reg:CC FLAGS_REG))]
9948   "TARGET_80387 && !TARGET_SSE_MATH
9949    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9950   "#")
9951
9952 (define_expand "copysignsf3"
9953   [(match_operand:SF 0 "register_operand" "")
9954    (match_operand:SF 1 "nonmemory_operand" "")
9955    (match_operand:SF 2 "register_operand" "")]
9956   "TARGET_SSE_MATH"
9957 {
9958   ix86_expand_copysign (operands);
9959   DONE;
9960 })
9961
9962 (define_insn_and_split "copysignsf3_const"
9963   [(set (match_operand:SF 0 "register_operand"          "=x")
9964         (unspec:SF
9965           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9966            (match_operand:SF 2 "register_operand"       "0")
9967            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9968           UNSPEC_COPYSIGN))]
9969   "TARGET_SSE_MATH"
9970   "#"
9971   "&& reload_completed"
9972   [(const_int 0)]
9973 {
9974   ix86_split_copysign_const (operands);
9975   DONE;
9976 })
9977
9978 (define_insn "copysignsf3_var"
9979   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9980         (unspec:SF
9981           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9982            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9983            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9984            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9985           UNSPEC_COPYSIGN))
9986    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9987   "TARGET_SSE_MATH"
9988   "#")
9989
9990 (define_split
9991   [(set (match_operand:SF 0 "register_operand" "")
9992         (unspec:SF
9993           [(match_operand:SF 2 "register_operand" "")
9994            (match_operand:SF 3 "register_operand" "")
9995            (match_operand:V4SF 4 "" "")
9996            (match_operand:V4SF 5 "" "")]
9997           UNSPEC_COPYSIGN))
9998    (clobber (match_scratch:V4SF 1 ""))]
9999   "TARGET_SSE_MATH && reload_completed"
10000   [(const_int 0)]
10001 {
10002   ix86_split_copysign_var (operands);
10003   DONE;
10004 })
10005
10006 (define_expand "negdf2"
10007   [(set (match_operand:DF 0 "nonimmediate_operand" "")
10008         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
10009   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
10010   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
10011
10012 (define_expand "absdf2"
10013   [(set (match_operand:DF 0 "nonimmediate_operand" "")
10014         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
10015   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
10016   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
10017
10018 (define_insn "*absnegdf2_mixed"
10019   [(set (match_operand:DF 0 "nonimmediate_operand"    "=x,x,f,rm")
10020         (match_operator:DF 3 "absneg_operator"
10021           [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0,0")]))
10022    (use (match_operand:V2DF 2 "nonimmediate_operand"  "xm,0,X,X"))
10023    (clobber (reg:CC FLAGS_REG))]
10024   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
10025    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10026   "#")
10027
10028 (define_insn "*absnegdf2_sse"
10029   [(set (match_operand:DF 0 "nonimmediate_operand"    "=x,x,rm")
10030         (match_operator:DF 3 "absneg_operator"
10031           [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0 ")]))
10032    (use (match_operand:V2DF 2 "nonimmediate_operand"  "xm,0,X "))
10033    (clobber (reg:CC FLAGS_REG))]
10034   "TARGET_SSE2 && TARGET_SSE_MATH
10035    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10036   "#")
10037
10038 (define_insn "*absnegdf2_i387"
10039   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
10040         (match_operator:DF 3 "absneg_operator"
10041           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
10042    (use (match_operand 2 "" ""))
10043    (clobber (reg:CC FLAGS_REG))]
10044   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
10045    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10046   "#")
10047
10048 (define_expand "copysigndf3"
10049   [(match_operand:DF 0 "register_operand" "")
10050    (match_operand:DF 1 "nonmemory_operand" "")
10051    (match_operand:DF 2 "register_operand" "")]
10052   "TARGET_SSE2 && TARGET_SSE_MATH"
10053 {
10054   ix86_expand_copysign (operands);
10055   DONE;
10056 })
10057
10058 (define_insn_and_split "copysigndf3_const"
10059   [(set (match_operand:DF 0 "register_operand"          "=x")
10060         (unspec:DF
10061           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
10062            (match_operand:DF 2 "register_operand"       "0")
10063            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
10064           UNSPEC_COPYSIGN))]
10065   "TARGET_SSE2 && TARGET_SSE_MATH"
10066   "#"
10067   "&& reload_completed"
10068   [(const_int 0)]
10069 {
10070   ix86_split_copysign_const (operands);
10071   DONE;
10072 })
10073
10074 (define_insn "copysigndf3_var"
10075   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
10076         (unspec:DF
10077           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
10078            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
10079            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
10080            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
10081           UNSPEC_COPYSIGN))
10082    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
10083   "TARGET_SSE2 && TARGET_SSE_MATH"
10084   "#")
10085
10086 (define_split
10087   [(set (match_operand:DF 0 "register_operand" "")
10088         (unspec:DF
10089           [(match_operand:DF 2 "register_operand" "")
10090            (match_operand:DF 3 "register_operand" "")
10091            (match_operand:V2DF 4 "" "")
10092            (match_operand:V2DF 5 "" "")]
10093           UNSPEC_COPYSIGN))
10094    (clobber (match_scratch:V2DF 1 ""))]
10095   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
10096   [(const_int 0)]
10097 {
10098   ix86_split_copysign_var (operands);
10099   DONE;
10100 })
10101
10102 (define_expand "negxf2"
10103   [(set (match_operand:XF 0 "nonimmediate_operand" "")
10104         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10105   "TARGET_80387"
10106   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
10107
10108 (define_expand "absxf2"
10109   [(set (match_operand:XF 0 "nonimmediate_operand" "")
10110         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10111   "TARGET_80387"
10112   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
10113
10114 (define_insn "*absnegxf2_i387"
10115   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
10116         (match_operator:XF 3 "absneg_operator"
10117           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
10118    (use (match_operand 2 "" ""))
10119    (clobber (reg:CC FLAGS_REG))]
10120   "TARGET_80387
10121    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
10122   "#")
10123
10124 ;; Splitters for fp abs and neg.
10125
10126 (define_split
10127   [(set (match_operand 0 "fp_register_operand" "")
10128         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10129    (use (match_operand 2 "" ""))
10130    (clobber (reg:CC FLAGS_REG))]
10131   "reload_completed"
10132   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10133
10134 (define_split
10135   [(set (match_operand 0 "register_operand" "")
10136         (match_operator 3 "absneg_operator"
10137           [(match_operand 1 "register_operand" "")]))
10138    (use (match_operand 2 "nonimmediate_operand" ""))
10139    (clobber (reg:CC FLAGS_REG))]
10140   "reload_completed && SSE_REG_P (operands[0])"
10141   [(set (match_dup 0) (match_dup 3))]
10142 {
10143   enum machine_mode mode = GET_MODE (operands[0]);
10144   enum machine_mode vmode = GET_MODE (operands[2]);
10145   rtx tmp;
10146
10147   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10148   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10149   if (operands_match_p (operands[0], operands[2]))
10150     {
10151       tmp = operands[1];
10152       operands[1] = operands[2];
10153       operands[2] = tmp;
10154     }
10155   if (GET_CODE (operands[3]) == ABS)
10156     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10157   else
10158     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10159   operands[3] = tmp;
10160 })
10161
10162 (define_split
10163   [(set (match_operand:SF 0 "register_operand" "")
10164         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10165    (use (match_operand:V4SF 2 "" ""))
10166    (clobber (reg:CC FLAGS_REG))]
10167   "reload_completed"
10168   [(parallel [(set (match_dup 0) (match_dup 1))
10169               (clobber (reg:CC FLAGS_REG))])]
10170 {
10171   rtx tmp;
10172   operands[0] = gen_lowpart (SImode, operands[0]);
10173   if (GET_CODE (operands[1]) == ABS)
10174     {
10175       tmp = gen_int_mode (0x7fffffff, SImode);
10176       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10177     }
10178   else
10179     {
10180       tmp = gen_int_mode (0x80000000, SImode);
10181       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10182     }
10183   operands[1] = tmp;
10184 })
10185
10186 (define_split
10187   [(set (match_operand:DF 0 "register_operand" "")
10188         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10189    (use (match_operand 2 "" ""))
10190    (clobber (reg:CC FLAGS_REG))]
10191   "reload_completed"
10192   [(parallel [(set (match_dup 0) (match_dup 1))
10193               (clobber (reg:CC FLAGS_REG))])]
10194 {
10195   rtx tmp;
10196   if (TARGET_64BIT)
10197     {
10198       tmp = gen_lowpart (DImode, operands[0]);
10199       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10200       operands[0] = tmp;
10201
10202       if (GET_CODE (operands[1]) == ABS)
10203         tmp = const0_rtx;
10204       else
10205         tmp = gen_rtx_NOT (DImode, tmp);
10206     }
10207   else
10208     {
10209       operands[0] = gen_highpart (SImode, operands[0]);
10210       if (GET_CODE (operands[1]) == ABS)
10211         {
10212           tmp = gen_int_mode (0x7fffffff, SImode);
10213           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10214         }
10215       else
10216         {
10217           tmp = gen_int_mode (0x80000000, SImode);
10218           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10219         }
10220     }
10221   operands[1] = tmp;
10222 })
10223
10224 (define_split
10225   [(set (match_operand:XF 0 "register_operand" "")
10226         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10227    (use (match_operand 2 "" ""))
10228    (clobber (reg:CC FLAGS_REG))]
10229   "reload_completed"
10230   [(parallel [(set (match_dup 0) (match_dup 1))
10231               (clobber (reg:CC FLAGS_REG))])]
10232 {
10233   rtx tmp;
10234   operands[0] = gen_rtx_REG (SImode,
10235                              true_regnum (operands[0])
10236                              + (TARGET_64BIT ? 1 : 2));
10237   if (GET_CODE (operands[1]) == ABS)
10238     {
10239       tmp = GEN_INT (0x7fff);
10240       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10241     }
10242   else
10243     {
10244       tmp = GEN_INT (0x8000);
10245       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10246     }
10247   operands[1] = tmp;
10248 })
10249
10250 (define_split
10251   [(set (match_operand 0 "memory_operand" "")
10252         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10253    (use (match_operand 2 "" ""))
10254    (clobber (reg:CC FLAGS_REG))]
10255   "reload_completed"
10256   [(parallel [(set (match_dup 0) (match_dup 1))
10257               (clobber (reg:CC FLAGS_REG))])]
10258 {
10259   enum machine_mode mode = GET_MODE (operands[0]);
10260   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
10261   rtx tmp;
10262
10263   operands[0] = adjust_address (operands[0], QImode, size - 1);
10264   if (GET_CODE (operands[1]) == ABS)
10265     {
10266       tmp = gen_int_mode (0x7f, QImode);
10267       tmp = gen_rtx_AND (QImode, operands[0], tmp);
10268     }
10269   else
10270     {
10271       tmp = gen_int_mode (0x80, QImode);
10272       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
10273     }
10274   operands[1] = tmp;
10275 })
10276
10277 ;; Conditionalize these after reload. If they match before reload, we
10278 ;; lose the clobber and ability to use integer instructions.
10279
10280 (define_insn "*negsf2_1"
10281   [(set (match_operand:SF 0 "register_operand" "=f")
10282         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10283   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10284   "fchs"
10285   [(set_attr "type" "fsgn")
10286    (set_attr "mode" "SF")])
10287
10288 (define_insn "*negdf2_1"
10289   [(set (match_operand:DF 0 "register_operand" "=f")
10290         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10291   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10292   "fchs"
10293   [(set_attr "type" "fsgn")
10294    (set_attr "mode" "DF")])
10295
10296 (define_insn "*negxf2_1"
10297   [(set (match_operand:XF 0 "register_operand" "=f")
10298         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10299   "TARGET_80387"
10300   "fchs"
10301   [(set_attr "type" "fsgn")
10302    (set_attr "mode" "XF")])
10303
10304 (define_insn "*abssf2_1"
10305   [(set (match_operand:SF 0 "register_operand" "=f")
10306         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10307   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10308   "fabs"
10309   [(set_attr "type" "fsgn")
10310    (set_attr "mode" "SF")])
10311
10312 (define_insn "*absdf2_1"
10313   [(set (match_operand:DF 0 "register_operand" "=f")
10314         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10315   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10316   "fabs"
10317   [(set_attr "type" "fsgn")
10318    (set_attr "mode" "DF")])
10319
10320 (define_insn "*absxf2_1"
10321   [(set (match_operand:XF 0 "register_operand" "=f")
10322         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10323   "TARGET_80387"
10324   "fabs"
10325   [(set_attr "type" "fsgn")
10326    (set_attr "mode" "DF")])
10327
10328 (define_insn "*negextendsfdf2"
10329   [(set (match_operand:DF 0 "register_operand" "=f")
10330         (neg:DF (float_extend:DF
10331                   (match_operand:SF 1 "register_operand" "0"))))]
10332   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10333   "fchs"
10334   [(set_attr "type" "fsgn")
10335    (set_attr "mode" "DF")])
10336
10337 (define_insn "*negextenddfxf2"
10338   [(set (match_operand:XF 0 "register_operand" "=f")
10339         (neg:XF (float_extend:XF
10340                   (match_operand:DF 1 "register_operand" "0"))))]
10341   "TARGET_80387"
10342   "fchs"
10343   [(set_attr "type" "fsgn")
10344    (set_attr "mode" "XF")])
10345
10346 (define_insn "*negextendsfxf2"
10347   [(set (match_operand:XF 0 "register_operand" "=f")
10348         (neg:XF (float_extend:XF
10349                   (match_operand:SF 1 "register_operand" "0"))))]
10350   "TARGET_80387"
10351   "fchs"
10352   [(set_attr "type" "fsgn")
10353    (set_attr "mode" "XF")])
10354
10355 (define_insn "*absextendsfdf2"
10356   [(set (match_operand:DF 0 "register_operand" "=f")
10357         (abs:DF (float_extend:DF
10358                   (match_operand:SF 1 "register_operand" "0"))))]
10359   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10360   "fabs"
10361   [(set_attr "type" "fsgn")
10362    (set_attr "mode" "DF")])
10363
10364 (define_insn "*absextenddfxf2"
10365   [(set (match_operand:XF 0 "register_operand" "=f")
10366         (abs:XF (float_extend:XF
10367           (match_operand:DF 1 "register_operand" "0"))))]
10368   "TARGET_80387"
10369   "fabs"
10370   [(set_attr "type" "fsgn")
10371    (set_attr "mode" "XF")])
10372
10373 (define_insn "*absextendsfxf2"
10374   [(set (match_operand:XF 0 "register_operand" "=f")
10375         (abs:XF (float_extend:XF
10376           (match_operand:SF 1 "register_operand" "0"))))]
10377   "TARGET_80387"
10378   "fabs"
10379   [(set_attr "type" "fsgn")
10380    (set_attr "mode" "XF")])
10381 \f
10382 ;; One complement instructions
10383
10384 (define_expand "one_cmpldi2"
10385   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10386         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10387   "TARGET_64BIT"
10388   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10389
10390 (define_insn "*one_cmpldi2_1_rex64"
10391   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10392         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10393   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10394   "not{q}\t%0"
10395   [(set_attr "type" "negnot")
10396    (set_attr "mode" "DI")])
10397
10398 (define_insn "*one_cmpldi2_2_rex64"
10399   [(set (reg FLAGS_REG)
10400         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10401                  (const_int 0)))
10402    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10403         (not:DI (match_dup 1)))]
10404   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10405    && ix86_unary_operator_ok (NOT, DImode, operands)"
10406   "#"
10407   [(set_attr "type" "alu1")
10408    (set_attr "mode" "DI")])
10409
10410 (define_split
10411   [(set (match_operand 0 "flags_reg_operand" "")
10412         (match_operator 2 "compare_operator"
10413           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10414            (const_int 0)]))
10415    (set (match_operand:DI 1 "nonimmediate_operand" "")
10416         (not:DI (match_dup 3)))]
10417   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10418   [(parallel [(set (match_dup 0)
10419                    (match_op_dup 2
10420                      [(xor:DI (match_dup 3) (const_int -1))
10421                       (const_int 0)]))
10422               (set (match_dup 1)
10423                    (xor:DI (match_dup 3) (const_int -1)))])]
10424   "")
10425
10426 (define_expand "one_cmplsi2"
10427   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10428         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10429   ""
10430   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10431
10432 (define_insn "*one_cmplsi2_1"
10433   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10434         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10435   "ix86_unary_operator_ok (NOT, SImode, operands)"
10436   "not{l}\t%0"
10437   [(set_attr "type" "negnot")
10438    (set_attr "mode" "SI")])
10439
10440 ;; ??? Currently never generated - xor is used instead.
10441 (define_insn "*one_cmplsi2_1_zext"
10442   [(set (match_operand:DI 0 "register_operand" "=r")
10443         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10444   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10445   "not{l}\t%k0"
10446   [(set_attr "type" "negnot")
10447    (set_attr "mode" "SI")])
10448
10449 (define_insn "*one_cmplsi2_2"
10450   [(set (reg FLAGS_REG)
10451         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10452                  (const_int 0)))
10453    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10454         (not:SI (match_dup 1)))]
10455   "ix86_match_ccmode (insn, CCNOmode)
10456    && ix86_unary_operator_ok (NOT, SImode, operands)"
10457   "#"
10458   [(set_attr "type" "alu1")
10459    (set_attr "mode" "SI")])
10460
10461 (define_split
10462   [(set (match_operand 0 "flags_reg_operand" "")
10463         (match_operator 2 "compare_operator"
10464           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10465            (const_int 0)]))
10466    (set (match_operand:SI 1 "nonimmediate_operand" "")
10467         (not:SI (match_dup 3)))]
10468   "ix86_match_ccmode (insn, CCNOmode)"
10469   [(parallel [(set (match_dup 0)
10470                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10471                                     (const_int 0)]))
10472               (set (match_dup 1)
10473                    (xor:SI (match_dup 3) (const_int -1)))])]
10474   "")
10475
10476 ;; ??? Currently never generated - xor is used instead.
10477 (define_insn "*one_cmplsi2_2_zext"
10478   [(set (reg FLAGS_REG)
10479         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10480                  (const_int 0)))
10481    (set (match_operand:DI 0 "register_operand" "=r")
10482         (zero_extend:DI (not:SI (match_dup 1))))]
10483   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10484    && ix86_unary_operator_ok (NOT, SImode, operands)"
10485   "#"
10486   [(set_attr "type" "alu1")
10487    (set_attr "mode" "SI")])
10488
10489 (define_split
10490   [(set (match_operand 0 "flags_reg_operand" "")
10491         (match_operator 2 "compare_operator"
10492           [(not:SI (match_operand:SI 3 "register_operand" ""))
10493            (const_int 0)]))
10494    (set (match_operand:DI 1 "register_operand" "")
10495         (zero_extend:DI (not:SI (match_dup 3))))]
10496   "ix86_match_ccmode (insn, CCNOmode)"
10497   [(parallel [(set (match_dup 0)
10498                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10499                                     (const_int 0)]))
10500               (set (match_dup 1)
10501                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10502   "")
10503
10504 (define_expand "one_cmplhi2"
10505   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10506         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10507   "TARGET_HIMODE_MATH"
10508   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10509
10510 (define_insn "*one_cmplhi2_1"
10511   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10512         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10513   "ix86_unary_operator_ok (NOT, HImode, operands)"
10514   "not{w}\t%0"
10515   [(set_attr "type" "negnot")
10516    (set_attr "mode" "HI")])
10517
10518 (define_insn "*one_cmplhi2_2"
10519   [(set (reg FLAGS_REG)
10520         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10521                  (const_int 0)))
10522    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10523         (not:HI (match_dup 1)))]
10524   "ix86_match_ccmode (insn, CCNOmode)
10525    && ix86_unary_operator_ok (NEG, HImode, operands)"
10526   "#"
10527   [(set_attr "type" "alu1")
10528    (set_attr "mode" "HI")])
10529
10530 (define_split
10531   [(set (match_operand 0 "flags_reg_operand" "")
10532         (match_operator 2 "compare_operator"
10533           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10534            (const_int 0)]))
10535    (set (match_operand:HI 1 "nonimmediate_operand" "")
10536         (not:HI (match_dup 3)))]
10537   "ix86_match_ccmode (insn, CCNOmode)"
10538   [(parallel [(set (match_dup 0)
10539                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10540                                     (const_int 0)]))
10541               (set (match_dup 1)
10542                    (xor:HI (match_dup 3) (const_int -1)))])]
10543   "")
10544
10545 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10546 (define_expand "one_cmplqi2"
10547   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10548         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10549   "TARGET_QIMODE_MATH"
10550   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10551
10552 (define_insn "*one_cmplqi2_1"
10553   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10554         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10555   "ix86_unary_operator_ok (NOT, QImode, operands)"
10556   "@
10557    not{b}\t%0
10558    not{l}\t%k0"
10559   [(set_attr "type" "negnot")
10560    (set_attr "mode" "QI,SI")])
10561
10562 (define_insn "*one_cmplqi2_2"
10563   [(set (reg FLAGS_REG)
10564         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10565                  (const_int 0)))
10566    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10567         (not:QI (match_dup 1)))]
10568   "ix86_match_ccmode (insn, CCNOmode)
10569    && ix86_unary_operator_ok (NOT, QImode, operands)"
10570   "#"
10571   [(set_attr "type" "alu1")
10572    (set_attr "mode" "QI")])
10573
10574 (define_split
10575   [(set (match_operand 0 "flags_reg_operand" "")
10576         (match_operator 2 "compare_operator"
10577           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10578            (const_int 0)]))
10579    (set (match_operand:QI 1 "nonimmediate_operand" "")
10580         (not:QI (match_dup 3)))]
10581   "ix86_match_ccmode (insn, CCNOmode)"
10582   [(parallel [(set (match_dup 0)
10583                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10584                                     (const_int 0)]))
10585               (set (match_dup 1)
10586                    (xor:QI (match_dup 3) (const_int -1)))])]
10587   "")
10588 \f
10589 ;; Arithmetic shift instructions
10590
10591 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10592 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10593 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10594 ;; from the assembler input.
10595 ;;
10596 ;; This instruction shifts the target reg/mem as usual, but instead of
10597 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10598 ;; is a left shift double, bits are taken from the high order bits of
10599 ;; reg, else if the insn is a shift right double, bits are taken from the
10600 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10601 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10602 ;;
10603 ;; Since sh[lr]d does not change the `reg' operand, that is done
10604 ;; separately, making all shifts emit pairs of shift double and normal
10605 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10606 ;; support a 63 bit shift, each shift where the count is in a reg expands
10607 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10608 ;;
10609 ;; If the shift count is a constant, we need never emit more than one
10610 ;; shift pair, instead using moves and sign extension for counts greater
10611 ;; than 31.
10612
10613 (define_expand "ashlti3"
10614   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10615                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10616                               (match_operand:QI 2 "nonmemory_operand" "")))
10617               (clobber (reg:CC FLAGS_REG))])]
10618   "TARGET_64BIT"
10619 {
10620   if (! immediate_operand (operands[2], QImode))
10621     {
10622       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10623       DONE;
10624     }
10625   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10626   DONE;
10627 })
10628
10629 (define_insn "ashlti3_1"
10630   [(set (match_operand:TI 0 "register_operand" "=r")
10631         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10632                    (match_operand:QI 2 "register_operand" "c")))
10633    (clobber (match_scratch:DI 3 "=&r"))
10634    (clobber (reg:CC FLAGS_REG))]
10635   "TARGET_64BIT"
10636   "#"
10637   [(set_attr "type" "multi")])
10638
10639 (define_insn "*ashlti3_2"
10640   [(set (match_operand:TI 0 "register_operand" "=r")
10641         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10642                    (match_operand:QI 2 "immediate_operand" "O")))
10643    (clobber (reg:CC FLAGS_REG))]
10644   "TARGET_64BIT"
10645   "#"
10646   [(set_attr "type" "multi")])
10647
10648 (define_split
10649   [(set (match_operand:TI 0 "register_operand" "")
10650         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10651                    (match_operand:QI 2 "register_operand" "")))
10652    (clobber (match_scratch:DI 3 ""))
10653    (clobber (reg:CC FLAGS_REG))]
10654   "TARGET_64BIT && reload_completed"
10655   [(const_int 0)]
10656   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10657
10658 (define_split
10659   [(set (match_operand:TI 0 "register_operand" "")
10660         (ashift:TI (match_operand:TI 1 "register_operand" "")
10661                    (match_operand:QI 2 "immediate_operand" "")))
10662    (clobber (reg:CC FLAGS_REG))]
10663   "TARGET_64BIT && reload_completed"
10664   [(const_int 0)]
10665   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10666
10667 (define_insn "x86_64_shld"
10668   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10669         (ior:DI (ashift:DI (match_dup 0)
10670                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10671                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10672                   (minus:QI (const_int 64) (match_dup 2)))))
10673    (clobber (reg:CC FLAGS_REG))]
10674   "TARGET_64BIT"
10675   "@
10676    shld{q}\t{%2, %1, %0|%0, %1, %2}
10677    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10678   [(set_attr "type" "ishift")
10679    (set_attr "prefix_0f" "1")
10680    (set_attr "mode" "DI")
10681    (set_attr "athlon_decode" "vector")
10682    (set_attr "amdfam10_decode" "vector")])   
10683
10684 (define_expand "x86_64_shift_adj"
10685   [(set (reg:CCZ FLAGS_REG)
10686         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10687                              (const_int 64))
10688                      (const_int 0)))
10689    (set (match_operand:DI 0 "register_operand" "")
10690         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10691                          (match_operand:DI 1 "register_operand" "")
10692                          (match_dup 0)))
10693    (set (match_dup 1)
10694         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10695                          (match_operand:DI 3 "register_operand" "r")
10696                          (match_dup 1)))]
10697   "TARGET_64BIT"
10698   "")
10699
10700 (define_expand "ashldi3"
10701   [(set (match_operand:DI 0 "shiftdi_operand" "")
10702         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10703                    (match_operand:QI 2 "nonmemory_operand" "")))]
10704   ""
10705   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10706
10707 (define_insn "*ashldi3_1_rex64"
10708   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10709         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10710                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10711    (clobber (reg:CC FLAGS_REG))]
10712   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10713 {
10714   switch (get_attr_type (insn))
10715     {
10716     case TYPE_ALU:
10717       gcc_assert (operands[2] == const1_rtx);
10718       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10719       return "add{q}\t%0, %0";
10720
10721     case TYPE_LEA:
10722       gcc_assert (CONST_INT_P (operands[2]));
10723       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10724       operands[1] = gen_rtx_MULT (DImode, operands[1],
10725                                   GEN_INT (1 << INTVAL (operands[2])));
10726       return "lea{q}\t{%a1, %0|%0, %a1}";
10727
10728     default:
10729       if (REG_P (operands[2]))
10730         return "sal{q}\t{%b2, %0|%0, %b2}";
10731       else if (operands[2] == const1_rtx
10732                && (TARGET_SHIFT1 || optimize_size))
10733         return "sal{q}\t%0";
10734       else
10735         return "sal{q}\t{%2, %0|%0, %2}";
10736     }
10737 }
10738   [(set (attr "type")
10739      (cond [(eq_attr "alternative" "1")
10740               (const_string "lea")
10741             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10742                           (const_int 0))
10743                       (match_operand 0 "register_operand" ""))
10744                  (match_operand 2 "const1_operand" ""))
10745               (const_string "alu")
10746            ]
10747            (const_string "ishift")))
10748    (set_attr "mode" "DI")])
10749
10750 ;; Convert lea to the lea pattern to avoid flags dependency.
10751 (define_split
10752   [(set (match_operand:DI 0 "register_operand" "")
10753         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10754                    (match_operand:QI 2 "immediate_operand" "")))
10755    (clobber (reg:CC FLAGS_REG))]
10756   "TARGET_64BIT && reload_completed
10757    && true_regnum (operands[0]) != true_regnum (operands[1])"
10758   [(set (match_dup 0)
10759         (mult:DI (match_dup 1)
10760                  (match_dup 2)))]
10761   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10762
10763 ;; This pattern can't accept a variable shift count, since shifts by
10764 ;; zero don't affect the flags.  We assume that shifts by constant
10765 ;; zero are optimized away.
10766 (define_insn "*ashldi3_cmp_rex64"
10767   [(set (reg FLAGS_REG)
10768         (compare
10769           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10770                      (match_operand:QI 2 "immediate_operand" "e"))
10771           (const_int 0)))
10772    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10773         (ashift:DI (match_dup 1) (match_dup 2)))]
10774   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10775    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10776    && (optimize_size
10777        || !TARGET_PARTIAL_FLAG_REG_STALL
10778        || (operands[2] == const1_rtx
10779            && (TARGET_SHIFT1
10780                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10781 {
10782   switch (get_attr_type (insn))
10783     {
10784     case TYPE_ALU:
10785       gcc_assert (operands[2] == const1_rtx);
10786       return "add{q}\t%0, %0";
10787
10788     default:
10789       if (REG_P (operands[2]))
10790         return "sal{q}\t{%b2, %0|%0, %b2}";
10791       else if (operands[2] == const1_rtx
10792                && (TARGET_SHIFT1 || optimize_size))
10793         return "sal{q}\t%0";
10794       else
10795         return "sal{q}\t{%2, %0|%0, %2}";
10796     }
10797 }
10798   [(set (attr "type")
10799      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10800                           (const_int 0))
10801                       (match_operand 0 "register_operand" ""))
10802                  (match_operand 2 "const1_operand" ""))
10803               (const_string "alu")
10804            ]
10805            (const_string "ishift")))
10806    (set_attr "mode" "DI")])
10807
10808 (define_insn "*ashldi3_cconly_rex64"
10809   [(set (reg FLAGS_REG)
10810         (compare
10811           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10812                      (match_operand:QI 2 "immediate_operand" "e"))
10813           (const_int 0)))
10814    (clobber (match_scratch:DI 0 "=r"))]
10815   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10816    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10817    && (optimize_size
10818        || !TARGET_PARTIAL_FLAG_REG_STALL
10819        || (operands[2] == const1_rtx
10820            && (TARGET_SHIFT1
10821                || TARGET_DOUBLE_WITH_ADD)))"
10822 {
10823   switch (get_attr_type (insn))
10824     {
10825     case TYPE_ALU:
10826       gcc_assert (operands[2] == const1_rtx);
10827       return "add{q}\t%0, %0";
10828
10829     default:
10830       if (REG_P (operands[2]))
10831         return "sal{q}\t{%b2, %0|%0, %b2}";
10832       else if (operands[2] == const1_rtx
10833                && (TARGET_SHIFT1 || optimize_size))
10834         return "sal{q}\t%0";
10835       else
10836         return "sal{q}\t{%2, %0|%0, %2}";
10837     }
10838 }
10839   [(set (attr "type")
10840      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10841                           (const_int 0))
10842                       (match_operand 0 "register_operand" ""))
10843                  (match_operand 2 "const1_operand" ""))
10844               (const_string "alu")
10845            ]
10846            (const_string "ishift")))
10847    (set_attr "mode" "DI")])
10848
10849 (define_insn "*ashldi3_1"
10850   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10851         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10852                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10853    (clobber (reg:CC FLAGS_REG))]
10854   "!TARGET_64BIT"
10855   "#"
10856   [(set_attr "type" "multi")])
10857
10858 ;; By default we don't ask for a scratch register, because when DImode
10859 ;; values are manipulated, registers are already at a premium.  But if
10860 ;; we have one handy, we won't turn it away.
10861 (define_peephole2
10862   [(match_scratch:SI 3 "r")
10863    (parallel [(set (match_operand:DI 0 "register_operand" "")
10864                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10865                               (match_operand:QI 2 "nonmemory_operand" "")))
10866               (clobber (reg:CC FLAGS_REG))])
10867    (match_dup 3)]
10868   "!TARGET_64BIT && TARGET_CMOVE"
10869   [(const_int 0)]
10870   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10871
10872 (define_split
10873   [(set (match_operand:DI 0 "register_operand" "")
10874         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10875                    (match_operand:QI 2 "nonmemory_operand" "")))
10876    (clobber (reg:CC FLAGS_REG))]
10877   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10878                      ? flow2_completed : reload_completed)"
10879   [(const_int 0)]
10880   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10881
10882 (define_insn "x86_shld_1"
10883   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10884         (ior:SI (ashift:SI (match_dup 0)
10885                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10886                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10887                   (minus:QI (const_int 32) (match_dup 2)))))
10888    (clobber (reg:CC FLAGS_REG))]
10889   ""
10890   "@
10891    shld{l}\t{%2, %1, %0|%0, %1, %2}
10892    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10893   [(set_attr "type" "ishift")
10894    (set_attr "prefix_0f" "1")
10895    (set_attr "mode" "SI")
10896    (set_attr "pent_pair" "np")
10897    (set_attr "athlon_decode" "vector")
10898    (set_attr "amdfam10_decode" "vector")])   
10899
10900 (define_expand "x86_shift_adj_1"
10901   [(set (reg:CCZ FLAGS_REG)
10902         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10903                              (const_int 32))
10904                      (const_int 0)))
10905    (set (match_operand:SI 0 "register_operand" "")
10906         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10907                          (match_operand:SI 1 "register_operand" "")
10908                          (match_dup 0)))
10909    (set (match_dup 1)
10910         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10911                          (match_operand:SI 3 "register_operand" "r")
10912                          (match_dup 1)))]
10913   "TARGET_CMOVE"
10914   "")
10915
10916 (define_expand "x86_shift_adj_2"
10917   [(use (match_operand:SI 0 "register_operand" ""))
10918    (use (match_operand:SI 1 "register_operand" ""))
10919    (use (match_operand:QI 2 "register_operand" ""))]
10920   ""
10921 {
10922   rtx label = gen_label_rtx ();
10923   rtx tmp;
10924
10925   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10926
10927   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10928   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10929   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10930                               gen_rtx_LABEL_REF (VOIDmode, label),
10931                               pc_rtx);
10932   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10933   JUMP_LABEL (tmp) = label;
10934
10935   emit_move_insn (operands[0], operands[1]);
10936   ix86_expand_clear (operands[1]);
10937
10938   emit_label (label);
10939   LABEL_NUSES (label) = 1;
10940
10941   DONE;
10942 })
10943
10944 (define_expand "ashlsi3"
10945   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10946         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10947                    (match_operand:QI 2 "nonmemory_operand" "")))
10948    (clobber (reg:CC FLAGS_REG))]
10949   ""
10950   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10951
10952 (define_insn "*ashlsi3_1"
10953   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10954         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10955                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10956    (clobber (reg:CC FLAGS_REG))]
10957   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10958 {
10959   switch (get_attr_type (insn))
10960     {
10961     case TYPE_ALU:
10962       gcc_assert (operands[2] == const1_rtx);
10963       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10964       return "add{l}\t%0, %0";
10965
10966     case TYPE_LEA:
10967       return "#";
10968
10969     default:
10970       if (REG_P (operands[2]))
10971         return "sal{l}\t{%b2, %0|%0, %b2}";
10972       else if (operands[2] == const1_rtx
10973                && (TARGET_SHIFT1 || optimize_size))
10974         return "sal{l}\t%0";
10975       else
10976         return "sal{l}\t{%2, %0|%0, %2}";
10977     }
10978 }
10979   [(set (attr "type")
10980      (cond [(eq_attr "alternative" "1")
10981               (const_string "lea")
10982             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10983                           (const_int 0))
10984                       (match_operand 0 "register_operand" ""))
10985                  (match_operand 2 "const1_operand" ""))
10986               (const_string "alu")
10987            ]
10988            (const_string "ishift")))
10989    (set_attr "mode" "SI")])
10990
10991 ;; Convert lea to the lea pattern to avoid flags dependency.
10992 (define_split
10993   [(set (match_operand 0 "register_operand" "")
10994         (ashift (match_operand 1 "index_register_operand" "")
10995                 (match_operand:QI 2 "const_int_operand" "")))
10996    (clobber (reg:CC FLAGS_REG))]
10997   "reload_completed
10998    && true_regnum (operands[0]) != true_regnum (operands[1])
10999    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11000   [(const_int 0)]
11001 {
11002   rtx pat;
11003   enum machine_mode mode = GET_MODE (operands[0]);
11004
11005   if (GET_MODE_SIZE (mode) < 4)
11006     operands[0] = gen_lowpart (SImode, operands[0]);
11007   if (mode != Pmode)
11008     operands[1] = gen_lowpart (Pmode, operands[1]);
11009   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11010
11011   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11012   if (Pmode != SImode)
11013     pat = gen_rtx_SUBREG (SImode, pat, 0);
11014   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11015   DONE;
11016 })
11017
11018 ;; Rare case of shifting RSP is handled by generating move and shift
11019 (define_split
11020   [(set (match_operand 0 "register_operand" "")
11021         (ashift (match_operand 1 "register_operand" "")
11022                 (match_operand:QI 2 "const_int_operand" "")))
11023    (clobber (reg:CC FLAGS_REG))]
11024   "reload_completed
11025    && true_regnum (operands[0]) != true_regnum (operands[1])"
11026   [(const_int 0)]
11027 {
11028   rtx pat, clob;
11029   emit_move_insn (operands[0], operands[1]);
11030   pat = gen_rtx_SET (VOIDmode, operands[0],
11031                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11032                                      operands[0], operands[2]));
11033   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11034   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11035   DONE;
11036 })
11037
11038 (define_insn "*ashlsi3_1_zext"
11039   [(set (match_operand:DI 0 "register_operand" "=r,r")
11040         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11041                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11042    (clobber (reg:CC FLAGS_REG))]
11043   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11044 {
11045   switch (get_attr_type (insn))
11046     {
11047     case TYPE_ALU:
11048       gcc_assert (operands[2] == const1_rtx);
11049       return "add{l}\t%k0, %k0";
11050
11051     case TYPE_LEA:
11052       return "#";
11053
11054     default:
11055       if (REG_P (operands[2]))
11056         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11057       else if (operands[2] == const1_rtx
11058                && (TARGET_SHIFT1 || optimize_size))
11059         return "sal{l}\t%k0";
11060       else
11061         return "sal{l}\t{%2, %k0|%k0, %2}";
11062     }
11063 }
11064   [(set (attr "type")
11065      (cond [(eq_attr "alternative" "1")
11066               (const_string "lea")
11067             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11068                      (const_int 0))
11069                  (match_operand 2 "const1_operand" ""))
11070               (const_string "alu")
11071            ]
11072            (const_string "ishift")))
11073    (set_attr "mode" "SI")])
11074
11075 ;; Convert lea to the lea pattern to avoid flags dependency.
11076 (define_split
11077   [(set (match_operand:DI 0 "register_operand" "")
11078         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11079                                 (match_operand:QI 2 "const_int_operand" ""))))
11080    (clobber (reg:CC FLAGS_REG))]
11081   "TARGET_64BIT && reload_completed
11082    && true_regnum (operands[0]) != true_regnum (operands[1])"
11083   [(set (match_dup 0) (zero_extend:DI
11084                         (subreg:SI (mult:SI (match_dup 1)
11085                                             (match_dup 2)) 0)))]
11086 {
11087   operands[1] = gen_lowpart (Pmode, operands[1]);
11088   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11089 })
11090
11091 ;; This pattern can't accept a variable shift count, since shifts by
11092 ;; zero don't affect the flags.  We assume that shifts by constant
11093 ;; zero are optimized away.
11094 (define_insn "*ashlsi3_cmp"
11095   [(set (reg FLAGS_REG)
11096         (compare
11097           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11098                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11099           (const_int 0)))
11100    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11101         (ashift:SI (match_dup 1) (match_dup 2)))]
11102   "ix86_match_ccmode (insn, CCGOCmode)
11103    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11104    && (optimize_size
11105        || !TARGET_PARTIAL_FLAG_REG_STALL
11106        || (operands[2] == const1_rtx
11107            && (TARGET_SHIFT1
11108                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11109 {
11110   switch (get_attr_type (insn))
11111     {
11112     case TYPE_ALU:
11113       gcc_assert (operands[2] == const1_rtx);
11114       return "add{l}\t%0, %0";
11115
11116     default:
11117       if (REG_P (operands[2]))
11118         return "sal{l}\t{%b2, %0|%0, %b2}";
11119       else if (operands[2] == const1_rtx
11120                && (TARGET_SHIFT1 || optimize_size))
11121         return "sal{l}\t%0";
11122       else
11123         return "sal{l}\t{%2, %0|%0, %2}";
11124     }
11125 }
11126   [(set (attr "type")
11127      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11128                           (const_int 0))
11129                       (match_operand 0 "register_operand" ""))
11130                  (match_operand 2 "const1_operand" ""))
11131               (const_string "alu")
11132            ]
11133            (const_string "ishift")))
11134    (set_attr "mode" "SI")])
11135
11136 (define_insn "*ashlsi3_cconly"
11137   [(set (reg FLAGS_REG)
11138         (compare
11139           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11140                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11141           (const_int 0)))
11142    (clobber (match_scratch:SI 0 "=r"))]
11143   "ix86_match_ccmode (insn, CCGOCmode)
11144    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11145    && (optimize_size
11146        || !TARGET_PARTIAL_FLAG_REG_STALL
11147        || (operands[2] == const1_rtx
11148            && (TARGET_SHIFT1
11149                || TARGET_DOUBLE_WITH_ADD)))"
11150 {
11151   switch (get_attr_type (insn))
11152     {
11153     case TYPE_ALU:
11154       gcc_assert (operands[2] == const1_rtx);
11155       return "add{l}\t%0, %0";
11156
11157     default:
11158       if (REG_P (operands[2]))
11159         return "sal{l}\t{%b2, %0|%0, %b2}";
11160       else if (operands[2] == const1_rtx
11161                && (TARGET_SHIFT1 || optimize_size))
11162         return "sal{l}\t%0";
11163       else
11164         return "sal{l}\t{%2, %0|%0, %2}";
11165     }
11166 }
11167   [(set (attr "type")
11168      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11169                           (const_int 0))
11170                       (match_operand 0 "register_operand" ""))
11171                  (match_operand 2 "const1_operand" ""))
11172               (const_string "alu")
11173            ]
11174            (const_string "ishift")))
11175    (set_attr "mode" "SI")])
11176
11177 (define_insn "*ashlsi3_cmp_zext"
11178   [(set (reg FLAGS_REG)
11179         (compare
11180           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11181                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11182           (const_int 0)))
11183    (set (match_operand:DI 0 "register_operand" "=r")
11184         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11185   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11186    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11187    && (optimize_size
11188        || !TARGET_PARTIAL_FLAG_REG_STALL
11189        || (operands[2] == const1_rtx
11190            && (TARGET_SHIFT1
11191                || TARGET_DOUBLE_WITH_ADD)))"
11192 {
11193   switch (get_attr_type (insn))
11194     {
11195     case TYPE_ALU:
11196       gcc_assert (operands[2] == const1_rtx);
11197       return "add{l}\t%k0, %k0";
11198
11199     default:
11200       if (REG_P (operands[2]))
11201         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11202       else if (operands[2] == const1_rtx
11203                && (TARGET_SHIFT1 || optimize_size))
11204         return "sal{l}\t%k0";
11205       else
11206         return "sal{l}\t{%2, %k0|%k0, %2}";
11207     }
11208 }
11209   [(set (attr "type")
11210      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11211                      (const_int 0))
11212                  (match_operand 2 "const1_operand" ""))
11213               (const_string "alu")
11214            ]
11215            (const_string "ishift")))
11216    (set_attr "mode" "SI")])
11217
11218 (define_expand "ashlhi3"
11219   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11220         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11221                    (match_operand:QI 2 "nonmemory_operand" "")))
11222    (clobber (reg:CC FLAGS_REG))]
11223   "TARGET_HIMODE_MATH"
11224   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11225
11226 (define_insn "*ashlhi3_1_lea"
11227   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11228         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11229                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11230    (clobber (reg:CC FLAGS_REG))]
11231   "!TARGET_PARTIAL_REG_STALL
11232    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11233 {
11234   switch (get_attr_type (insn))
11235     {
11236     case TYPE_LEA:
11237       return "#";
11238     case TYPE_ALU:
11239       gcc_assert (operands[2] == const1_rtx);
11240       return "add{w}\t%0, %0";
11241
11242     default:
11243       if (REG_P (operands[2]))
11244         return "sal{w}\t{%b2, %0|%0, %b2}";
11245       else if (operands[2] == const1_rtx
11246                && (TARGET_SHIFT1 || optimize_size))
11247         return "sal{w}\t%0";
11248       else
11249         return "sal{w}\t{%2, %0|%0, %2}";
11250     }
11251 }
11252   [(set (attr "type")
11253      (cond [(eq_attr "alternative" "1")
11254               (const_string "lea")
11255             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11256                           (const_int 0))
11257                       (match_operand 0 "register_operand" ""))
11258                  (match_operand 2 "const1_operand" ""))
11259               (const_string "alu")
11260            ]
11261            (const_string "ishift")))
11262    (set_attr "mode" "HI,SI")])
11263
11264 (define_insn "*ashlhi3_1"
11265   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11266         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11267                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11268    (clobber (reg:CC FLAGS_REG))]
11269   "TARGET_PARTIAL_REG_STALL
11270    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11271 {
11272   switch (get_attr_type (insn))
11273     {
11274     case TYPE_ALU:
11275       gcc_assert (operands[2] == const1_rtx);
11276       return "add{w}\t%0, %0";
11277
11278     default:
11279       if (REG_P (operands[2]))
11280         return "sal{w}\t{%b2, %0|%0, %b2}";
11281       else if (operands[2] == const1_rtx
11282                && (TARGET_SHIFT1 || optimize_size))
11283         return "sal{w}\t%0";
11284       else
11285         return "sal{w}\t{%2, %0|%0, %2}";
11286     }
11287 }
11288   [(set (attr "type")
11289      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11290                           (const_int 0))
11291                       (match_operand 0 "register_operand" ""))
11292                  (match_operand 2 "const1_operand" ""))
11293               (const_string "alu")
11294            ]
11295            (const_string "ishift")))
11296    (set_attr "mode" "HI")])
11297
11298 ;; This pattern can't accept a variable shift count, since shifts by
11299 ;; zero don't affect the flags.  We assume that shifts by constant
11300 ;; zero are optimized away.
11301 (define_insn "*ashlhi3_cmp"
11302   [(set (reg FLAGS_REG)
11303         (compare
11304           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11305                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11306           (const_int 0)))
11307    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11308         (ashift:HI (match_dup 1) (match_dup 2)))]
11309   "ix86_match_ccmode (insn, CCGOCmode)
11310    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11311    && (optimize_size
11312        || !TARGET_PARTIAL_FLAG_REG_STALL
11313        || (operands[2] == const1_rtx
11314            && (TARGET_SHIFT1
11315                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11316 {
11317   switch (get_attr_type (insn))
11318     {
11319     case TYPE_ALU:
11320       gcc_assert (operands[2] == const1_rtx);
11321       return "add{w}\t%0, %0";
11322
11323     default:
11324       if (REG_P (operands[2]))
11325         return "sal{w}\t{%b2, %0|%0, %b2}";
11326       else if (operands[2] == const1_rtx
11327                && (TARGET_SHIFT1 || optimize_size))
11328         return "sal{w}\t%0";
11329       else
11330         return "sal{w}\t{%2, %0|%0, %2}";
11331     }
11332 }
11333   [(set (attr "type")
11334      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11335                           (const_int 0))
11336                       (match_operand 0 "register_operand" ""))
11337                  (match_operand 2 "const1_operand" ""))
11338               (const_string "alu")
11339            ]
11340            (const_string "ishift")))
11341    (set_attr "mode" "HI")])
11342
11343 (define_insn "*ashlhi3_cconly"
11344   [(set (reg FLAGS_REG)
11345         (compare
11346           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11347                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11348           (const_int 0)))
11349    (clobber (match_scratch:HI 0 "=r"))]
11350   "ix86_match_ccmode (insn, CCGOCmode)
11351    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11352    && (optimize_size
11353        || !TARGET_PARTIAL_FLAG_REG_STALL
11354        || (operands[2] == const1_rtx
11355            && (TARGET_SHIFT1
11356                || TARGET_DOUBLE_WITH_ADD)))"
11357 {
11358   switch (get_attr_type (insn))
11359     {
11360     case TYPE_ALU:
11361       gcc_assert (operands[2] == const1_rtx);
11362       return "add{w}\t%0, %0";
11363
11364     default:
11365       if (REG_P (operands[2]))
11366         return "sal{w}\t{%b2, %0|%0, %b2}";
11367       else if (operands[2] == const1_rtx
11368                && (TARGET_SHIFT1 || optimize_size))
11369         return "sal{w}\t%0";
11370       else
11371         return "sal{w}\t{%2, %0|%0, %2}";
11372     }
11373 }
11374   [(set (attr "type")
11375      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11376                           (const_int 0))
11377                       (match_operand 0 "register_operand" ""))
11378                  (match_operand 2 "const1_operand" ""))
11379               (const_string "alu")
11380            ]
11381            (const_string "ishift")))
11382    (set_attr "mode" "HI")])
11383
11384 (define_expand "ashlqi3"
11385   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11386         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11387                    (match_operand:QI 2 "nonmemory_operand" "")))
11388    (clobber (reg:CC FLAGS_REG))]
11389   "TARGET_QIMODE_MATH"
11390   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11391
11392 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11393
11394 (define_insn "*ashlqi3_1_lea"
11395   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11396         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11397                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11398    (clobber (reg:CC FLAGS_REG))]
11399   "!TARGET_PARTIAL_REG_STALL
11400    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11401 {
11402   switch (get_attr_type (insn))
11403     {
11404     case TYPE_LEA:
11405       return "#";
11406     case TYPE_ALU:
11407       gcc_assert (operands[2] == const1_rtx);
11408       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11409         return "add{l}\t%k0, %k0";
11410       else
11411         return "add{b}\t%0, %0";
11412
11413     default:
11414       if (REG_P (operands[2]))
11415         {
11416           if (get_attr_mode (insn) == MODE_SI)
11417             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11418           else
11419             return "sal{b}\t{%b2, %0|%0, %b2}";
11420         }
11421       else if (operands[2] == const1_rtx
11422                && (TARGET_SHIFT1 || optimize_size))
11423         {
11424           if (get_attr_mode (insn) == MODE_SI)
11425             return "sal{l}\t%0";
11426           else
11427             return "sal{b}\t%0";
11428         }
11429       else
11430         {
11431           if (get_attr_mode (insn) == MODE_SI)
11432             return "sal{l}\t{%2, %k0|%k0, %2}";
11433           else
11434             return "sal{b}\t{%2, %0|%0, %2}";
11435         }
11436     }
11437 }
11438   [(set (attr "type")
11439      (cond [(eq_attr "alternative" "2")
11440               (const_string "lea")
11441             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11442                           (const_int 0))
11443                       (match_operand 0 "register_operand" ""))
11444                  (match_operand 2 "const1_operand" ""))
11445               (const_string "alu")
11446            ]
11447            (const_string "ishift")))
11448    (set_attr "mode" "QI,SI,SI")])
11449
11450 (define_insn "*ashlqi3_1"
11451   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11452         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11453                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11454    (clobber (reg:CC FLAGS_REG))]
11455   "TARGET_PARTIAL_REG_STALL
11456    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11457 {
11458   switch (get_attr_type (insn))
11459     {
11460     case TYPE_ALU:
11461       gcc_assert (operands[2] == const1_rtx);
11462       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11463         return "add{l}\t%k0, %k0";
11464       else
11465         return "add{b}\t%0, %0";
11466
11467     default:
11468       if (REG_P (operands[2]))
11469         {
11470           if (get_attr_mode (insn) == MODE_SI)
11471             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11472           else
11473             return "sal{b}\t{%b2, %0|%0, %b2}";
11474         }
11475       else if (operands[2] == const1_rtx
11476                && (TARGET_SHIFT1 || optimize_size))
11477         {
11478           if (get_attr_mode (insn) == MODE_SI)
11479             return "sal{l}\t%0";
11480           else
11481             return "sal{b}\t%0";
11482         }
11483       else
11484         {
11485           if (get_attr_mode (insn) == MODE_SI)
11486             return "sal{l}\t{%2, %k0|%k0, %2}";
11487           else
11488             return "sal{b}\t{%2, %0|%0, %2}";
11489         }
11490     }
11491 }
11492   [(set (attr "type")
11493      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11494                           (const_int 0))
11495                       (match_operand 0 "register_operand" ""))
11496                  (match_operand 2 "const1_operand" ""))
11497               (const_string "alu")
11498            ]
11499            (const_string "ishift")))
11500    (set_attr "mode" "QI,SI")])
11501
11502 ;; This pattern can't accept a variable shift count, since shifts by
11503 ;; zero don't affect the flags.  We assume that shifts by constant
11504 ;; zero are optimized away.
11505 (define_insn "*ashlqi3_cmp"
11506   [(set (reg FLAGS_REG)
11507         (compare
11508           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11509                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11510           (const_int 0)))
11511    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11512         (ashift:QI (match_dup 1) (match_dup 2)))]
11513   "ix86_match_ccmode (insn, CCGOCmode)
11514    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11515    && (optimize_size
11516        || !TARGET_PARTIAL_FLAG_REG_STALL
11517        || (operands[2] == const1_rtx
11518            && (TARGET_SHIFT1
11519                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11520 {
11521   switch (get_attr_type (insn))
11522     {
11523     case TYPE_ALU:
11524       gcc_assert (operands[2] == const1_rtx);
11525       return "add{b}\t%0, %0";
11526
11527     default:
11528       if (REG_P (operands[2]))
11529         return "sal{b}\t{%b2, %0|%0, %b2}";
11530       else if (operands[2] == const1_rtx
11531                && (TARGET_SHIFT1 || optimize_size))
11532         return "sal{b}\t%0";
11533       else
11534         return "sal{b}\t{%2, %0|%0, %2}";
11535     }
11536 }
11537   [(set (attr "type")
11538      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11539                           (const_int 0))
11540                       (match_operand 0 "register_operand" ""))
11541                  (match_operand 2 "const1_operand" ""))
11542               (const_string "alu")
11543            ]
11544            (const_string "ishift")))
11545    (set_attr "mode" "QI")])
11546
11547 (define_insn "*ashlqi3_cconly"
11548   [(set (reg FLAGS_REG)
11549         (compare
11550           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11551                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11552           (const_int 0)))
11553    (clobber (match_scratch:QI 0 "=q"))]
11554   "ix86_match_ccmode (insn, CCGOCmode)
11555    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11556    && (optimize_size
11557        || !TARGET_PARTIAL_FLAG_REG_STALL
11558        || (operands[2] == const1_rtx
11559            && (TARGET_SHIFT1
11560                || TARGET_DOUBLE_WITH_ADD)))"
11561 {
11562   switch (get_attr_type (insn))
11563     {
11564     case TYPE_ALU:
11565       gcc_assert (operands[2] == const1_rtx);
11566       return "add{b}\t%0, %0";
11567
11568     default:
11569       if (REG_P (operands[2]))
11570         return "sal{b}\t{%b2, %0|%0, %b2}";
11571       else if (operands[2] == const1_rtx
11572                && (TARGET_SHIFT1 || optimize_size))
11573         return "sal{b}\t%0";
11574       else
11575         return "sal{b}\t{%2, %0|%0, %2}";
11576     }
11577 }
11578   [(set (attr "type")
11579      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11580                           (const_int 0))
11581                       (match_operand 0 "register_operand" ""))
11582                  (match_operand 2 "const1_operand" ""))
11583               (const_string "alu")
11584            ]
11585            (const_string "ishift")))
11586    (set_attr "mode" "QI")])
11587
11588 ;; See comment above `ashldi3' about how this works.
11589
11590 (define_expand "ashrti3"
11591   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11592                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11593                                 (match_operand:QI 2 "nonmemory_operand" "")))
11594               (clobber (reg:CC FLAGS_REG))])]
11595   "TARGET_64BIT"
11596 {
11597   if (! immediate_operand (operands[2], QImode))
11598     {
11599       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11600       DONE;
11601     }
11602   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11603   DONE;
11604 })
11605
11606 (define_insn "ashrti3_1"
11607   [(set (match_operand:TI 0 "register_operand" "=r")
11608         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11609                      (match_operand:QI 2 "register_operand" "c")))
11610    (clobber (match_scratch:DI 3 "=&r"))
11611    (clobber (reg:CC FLAGS_REG))]
11612   "TARGET_64BIT"
11613   "#"
11614   [(set_attr "type" "multi")])
11615
11616 (define_insn "*ashrti3_2"
11617   [(set (match_operand:TI 0 "register_operand" "=r")
11618         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11619                      (match_operand:QI 2 "immediate_operand" "O")))
11620    (clobber (reg:CC FLAGS_REG))]
11621   "TARGET_64BIT"
11622   "#"
11623   [(set_attr "type" "multi")])
11624
11625 (define_split
11626   [(set (match_operand:TI 0 "register_operand" "")
11627         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11628                      (match_operand:QI 2 "register_operand" "")))
11629    (clobber (match_scratch:DI 3 ""))
11630    (clobber (reg:CC FLAGS_REG))]
11631   "TARGET_64BIT && reload_completed"
11632   [(const_int 0)]
11633   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11634
11635 (define_split
11636   [(set (match_operand:TI 0 "register_operand" "")
11637         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11638                      (match_operand:QI 2 "immediate_operand" "")))
11639    (clobber (reg:CC FLAGS_REG))]
11640   "TARGET_64BIT && reload_completed"
11641   [(const_int 0)]
11642   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11643
11644 (define_insn "x86_64_shrd"
11645   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11646         (ior:DI (ashiftrt:DI (match_dup 0)
11647                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11648                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11649                   (minus:QI (const_int 64) (match_dup 2)))))
11650    (clobber (reg:CC FLAGS_REG))]
11651   "TARGET_64BIT"
11652   "@
11653    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11654    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11655   [(set_attr "type" "ishift")
11656    (set_attr "prefix_0f" "1")
11657    (set_attr "mode" "DI")
11658    (set_attr "athlon_decode" "vector")
11659    (set_attr "amdfam10_decode" "vector")])   
11660
11661 (define_expand "ashrdi3"
11662   [(set (match_operand:DI 0 "shiftdi_operand" "")
11663         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11664                      (match_operand:QI 2 "nonmemory_operand" "")))]
11665   ""
11666   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11667
11668 (define_insn "*ashrdi3_63_rex64"
11669   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11670         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11671                      (match_operand:DI 2 "const_int_operand" "i,i")))
11672    (clobber (reg:CC FLAGS_REG))]
11673   "TARGET_64BIT && INTVAL (operands[2]) == 63
11674    && (TARGET_USE_CLTD || optimize_size)
11675    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11676   "@
11677    {cqto|cqo}
11678    sar{q}\t{%2, %0|%0, %2}"
11679   [(set_attr "type" "imovx,ishift")
11680    (set_attr "prefix_0f" "0,*")
11681    (set_attr "length_immediate" "0,*")
11682    (set_attr "modrm" "0,1")
11683    (set_attr "mode" "DI")])
11684
11685 (define_insn "*ashrdi3_1_one_bit_rex64"
11686   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11687         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11688                      (match_operand:QI 2 "const1_operand" "")))
11689    (clobber (reg:CC FLAGS_REG))]
11690   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11691    && (TARGET_SHIFT1 || optimize_size)"
11692   "sar{q}\t%0"
11693   [(set_attr "type" "ishift")
11694    (set (attr "length")
11695      (if_then_else (match_operand:DI 0 "register_operand" "")
11696         (const_string "2")
11697         (const_string "*")))])
11698
11699 (define_insn "*ashrdi3_1_rex64"
11700   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11701         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11702                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11703    (clobber (reg:CC FLAGS_REG))]
11704   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11705   "@
11706    sar{q}\t{%2, %0|%0, %2}
11707    sar{q}\t{%b2, %0|%0, %b2}"
11708   [(set_attr "type" "ishift")
11709    (set_attr "mode" "DI")])
11710
11711 ;; This pattern can't accept a variable shift count, since shifts by
11712 ;; zero don't affect the flags.  We assume that shifts by constant
11713 ;; zero are optimized away.
11714 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11715   [(set (reg FLAGS_REG)
11716         (compare
11717           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11718                        (match_operand:QI 2 "const1_operand" ""))
11719           (const_int 0)))
11720    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11721         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11722   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11723    && (TARGET_SHIFT1 || optimize_size)
11724    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11725   "sar{q}\t%0"
11726   [(set_attr "type" "ishift")
11727    (set (attr "length")
11728      (if_then_else (match_operand:DI 0 "register_operand" "")
11729         (const_string "2")
11730         (const_string "*")))])
11731
11732 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11733   [(set (reg FLAGS_REG)
11734         (compare
11735           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11736                        (match_operand:QI 2 "const1_operand" ""))
11737           (const_int 0)))
11738    (clobber (match_scratch:DI 0 "=r"))]
11739   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11740    && (TARGET_SHIFT1 || optimize_size)
11741    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11742   "sar{q}\t%0"
11743   [(set_attr "type" "ishift")
11744    (set_attr "length" "2")])
11745
11746 ;; This pattern can't accept a variable shift count, since shifts by
11747 ;; zero don't affect the flags.  We assume that shifts by constant
11748 ;; zero are optimized away.
11749 (define_insn "*ashrdi3_cmp_rex64"
11750   [(set (reg FLAGS_REG)
11751         (compare
11752           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11753                        (match_operand:QI 2 "const_int_operand" "n"))
11754           (const_int 0)))
11755    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11756         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11757   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11758    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11759    && (optimize_size
11760        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11761   "sar{q}\t{%2, %0|%0, %2}"
11762   [(set_attr "type" "ishift")
11763    (set_attr "mode" "DI")])
11764
11765 (define_insn "*ashrdi3_cconly_rex64"
11766   [(set (reg FLAGS_REG)
11767         (compare
11768           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11769                        (match_operand:QI 2 "const_int_operand" "n"))
11770           (const_int 0)))
11771    (clobber (match_scratch:DI 0 "=r"))]
11772   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11773    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11774    && (optimize_size
11775        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11776   "sar{q}\t{%2, %0|%0, %2}"
11777   [(set_attr "type" "ishift")
11778    (set_attr "mode" "DI")])
11779
11780 (define_insn "*ashrdi3_1"
11781   [(set (match_operand:DI 0 "register_operand" "=r")
11782         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11783                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11784    (clobber (reg:CC FLAGS_REG))]
11785   "!TARGET_64BIT"
11786   "#"
11787   [(set_attr "type" "multi")])
11788
11789 ;; By default we don't ask for a scratch register, because when DImode
11790 ;; values are manipulated, registers are already at a premium.  But if
11791 ;; we have one handy, we won't turn it away.
11792 (define_peephole2
11793   [(match_scratch:SI 3 "r")
11794    (parallel [(set (match_operand:DI 0 "register_operand" "")
11795                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11796                                 (match_operand:QI 2 "nonmemory_operand" "")))
11797               (clobber (reg:CC FLAGS_REG))])
11798    (match_dup 3)]
11799   "!TARGET_64BIT && TARGET_CMOVE"
11800   [(const_int 0)]
11801   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11802
11803 (define_split
11804   [(set (match_operand:DI 0 "register_operand" "")
11805         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11806                      (match_operand:QI 2 "nonmemory_operand" "")))
11807    (clobber (reg:CC FLAGS_REG))]
11808   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11809                      ? flow2_completed : reload_completed)"
11810   [(const_int 0)]
11811   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11812
11813 (define_insn "x86_shrd_1"
11814   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11815         (ior:SI (ashiftrt:SI (match_dup 0)
11816                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11817                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11818                   (minus:QI (const_int 32) (match_dup 2)))))
11819    (clobber (reg:CC FLAGS_REG))]
11820   ""
11821   "@
11822    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11823    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11824   [(set_attr "type" "ishift")
11825    (set_attr "prefix_0f" "1")
11826    (set_attr "pent_pair" "np")
11827    (set_attr "mode" "SI")])
11828
11829 (define_expand "x86_shift_adj_3"
11830   [(use (match_operand:SI 0 "register_operand" ""))
11831    (use (match_operand:SI 1 "register_operand" ""))
11832    (use (match_operand:QI 2 "register_operand" ""))]
11833   ""
11834 {
11835   rtx label = gen_label_rtx ();
11836   rtx tmp;
11837
11838   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11839
11840   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11841   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11842   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11843                               gen_rtx_LABEL_REF (VOIDmode, label),
11844                               pc_rtx);
11845   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11846   JUMP_LABEL (tmp) = label;
11847
11848   emit_move_insn (operands[0], operands[1]);
11849   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11850
11851   emit_label (label);
11852   LABEL_NUSES (label) = 1;
11853
11854   DONE;
11855 })
11856
11857 (define_insn "ashrsi3_31"
11858   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11859         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11860                      (match_operand:SI 2 "const_int_operand" "i,i")))
11861    (clobber (reg:CC FLAGS_REG))]
11862   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11863    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11864   "@
11865    {cltd|cdq}
11866    sar{l}\t{%2, %0|%0, %2}"
11867   [(set_attr "type" "imovx,ishift")
11868    (set_attr "prefix_0f" "0,*")
11869    (set_attr "length_immediate" "0,*")
11870    (set_attr "modrm" "0,1")
11871    (set_attr "mode" "SI")])
11872
11873 (define_insn "*ashrsi3_31_zext"
11874   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11875         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11876                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11877    (clobber (reg:CC FLAGS_REG))]
11878   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11879    && INTVAL (operands[2]) == 31
11880    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11881   "@
11882    {cltd|cdq}
11883    sar{l}\t{%2, %k0|%k0, %2}"
11884   [(set_attr "type" "imovx,ishift")
11885    (set_attr "prefix_0f" "0,*")
11886    (set_attr "length_immediate" "0,*")
11887    (set_attr "modrm" "0,1")
11888    (set_attr "mode" "SI")])
11889
11890 (define_expand "ashrsi3"
11891   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11892         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11893                      (match_operand:QI 2 "nonmemory_operand" "")))
11894    (clobber (reg:CC FLAGS_REG))]
11895   ""
11896   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11897
11898 (define_insn "*ashrsi3_1_one_bit"
11899   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11900         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11901                      (match_operand:QI 2 "const1_operand" "")))
11902    (clobber (reg:CC FLAGS_REG))]
11903   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11904    && (TARGET_SHIFT1 || optimize_size)"
11905   "sar{l}\t%0"
11906   [(set_attr "type" "ishift")
11907    (set (attr "length")
11908      (if_then_else (match_operand:SI 0 "register_operand" "")
11909         (const_string "2")
11910         (const_string "*")))])
11911
11912 (define_insn "*ashrsi3_1_one_bit_zext"
11913   [(set (match_operand:DI 0 "register_operand" "=r")
11914         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11915                                      (match_operand:QI 2 "const1_operand" ""))))
11916    (clobber (reg:CC FLAGS_REG))]
11917   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11918    && (TARGET_SHIFT1 || optimize_size)"
11919   "sar{l}\t%k0"
11920   [(set_attr "type" "ishift")
11921    (set_attr "length" "2")])
11922
11923 (define_insn "*ashrsi3_1"
11924   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11925         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11926                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11927    (clobber (reg:CC FLAGS_REG))]
11928   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11929   "@
11930    sar{l}\t{%2, %0|%0, %2}
11931    sar{l}\t{%b2, %0|%0, %b2}"
11932   [(set_attr "type" "ishift")
11933    (set_attr "mode" "SI")])
11934
11935 (define_insn "*ashrsi3_1_zext"
11936   [(set (match_operand:DI 0 "register_operand" "=r,r")
11937         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11938                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11939    (clobber (reg:CC FLAGS_REG))]
11940   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11941   "@
11942    sar{l}\t{%2, %k0|%k0, %2}
11943    sar{l}\t{%b2, %k0|%k0, %b2}"
11944   [(set_attr "type" "ishift")
11945    (set_attr "mode" "SI")])
11946
11947 ;; This pattern can't accept a variable shift count, since shifts by
11948 ;; zero don't affect the flags.  We assume that shifts by constant
11949 ;; zero are optimized away.
11950 (define_insn "*ashrsi3_one_bit_cmp"
11951   [(set (reg FLAGS_REG)
11952         (compare
11953           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11954                        (match_operand:QI 2 "const1_operand" ""))
11955           (const_int 0)))
11956    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11957         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11958   "ix86_match_ccmode (insn, CCGOCmode)
11959    && (TARGET_SHIFT1 || optimize_size)
11960    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11961   "sar{l}\t%0"
11962   [(set_attr "type" "ishift")
11963    (set (attr "length")
11964      (if_then_else (match_operand:SI 0 "register_operand" "")
11965         (const_string "2")
11966         (const_string "*")))])
11967
11968 (define_insn "*ashrsi3_one_bit_cconly"
11969   [(set (reg FLAGS_REG)
11970         (compare
11971           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11972                        (match_operand:QI 2 "const1_operand" ""))
11973           (const_int 0)))
11974    (clobber (match_scratch:SI 0 "=r"))]
11975   "ix86_match_ccmode (insn, CCGOCmode)
11976    && (TARGET_SHIFT1 || optimize_size)
11977    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11978   "sar{l}\t%0"
11979   [(set_attr "type" "ishift")
11980    (set_attr "length" "2")])
11981
11982 (define_insn "*ashrsi3_one_bit_cmp_zext"
11983   [(set (reg FLAGS_REG)
11984         (compare
11985           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11986                        (match_operand:QI 2 "const1_operand" ""))
11987           (const_int 0)))
11988    (set (match_operand:DI 0 "register_operand" "=r")
11989         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11990   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11991    && (TARGET_SHIFT1 || optimize_size)
11992    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11993   "sar{l}\t%k0"
11994   [(set_attr "type" "ishift")
11995    (set_attr "length" "2")])
11996
11997 ;; This pattern can't accept a variable shift count, since shifts by
11998 ;; zero don't affect the flags.  We assume that shifts by constant
11999 ;; zero are optimized away.
12000 (define_insn "*ashrsi3_cmp"
12001   [(set (reg FLAGS_REG)
12002         (compare
12003           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12004                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12005           (const_int 0)))
12006    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12007         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12008   "ix86_match_ccmode (insn, CCGOCmode)
12009    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
12010    && (optimize_size
12011        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12012   "sar{l}\t{%2, %0|%0, %2}"
12013   [(set_attr "type" "ishift")
12014    (set_attr "mode" "SI")])
12015
12016 (define_insn "*ashrsi3_cconly"
12017   [(set (reg FLAGS_REG)
12018         (compare
12019           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12020                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12021           (const_int 0)))
12022    (clobber (match_scratch:SI 0 "=r"))]
12023   "ix86_match_ccmode (insn, CCGOCmode)
12024    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
12025    && (optimize_size
12026        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12027   "sar{l}\t{%2, %0|%0, %2}"
12028   [(set_attr "type" "ishift")
12029    (set_attr "mode" "SI")])
12030
12031 (define_insn "*ashrsi3_cmp_zext"
12032   [(set (reg FLAGS_REG)
12033         (compare
12034           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12035                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12036           (const_int 0)))
12037    (set (match_operand:DI 0 "register_operand" "=r")
12038         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12039   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12040    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
12041    && (optimize_size
12042        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12043   "sar{l}\t{%2, %k0|%k0, %2}"
12044   [(set_attr "type" "ishift")
12045    (set_attr "mode" "SI")])
12046
12047 (define_expand "ashrhi3"
12048   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12049         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12050                      (match_operand:QI 2 "nonmemory_operand" "")))
12051    (clobber (reg:CC FLAGS_REG))]
12052   "TARGET_HIMODE_MATH"
12053   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12054
12055 (define_insn "*ashrhi3_1_one_bit"
12056   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12057         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12058                      (match_operand:QI 2 "const1_operand" "")))
12059    (clobber (reg:CC FLAGS_REG))]
12060   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12061    && (TARGET_SHIFT1 || optimize_size)"
12062   "sar{w}\t%0"
12063   [(set_attr "type" "ishift")
12064    (set (attr "length")
12065      (if_then_else (match_operand 0 "register_operand" "")
12066         (const_string "2")
12067         (const_string "*")))])
12068
12069 (define_insn "*ashrhi3_1"
12070   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12071         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12072                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12073    (clobber (reg:CC FLAGS_REG))]
12074   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12075   "@
12076    sar{w}\t{%2, %0|%0, %2}
12077    sar{w}\t{%b2, %0|%0, %b2}"
12078   [(set_attr "type" "ishift")
12079    (set_attr "mode" "HI")])
12080
12081 ;; This pattern can't accept a variable shift count, since shifts by
12082 ;; zero don't affect the flags.  We assume that shifts by constant
12083 ;; zero are optimized away.
12084 (define_insn "*ashrhi3_one_bit_cmp"
12085   [(set (reg FLAGS_REG)
12086         (compare
12087           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12088                        (match_operand:QI 2 "const1_operand" ""))
12089           (const_int 0)))
12090    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12091         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12092   "ix86_match_ccmode (insn, CCGOCmode)
12093    && (TARGET_SHIFT1 || optimize_size)
12094    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12095   "sar{w}\t%0"
12096   [(set_attr "type" "ishift")
12097    (set (attr "length")
12098      (if_then_else (match_operand 0 "register_operand" "")
12099         (const_string "2")
12100         (const_string "*")))])
12101
12102 (define_insn "*ashrhi3_one_bit_cconly"
12103   [(set (reg FLAGS_REG)
12104         (compare
12105           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12106                        (match_operand:QI 2 "const1_operand" ""))
12107           (const_int 0)))
12108    (clobber (match_scratch:HI 0 "=r"))]
12109   "ix86_match_ccmode (insn, CCGOCmode)
12110    && (TARGET_SHIFT1 || optimize_size)
12111    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12112   "sar{w}\t%0"
12113   [(set_attr "type" "ishift")
12114    (set_attr "length" "2")])
12115
12116 ;; This pattern can't accept a variable shift count, since shifts by
12117 ;; zero don't affect the flags.  We assume that shifts by constant
12118 ;; zero are optimized away.
12119 (define_insn "*ashrhi3_cmp"
12120   [(set (reg FLAGS_REG)
12121         (compare
12122           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12123                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12124           (const_int 0)))
12125    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12126         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12127   "ix86_match_ccmode (insn, CCGOCmode)
12128    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12129    && (optimize_size
12130        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12131   "sar{w}\t{%2, %0|%0, %2}"
12132   [(set_attr "type" "ishift")
12133    (set_attr "mode" "HI")])
12134
12135 (define_insn "*ashrhi3_cconly"
12136   [(set (reg FLAGS_REG)
12137         (compare
12138           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12139                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12140           (const_int 0)))
12141    (clobber (match_scratch:HI 0 "=r"))]
12142   "ix86_match_ccmode (insn, CCGOCmode)
12143    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12144    && (optimize_size
12145        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12146   "sar{w}\t{%2, %0|%0, %2}"
12147   [(set_attr "type" "ishift")
12148    (set_attr "mode" "HI")])
12149
12150 (define_expand "ashrqi3"
12151   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12152         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12153                      (match_operand:QI 2 "nonmemory_operand" "")))
12154    (clobber (reg:CC FLAGS_REG))]
12155   "TARGET_QIMODE_MATH"
12156   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12157
12158 (define_insn "*ashrqi3_1_one_bit"
12159   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12160         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12161                      (match_operand:QI 2 "const1_operand" "")))
12162    (clobber (reg:CC FLAGS_REG))]
12163   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12164    && (TARGET_SHIFT1 || optimize_size)"
12165   "sar{b}\t%0"
12166   [(set_attr "type" "ishift")
12167    (set (attr "length")
12168      (if_then_else (match_operand 0 "register_operand" "")
12169         (const_string "2")
12170         (const_string "*")))])
12171
12172 (define_insn "*ashrqi3_1_one_bit_slp"
12173   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12174         (ashiftrt:QI (match_dup 0)
12175                      (match_operand:QI 1 "const1_operand" "")))
12176    (clobber (reg:CC FLAGS_REG))]
12177   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12178    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
12179    && (TARGET_SHIFT1 || optimize_size)"
12180   "sar{b}\t%0"
12181   [(set_attr "type" "ishift1")
12182    (set (attr "length")
12183      (if_then_else (match_operand 0 "register_operand" "")
12184         (const_string "2")
12185         (const_string "*")))])
12186
12187 (define_insn "*ashrqi3_1"
12188   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12189         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12190                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12191    (clobber (reg:CC FLAGS_REG))]
12192   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12193   "@
12194    sar{b}\t{%2, %0|%0, %2}
12195    sar{b}\t{%b2, %0|%0, %b2}"
12196   [(set_attr "type" "ishift")
12197    (set_attr "mode" "QI")])
12198
12199 (define_insn "*ashrqi3_1_slp"
12200   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12201         (ashiftrt:QI (match_dup 0)
12202                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12203    (clobber (reg:CC FLAGS_REG))]
12204   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12205    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12206   "@
12207    sar{b}\t{%1, %0|%0, %1}
12208    sar{b}\t{%b1, %0|%0, %b1}"
12209   [(set_attr "type" "ishift1")
12210    (set_attr "mode" "QI")])
12211
12212 ;; This pattern can't accept a variable shift count, since shifts by
12213 ;; zero don't affect the flags.  We assume that shifts by constant
12214 ;; zero are optimized away.
12215 (define_insn "*ashrqi3_one_bit_cmp"
12216   [(set (reg FLAGS_REG)
12217         (compare
12218           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12219                        (match_operand:QI 2 "const1_operand" "I"))
12220           (const_int 0)))
12221    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12222         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12223   "ix86_match_ccmode (insn, CCGOCmode)
12224    && (TARGET_SHIFT1 || optimize_size)
12225    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12226   "sar{b}\t%0"
12227   [(set_attr "type" "ishift")
12228    (set (attr "length")
12229      (if_then_else (match_operand 0 "register_operand" "")
12230         (const_string "2")
12231         (const_string "*")))])
12232
12233 (define_insn "*ashrqi3_one_bit_cconly"
12234   [(set (reg FLAGS_REG)
12235         (compare
12236           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12237                        (match_operand:QI 2 "const1_operand" "I"))
12238           (const_int 0)))
12239    (clobber (match_scratch:QI 0 "=q"))]
12240   "ix86_match_ccmode (insn, CCGOCmode)
12241    && (TARGET_SHIFT1 || optimize_size)
12242    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12243   "sar{b}\t%0"
12244   [(set_attr "type" "ishift")
12245    (set_attr "length" "2")])
12246
12247 ;; This pattern can't accept a variable shift count, since shifts by
12248 ;; zero don't affect the flags.  We assume that shifts by constant
12249 ;; zero are optimized away.
12250 (define_insn "*ashrqi3_cmp"
12251   [(set (reg FLAGS_REG)
12252         (compare
12253           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12254                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12255           (const_int 0)))
12256    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12257         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12258   "ix86_match_ccmode (insn, CCGOCmode)
12259    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12260    && (optimize_size
12261        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12262   "sar{b}\t{%2, %0|%0, %2}"
12263   [(set_attr "type" "ishift")
12264    (set_attr "mode" "QI")])
12265
12266 (define_insn "*ashrqi3_cconly"
12267   [(set (reg FLAGS_REG)
12268         (compare
12269           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12270                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12271           (const_int 0)))
12272    (clobber (match_scratch:QI 0 "=q"))]
12273   "ix86_match_ccmode (insn, CCGOCmode)
12274    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12275    && (optimize_size
12276        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12277   "sar{b}\t{%2, %0|%0, %2}"
12278   [(set_attr "type" "ishift")
12279    (set_attr "mode" "QI")])
12280
12281 \f
12282 ;; Logical shift instructions
12283
12284 ;; See comment above `ashldi3' about how this works.
12285
12286 (define_expand "lshrti3"
12287   [(parallel [(set (match_operand:TI 0 "register_operand" "")
12288                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12289                                 (match_operand:QI 2 "nonmemory_operand" "")))
12290               (clobber (reg:CC FLAGS_REG))])]
12291   "TARGET_64BIT"
12292 {
12293   if (! immediate_operand (operands[2], QImode))
12294     {
12295       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12296       DONE;
12297     }
12298   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12299   DONE;
12300 })
12301
12302 (define_insn "lshrti3_1"
12303   [(set (match_operand:TI 0 "register_operand" "=r")
12304         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12305                      (match_operand:QI 2 "register_operand" "c")))
12306    (clobber (match_scratch:DI 3 "=&r"))
12307    (clobber (reg:CC FLAGS_REG))]
12308   "TARGET_64BIT"
12309   "#"
12310   [(set_attr "type" "multi")])
12311
12312 (define_insn "*lshrti3_2"
12313   [(set (match_operand:TI 0 "register_operand" "=r")
12314         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12315                      (match_operand:QI 2 "immediate_operand" "O")))
12316    (clobber (reg:CC FLAGS_REG))]
12317   "TARGET_64BIT"
12318   "#"
12319   [(set_attr "type" "multi")])
12320
12321 (define_split
12322   [(set (match_operand:TI 0 "register_operand" "")
12323         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12324                      (match_operand:QI 2 "register_operand" "")))
12325    (clobber (match_scratch:DI 3 ""))
12326    (clobber (reg:CC FLAGS_REG))]
12327   "TARGET_64BIT && reload_completed"
12328   [(const_int 0)]
12329   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12330
12331 (define_split
12332   [(set (match_operand:TI 0 "register_operand" "")
12333         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12334                      (match_operand:QI 2 "immediate_operand" "")))
12335    (clobber (reg:CC FLAGS_REG))]
12336   "TARGET_64BIT && reload_completed"
12337   [(const_int 0)]
12338   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12339
12340 (define_expand "lshrdi3"
12341   [(set (match_operand:DI 0 "shiftdi_operand" "")
12342         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12343                      (match_operand:QI 2 "nonmemory_operand" "")))]
12344   ""
12345   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12346
12347 (define_insn "*lshrdi3_1_one_bit_rex64"
12348   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12349         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12350                      (match_operand:QI 2 "const1_operand" "")))
12351    (clobber (reg:CC FLAGS_REG))]
12352   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12353    && (TARGET_SHIFT1 || optimize_size)"
12354   "shr{q}\t%0"
12355   [(set_attr "type" "ishift")
12356    (set (attr "length")
12357      (if_then_else (match_operand:DI 0 "register_operand" "")
12358         (const_string "2")
12359         (const_string "*")))])
12360
12361 (define_insn "*lshrdi3_1_rex64"
12362   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12363         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12364                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12365    (clobber (reg:CC FLAGS_REG))]
12366   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12367   "@
12368    shr{q}\t{%2, %0|%0, %2}
12369    shr{q}\t{%b2, %0|%0, %b2}"
12370   [(set_attr "type" "ishift")
12371    (set_attr "mode" "DI")])
12372
12373 ;; This pattern can't accept a variable shift count, since shifts by
12374 ;; zero don't affect the flags.  We assume that shifts by constant
12375 ;; zero are optimized away.
12376 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12377   [(set (reg FLAGS_REG)
12378         (compare
12379           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12380                        (match_operand:QI 2 "const1_operand" ""))
12381           (const_int 0)))
12382    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12383         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12384   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12385    && (TARGET_SHIFT1 || optimize_size)
12386    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12387   "shr{q}\t%0"
12388   [(set_attr "type" "ishift")
12389    (set (attr "length")
12390      (if_then_else (match_operand:DI 0 "register_operand" "")
12391         (const_string "2")
12392         (const_string "*")))])
12393
12394 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12395   [(set (reg FLAGS_REG)
12396         (compare
12397           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12398                        (match_operand:QI 2 "const1_operand" ""))
12399           (const_int 0)))
12400    (clobber (match_scratch:DI 0 "=r"))]
12401   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12402    && (TARGET_SHIFT1 || optimize_size)
12403    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12404   "shr{q}\t%0"
12405   [(set_attr "type" "ishift")
12406    (set_attr "length" "2")])
12407
12408 ;; This pattern can't accept a variable shift count, since shifts by
12409 ;; zero don't affect the flags.  We assume that shifts by constant
12410 ;; zero are optimized away.
12411 (define_insn "*lshrdi3_cmp_rex64"
12412   [(set (reg FLAGS_REG)
12413         (compare
12414           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12415                        (match_operand:QI 2 "const_int_operand" "e"))
12416           (const_int 0)))
12417    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12418         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12419   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12420    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12421    && (optimize_size
12422        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12423   "shr{q}\t{%2, %0|%0, %2}"
12424   [(set_attr "type" "ishift")
12425    (set_attr "mode" "DI")])
12426
12427 (define_insn "*lshrdi3_cconly_rex64"
12428   [(set (reg FLAGS_REG)
12429         (compare
12430           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12431                        (match_operand:QI 2 "const_int_operand" "e"))
12432           (const_int 0)))
12433    (clobber (match_scratch:DI 0 "=r"))]
12434   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12435    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12436    && (optimize_size
12437        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12438   "shr{q}\t{%2, %0|%0, %2}"
12439   [(set_attr "type" "ishift")
12440    (set_attr "mode" "DI")])
12441
12442 (define_insn "*lshrdi3_1"
12443   [(set (match_operand:DI 0 "register_operand" "=r")
12444         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12445                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12446    (clobber (reg:CC FLAGS_REG))]
12447   "!TARGET_64BIT"
12448   "#"
12449   [(set_attr "type" "multi")])
12450
12451 ;; By default we don't ask for a scratch register, because when DImode
12452 ;; values are manipulated, registers are already at a premium.  But if
12453 ;; we have one handy, we won't turn it away.
12454 (define_peephole2
12455   [(match_scratch:SI 3 "r")
12456    (parallel [(set (match_operand:DI 0 "register_operand" "")
12457                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12458                                 (match_operand:QI 2 "nonmemory_operand" "")))
12459               (clobber (reg:CC FLAGS_REG))])
12460    (match_dup 3)]
12461   "!TARGET_64BIT && TARGET_CMOVE"
12462   [(const_int 0)]
12463   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12464
12465 (define_split
12466   [(set (match_operand:DI 0 "register_operand" "")
12467         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12468                      (match_operand:QI 2 "nonmemory_operand" "")))
12469    (clobber (reg:CC FLAGS_REG))]
12470   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12471                      ? flow2_completed : reload_completed)"
12472   [(const_int 0)]
12473   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12474
12475 (define_expand "lshrsi3"
12476   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12477         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12478                      (match_operand:QI 2 "nonmemory_operand" "")))
12479    (clobber (reg:CC FLAGS_REG))]
12480   ""
12481   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12482
12483 (define_insn "*lshrsi3_1_one_bit"
12484   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12485         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12486                      (match_operand:QI 2 "const1_operand" "")))
12487    (clobber (reg:CC FLAGS_REG))]
12488   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12489    && (TARGET_SHIFT1 || optimize_size)"
12490   "shr{l}\t%0"
12491   [(set_attr "type" "ishift")
12492    (set (attr "length")
12493      (if_then_else (match_operand:SI 0 "register_operand" "")
12494         (const_string "2")
12495         (const_string "*")))])
12496
12497 (define_insn "*lshrsi3_1_one_bit_zext"
12498   [(set (match_operand:DI 0 "register_operand" "=r")
12499         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12500                      (match_operand:QI 2 "const1_operand" "")))
12501    (clobber (reg:CC FLAGS_REG))]
12502   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12503    && (TARGET_SHIFT1 || optimize_size)"
12504   "shr{l}\t%k0"
12505   [(set_attr "type" "ishift")
12506    (set_attr "length" "2")])
12507
12508 (define_insn "*lshrsi3_1"
12509   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12510         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12511                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12512    (clobber (reg:CC FLAGS_REG))]
12513   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12514   "@
12515    shr{l}\t{%2, %0|%0, %2}
12516    shr{l}\t{%b2, %0|%0, %b2}"
12517   [(set_attr "type" "ishift")
12518    (set_attr "mode" "SI")])
12519
12520 (define_insn "*lshrsi3_1_zext"
12521   [(set (match_operand:DI 0 "register_operand" "=r,r")
12522         (zero_extend:DI
12523           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12524                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12525    (clobber (reg:CC FLAGS_REG))]
12526   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12527   "@
12528    shr{l}\t{%2, %k0|%k0, %2}
12529    shr{l}\t{%b2, %k0|%k0, %b2}"
12530   [(set_attr "type" "ishift")
12531    (set_attr "mode" "SI")])
12532
12533 ;; This pattern can't accept a variable shift count, since shifts by
12534 ;; zero don't affect the flags.  We assume that shifts by constant
12535 ;; zero are optimized away.
12536 (define_insn "*lshrsi3_one_bit_cmp"
12537   [(set (reg FLAGS_REG)
12538         (compare
12539           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12540                        (match_operand:QI 2 "const1_operand" ""))
12541           (const_int 0)))
12542    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12543         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12544   "ix86_match_ccmode (insn, CCGOCmode)
12545    && (TARGET_SHIFT1 || optimize_size)
12546    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12547   "shr{l}\t%0"
12548   [(set_attr "type" "ishift")
12549    (set (attr "length")
12550      (if_then_else (match_operand:SI 0 "register_operand" "")
12551         (const_string "2")
12552         (const_string "*")))])
12553
12554 (define_insn "*lshrsi3_one_bit_cconly"
12555   [(set (reg FLAGS_REG)
12556         (compare
12557           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12558                        (match_operand:QI 2 "const1_operand" ""))
12559           (const_int 0)))
12560    (clobber (match_scratch:SI 0 "=r"))]
12561   "ix86_match_ccmode (insn, CCGOCmode)
12562    && (TARGET_SHIFT1 || optimize_size)
12563    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12564   "shr{l}\t%0"
12565   [(set_attr "type" "ishift")
12566    (set_attr "length" "2")])
12567
12568 (define_insn "*lshrsi3_cmp_one_bit_zext"
12569   [(set (reg FLAGS_REG)
12570         (compare
12571           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12572                        (match_operand:QI 2 "const1_operand" ""))
12573           (const_int 0)))
12574    (set (match_operand:DI 0 "register_operand" "=r")
12575         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12576   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12577    && (TARGET_SHIFT1 || optimize_size)
12578    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12579   "shr{l}\t%k0"
12580   [(set_attr "type" "ishift")
12581    (set_attr "length" "2")])
12582
12583 ;; This pattern can't accept a variable shift count, since shifts by
12584 ;; zero don't affect the flags.  We assume that shifts by constant
12585 ;; zero are optimized away.
12586 (define_insn "*lshrsi3_cmp"
12587   [(set (reg FLAGS_REG)
12588         (compare
12589           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12590                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12591           (const_int 0)))
12592    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12593         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12594   "ix86_match_ccmode (insn, CCGOCmode)
12595    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12596    && (optimize_size
12597        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12598   "shr{l}\t{%2, %0|%0, %2}"
12599   [(set_attr "type" "ishift")
12600    (set_attr "mode" "SI")])
12601
12602 (define_insn "*lshrsi3_cconly"
12603   [(set (reg FLAGS_REG)
12604       (compare
12605         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12606                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12607         (const_int 0)))
12608    (clobber (match_scratch:SI 0 "=r"))]
12609   "ix86_match_ccmode (insn, CCGOCmode)
12610    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12611    && (optimize_size
12612        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12613   "shr{l}\t{%2, %0|%0, %2}"
12614   [(set_attr "type" "ishift")
12615    (set_attr "mode" "SI")])
12616
12617 (define_insn "*lshrsi3_cmp_zext"
12618   [(set (reg FLAGS_REG)
12619         (compare
12620           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12621                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12622           (const_int 0)))
12623    (set (match_operand:DI 0 "register_operand" "=r")
12624         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12625   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12626    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12627    && (optimize_size
12628        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12629   "shr{l}\t{%2, %k0|%k0, %2}"
12630   [(set_attr "type" "ishift")
12631    (set_attr "mode" "SI")])
12632
12633 (define_expand "lshrhi3"
12634   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12635         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12636                      (match_operand:QI 2 "nonmemory_operand" "")))
12637    (clobber (reg:CC FLAGS_REG))]
12638   "TARGET_HIMODE_MATH"
12639   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12640
12641 (define_insn "*lshrhi3_1_one_bit"
12642   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12643         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12644                      (match_operand:QI 2 "const1_operand" "")))
12645    (clobber (reg:CC FLAGS_REG))]
12646   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12647    && (TARGET_SHIFT1 || optimize_size)"
12648   "shr{w}\t%0"
12649   [(set_attr "type" "ishift")
12650    (set (attr "length")
12651      (if_then_else (match_operand 0 "register_operand" "")
12652         (const_string "2")
12653         (const_string "*")))])
12654
12655 (define_insn "*lshrhi3_1"
12656   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12657         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12658                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12659    (clobber (reg:CC FLAGS_REG))]
12660   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12661   "@
12662    shr{w}\t{%2, %0|%0, %2}
12663    shr{w}\t{%b2, %0|%0, %b2}"
12664   [(set_attr "type" "ishift")
12665    (set_attr "mode" "HI")])
12666
12667 ;; This pattern can't accept a variable shift count, since shifts by
12668 ;; zero don't affect the flags.  We assume that shifts by constant
12669 ;; zero are optimized away.
12670 (define_insn "*lshrhi3_one_bit_cmp"
12671   [(set (reg FLAGS_REG)
12672         (compare
12673           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12674                        (match_operand:QI 2 "const1_operand" ""))
12675           (const_int 0)))
12676    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12677         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12678   "ix86_match_ccmode (insn, CCGOCmode)
12679    && (TARGET_SHIFT1 || optimize_size)
12680    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12681   "shr{w}\t%0"
12682   [(set_attr "type" "ishift")
12683    (set (attr "length")
12684      (if_then_else (match_operand:SI 0 "register_operand" "")
12685         (const_string "2")
12686         (const_string "*")))])
12687
12688 (define_insn "*lshrhi3_one_bit_cconly"
12689   [(set (reg FLAGS_REG)
12690         (compare
12691           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12692                        (match_operand:QI 2 "const1_operand" ""))
12693           (const_int 0)))
12694    (clobber (match_scratch:HI 0 "=r"))]
12695   "ix86_match_ccmode (insn, CCGOCmode)
12696    && (TARGET_SHIFT1 || optimize_size)
12697    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12698   "shr{w}\t%0"
12699   [(set_attr "type" "ishift")
12700    (set_attr "length" "2")])
12701
12702 ;; This pattern can't accept a variable shift count, since shifts by
12703 ;; zero don't affect the flags.  We assume that shifts by constant
12704 ;; zero are optimized away.
12705 (define_insn "*lshrhi3_cmp"
12706   [(set (reg FLAGS_REG)
12707         (compare
12708           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12709                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12710           (const_int 0)))
12711    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12712         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12713   "ix86_match_ccmode (insn, CCGOCmode)
12714    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12715    && (optimize_size
12716        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12717   "shr{w}\t{%2, %0|%0, %2}"
12718   [(set_attr "type" "ishift")
12719    (set_attr "mode" "HI")])
12720
12721 (define_insn "*lshrhi3_cconly"
12722   [(set (reg FLAGS_REG)
12723         (compare
12724           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12725                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12726           (const_int 0)))
12727    (clobber (match_scratch:HI 0 "=r"))]
12728   "ix86_match_ccmode (insn, CCGOCmode)
12729    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12730    && (optimize_size
12731        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12732   "shr{w}\t{%2, %0|%0, %2}"
12733   [(set_attr "type" "ishift")
12734    (set_attr "mode" "HI")])
12735
12736 (define_expand "lshrqi3"
12737   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12738         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12739                      (match_operand:QI 2 "nonmemory_operand" "")))
12740    (clobber (reg:CC FLAGS_REG))]
12741   "TARGET_QIMODE_MATH"
12742   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12743
12744 (define_insn "*lshrqi3_1_one_bit"
12745   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12746         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12747                      (match_operand:QI 2 "const1_operand" "")))
12748    (clobber (reg:CC FLAGS_REG))]
12749   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12750    && (TARGET_SHIFT1 || optimize_size)"
12751   "shr{b}\t%0"
12752   [(set_attr "type" "ishift")
12753    (set (attr "length")
12754      (if_then_else (match_operand 0 "register_operand" "")
12755         (const_string "2")
12756         (const_string "*")))])
12757
12758 (define_insn "*lshrqi3_1_one_bit_slp"
12759   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12760         (lshiftrt:QI (match_dup 0)
12761                      (match_operand:QI 1 "const1_operand" "")))
12762    (clobber (reg:CC FLAGS_REG))]
12763   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12764    && (TARGET_SHIFT1 || optimize_size)"
12765   "shr{b}\t%0"
12766   [(set_attr "type" "ishift1")
12767    (set (attr "length")
12768      (if_then_else (match_operand 0 "register_operand" "")
12769         (const_string "2")
12770         (const_string "*")))])
12771
12772 (define_insn "*lshrqi3_1"
12773   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12774         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12775                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12776    (clobber (reg:CC FLAGS_REG))]
12777   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12778   "@
12779    shr{b}\t{%2, %0|%0, %2}
12780    shr{b}\t{%b2, %0|%0, %b2}"
12781   [(set_attr "type" "ishift")
12782    (set_attr "mode" "QI")])
12783
12784 (define_insn "*lshrqi3_1_slp"
12785   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12786         (lshiftrt:QI (match_dup 0)
12787                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12788    (clobber (reg:CC FLAGS_REG))]
12789   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12790    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12791   "@
12792    shr{b}\t{%1, %0|%0, %1}
12793    shr{b}\t{%b1, %0|%0, %b1}"
12794   [(set_attr "type" "ishift1")
12795    (set_attr "mode" "QI")])
12796
12797 ;; This pattern can't accept a variable shift count, since shifts by
12798 ;; zero don't affect the flags.  We assume that shifts by constant
12799 ;; zero are optimized away.
12800 (define_insn "*lshrqi2_one_bit_cmp"
12801   [(set (reg FLAGS_REG)
12802         (compare
12803           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12804                        (match_operand:QI 2 "const1_operand" ""))
12805           (const_int 0)))
12806    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12807         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12808   "ix86_match_ccmode (insn, CCGOCmode)
12809    && (TARGET_SHIFT1 || optimize_size)
12810    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12811   "shr{b}\t%0"
12812   [(set_attr "type" "ishift")
12813    (set (attr "length")
12814      (if_then_else (match_operand:SI 0 "register_operand" "")
12815         (const_string "2")
12816         (const_string "*")))])
12817
12818 (define_insn "*lshrqi2_one_bit_cconly"
12819   [(set (reg FLAGS_REG)
12820         (compare
12821           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12822                        (match_operand:QI 2 "const1_operand" ""))
12823           (const_int 0)))
12824    (clobber (match_scratch:QI 0 "=q"))]
12825   "ix86_match_ccmode (insn, CCGOCmode)
12826    && (TARGET_SHIFT1 || optimize_size)
12827    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12828   "shr{b}\t%0"
12829   [(set_attr "type" "ishift")
12830    (set_attr "length" "2")])
12831
12832 ;; This pattern can't accept a variable shift count, since shifts by
12833 ;; zero don't affect the flags.  We assume that shifts by constant
12834 ;; zero are optimized away.
12835 (define_insn "*lshrqi2_cmp"
12836   [(set (reg FLAGS_REG)
12837         (compare
12838           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12839                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12840           (const_int 0)))
12841    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12842         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12843   "ix86_match_ccmode (insn, CCGOCmode)
12844    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12845    && (optimize_size
12846        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12847   "shr{b}\t{%2, %0|%0, %2}"
12848   [(set_attr "type" "ishift")
12849    (set_attr "mode" "QI")])
12850
12851 (define_insn "*lshrqi2_cconly"
12852   [(set (reg FLAGS_REG)
12853         (compare
12854           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12855                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12856           (const_int 0)))
12857    (clobber (match_scratch:QI 0 "=q"))]
12858   "ix86_match_ccmode (insn, CCGOCmode)
12859    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12860    && (optimize_size
12861        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12862   "shr{b}\t{%2, %0|%0, %2}"
12863   [(set_attr "type" "ishift")
12864    (set_attr "mode" "QI")])
12865 \f
12866 ;; Rotate instructions
12867
12868 (define_expand "rotldi3"
12869   [(set (match_operand:DI 0 "shiftdi_operand" "")
12870         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12871                    (match_operand:QI 2 "nonmemory_operand" "")))
12872    (clobber (reg:CC FLAGS_REG))]
12873  ""
12874 {
12875   if (TARGET_64BIT)
12876     {
12877       ix86_expand_binary_operator (ROTATE, DImode, operands);
12878       DONE;
12879     }
12880   if (!const_1_to_31_operand (operands[2], VOIDmode))
12881     FAIL;
12882   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12883   DONE;
12884 })
12885
12886 ;; Implement rotation using two double-precision shift instructions
12887 ;; and a scratch register.
12888 (define_insn_and_split "ix86_rotldi3"
12889  [(set (match_operand:DI 0 "register_operand" "=r")
12890        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12891                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12892   (clobber (reg:CC FLAGS_REG))
12893   (clobber (match_scratch:SI 3 "=&r"))]
12894  "!TARGET_64BIT"
12895  ""
12896  "&& reload_completed"
12897  [(set (match_dup 3) (match_dup 4))
12898   (parallel
12899    [(set (match_dup 4)
12900          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12901                  (lshiftrt:SI (match_dup 5)
12902                               (minus:QI (const_int 32) (match_dup 2)))))
12903     (clobber (reg:CC FLAGS_REG))])
12904   (parallel
12905    [(set (match_dup 5)
12906          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12907                  (lshiftrt:SI (match_dup 3)
12908                               (minus:QI (const_int 32) (match_dup 2)))))
12909     (clobber (reg:CC FLAGS_REG))])]
12910  "split_di (operands, 1, operands + 4, operands + 5);")
12911
12912 (define_insn "*rotlsi3_1_one_bit_rex64"
12913   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12914         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12915                    (match_operand:QI 2 "const1_operand" "")))
12916    (clobber (reg:CC FLAGS_REG))]
12917   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12918    && (TARGET_SHIFT1 || optimize_size)"
12919   "rol{q}\t%0"
12920   [(set_attr "type" "rotate")
12921    (set (attr "length")
12922      (if_then_else (match_operand:DI 0 "register_operand" "")
12923         (const_string "2")
12924         (const_string "*")))])
12925
12926 (define_insn "*rotldi3_1_rex64"
12927   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12928         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12929                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12930    (clobber (reg:CC FLAGS_REG))]
12931   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12932   "@
12933    rol{q}\t{%2, %0|%0, %2}
12934    rol{q}\t{%b2, %0|%0, %b2}"
12935   [(set_attr "type" "rotate")
12936    (set_attr "mode" "DI")])
12937
12938 (define_expand "rotlsi3"
12939   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12940         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12941                    (match_operand:QI 2 "nonmemory_operand" "")))
12942    (clobber (reg:CC FLAGS_REG))]
12943   ""
12944   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12945
12946 (define_insn "*rotlsi3_1_one_bit"
12947   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12948         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12949                    (match_operand:QI 2 "const1_operand" "")))
12950    (clobber (reg:CC FLAGS_REG))]
12951   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12952    && (TARGET_SHIFT1 || optimize_size)"
12953   "rol{l}\t%0"
12954   [(set_attr "type" "rotate")
12955    (set (attr "length")
12956      (if_then_else (match_operand:SI 0 "register_operand" "")
12957         (const_string "2")
12958         (const_string "*")))])
12959
12960 (define_insn "*rotlsi3_1_one_bit_zext"
12961   [(set (match_operand:DI 0 "register_operand" "=r")
12962         (zero_extend:DI
12963           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12964                      (match_operand:QI 2 "const1_operand" ""))))
12965    (clobber (reg:CC FLAGS_REG))]
12966   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12967    && (TARGET_SHIFT1 || optimize_size)"
12968   "rol{l}\t%k0"
12969   [(set_attr "type" "rotate")
12970    (set_attr "length" "2")])
12971
12972 (define_insn "*rotlsi3_1"
12973   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12974         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12975                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12976    (clobber (reg:CC FLAGS_REG))]
12977   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12978   "@
12979    rol{l}\t{%2, %0|%0, %2}
12980    rol{l}\t{%b2, %0|%0, %b2}"
12981   [(set_attr "type" "rotate")
12982    (set_attr "mode" "SI")])
12983
12984 (define_insn "*rotlsi3_1_zext"
12985   [(set (match_operand:DI 0 "register_operand" "=r,r")
12986         (zero_extend:DI
12987           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12988                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12989    (clobber (reg:CC FLAGS_REG))]
12990   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12991   "@
12992    rol{l}\t{%2, %k0|%k0, %2}
12993    rol{l}\t{%b2, %k0|%k0, %b2}"
12994   [(set_attr "type" "rotate")
12995    (set_attr "mode" "SI")])
12996
12997 (define_expand "rotlhi3"
12998   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12999         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13000                    (match_operand:QI 2 "nonmemory_operand" "")))
13001    (clobber (reg:CC FLAGS_REG))]
13002   "TARGET_HIMODE_MATH"
13003   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13004
13005 (define_insn "*rotlhi3_1_one_bit"
13006   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13007         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13008                    (match_operand:QI 2 "const1_operand" "")))
13009    (clobber (reg:CC FLAGS_REG))]
13010   "ix86_binary_operator_ok (ROTATE, HImode, operands)
13011    && (TARGET_SHIFT1 || optimize_size)"
13012   "rol{w}\t%0"
13013   [(set_attr "type" "rotate")
13014    (set (attr "length")
13015      (if_then_else (match_operand 0 "register_operand" "")
13016         (const_string "2")
13017         (const_string "*")))])
13018
13019 (define_insn "*rotlhi3_1"
13020   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13021         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13022                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13023    (clobber (reg:CC FLAGS_REG))]
13024   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13025   "@
13026    rol{w}\t{%2, %0|%0, %2}
13027    rol{w}\t{%b2, %0|%0, %b2}"
13028   [(set_attr "type" "rotate")
13029    (set_attr "mode" "HI")])
13030
13031 (define_expand "rotlqi3"
13032   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13033         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13034                    (match_operand:QI 2 "nonmemory_operand" "")))
13035    (clobber (reg:CC FLAGS_REG))]
13036   "TARGET_QIMODE_MATH"
13037   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13038
13039 (define_insn "*rotlqi3_1_one_bit_slp"
13040   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13041         (rotate:QI (match_dup 0)
13042                    (match_operand:QI 1 "const1_operand" "")))
13043    (clobber (reg:CC FLAGS_REG))]
13044   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13045    && (TARGET_SHIFT1 || optimize_size)"
13046   "rol{b}\t%0"
13047   [(set_attr "type" "rotate1")
13048    (set (attr "length")
13049      (if_then_else (match_operand 0 "register_operand" "")
13050         (const_string "2")
13051         (const_string "*")))])
13052
13053 (define_insn "*rotlqi3_1_one_bit"
13054   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13055         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13056                    (match_operand:QI 2 "const1_operand" "")))
13057    (clobber (reg:CC FLAGS_REG))]
13058   "ix86_binary_operator_ok (ROTATE, QImode, operands)
13059    && (TARGET_SHIFT1 || optimize_size)"
13060   "rol{b}\t%0"
13061   [(set_attr "type" "rotate")
13062    (set (attr "length")
13063      (if_then_else (match_operand 0 "register_operand" "")
13064         (const_string "2")
13065         (const_string "*")))])
13066
13067 (define_insn "*rotlqi3_1_slp"
13068   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13069         (rotate:QI (match_dup 0)
13070                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13071    (clobber (reg:CC FLAGS_REG))]
13072   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13073    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13074   "@
13075    rol{b}\t{%1, %0|%0, %1}
13076    rol{b}\t{%b1, %0|%0, %b1}"
13077   [(set_attr "type" "rotate1")
13078    (set_attr "mode" "QI")])
13079
13080 (define_insn "*rotlqi3_1"
13081   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13082         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13083                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13084    (clobber (reg:CC FLAGS_REG))]
13085   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13086   "@
13087    rol{b}\t{%2, %0|%0, %2}
13088    rol{b}\t{%b2, %0|%0, %b2}"
13089   [(set_attr "type" "rotate")
13090    (set_attr "mode" "QI")])
13091
13092 (define_expand "rotrdi3"
13093   [(set (match_operand:DI 0 "shiftdi_operand" "")
13094         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13095                    (match_operand:QI 2 "nonmemory_operand" "")))
13096    (clobber (reg:CC FLAGS_REG))]
13097  ""
13098 {
13099   if (TARGET_64BIT)
13100     {
13101       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13102       DONE;
13103     }
13104   if (!const_1_to_31_operand (operands[2], VOIDmode))
13105     FAIL;
13106   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13107   DONE;
13108 })
13109
13110 ;; Implement rotation using two double-precision shift instructions
13111 ;; and a scratch register.
13112 (define_insn_and_split "ix86_rotrdi3"
13113  [(set (match_operand:DI 0 "register_operand" "=r")
13114        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13115                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13116   (clobber (reg:CC FLAGS_REG))
13117   (clobber (match_scratch:SI 3 "=&r"))]
13118  "!TARGET_64BIT"
13119  ""
13120  "&& reload_completed"
13121  [(set (match_dup 3) (match_dup 4))
13122   (parallel
13123    [(set (match_dup 4)
13124          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13125                  (ashift:SI (match_dup 5)
13126                             (minus:QI (const_int 32) (match_dup 2)))))
13127     (clobber (reg:CC FLAGS_REG))])
13128   (parallel
13129    [(set (match_dup 5)
13130          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13131                  (ashift:SI (match_dup 3)
13132                             (minus:QI (const_int 32) (match_dup 2)))))
13133     (clobber (reg:CC FLAGS_REG))])]
13134  "split_di (operands, 1, operands + 4, operands + 5);")
13135
13136 (define_insn "*rotrdi3_1_one_bit_rex64"
13137   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13138         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13139                      (match_operand:QI 2 "const1_operand" "")))
13140    (clobber (reg:CC FLAGS_REG))]
13141   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
13142    && (TARGET_SHIFT1 || optimize_size)"
13143   "ror{q}\t%0"
13144   [(set_attr "type" "rotate")
13145    (set (attr "length")
13146      (if_then_else (match_operand:DI 0 "register_operand" "")
13147         (const_string "2")
13148         (const_string "*")))])
13149
13150 (define_insn "*rotrdi3_1_rex64"
13151   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13152         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13153                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13154    (clobber (reg:CC FLAGS_REG))]
13155   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13156   "@
13157    ror{q}\t{%2, %0|%0, %2}
13158    ror{q}\t{%b2, %0|%0, %b2}"
13159   [(set_attr "type" "rotate")
13160    (set_attr "mode" "DI")])
13161
13162 (define_expand "rotrsi3"
13163   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13164         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13165                      (match_operand:QI 2 "nonmemory_operand" "")))
13166    (clobber (reg:CC FLAGS_REG))]
13167   ""
13168   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13169
13170 (define_insn "*rotrsi3_1_one_bit"
13171   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13172         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13173                      (match_operand:QI 2 "const1_operand" "")))
13174    (clobber (reg:CC FLAGS_REG))]
13175   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
13176    && (TARGET_SHIFT1 || optimize_size)"
13177   "ror{l}\t%0"
13178   [(set_attr "type" "rotate")
13179    (set (attr "length")
13180      (if_then_else (match_operand:SI 0 "register_operand" "")
13181         (const_string "2")
13182         (const_string "*")))])
13183
13184 (define_insn "*rotrsi3_1_one_bit_zext"
13185   [(set (match_operand:DI 0 "register_operand" "=r")
13186         (zero_extend:DI
13187           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13188                        (match_operand:QI 2 "const1_operand" ""))))
13189    (clobber (reg:CC FLAGS_REG))]
13190   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
13191    && (TARGET_SHIFT1 || optimize_size)"
13192   "ror{l}\t%k0"
13193   [(set_attr "type" "rotate")
13194    (set (attr "length")
13195      (if_then_else (match_operand:SI 0 "register_operand" "")
13196         (const_string "2")
13197         (const_string "*")))])
13198
13199 (define_insn "*rotrsi3_1"
13200   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13201         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13202                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13203    (clobber (reg:CC FLAGS_REG))]
13204   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13205   "@
13206    ror{l}\t{%2, %0|%0, %2}
13207    ror{l}\t{%b2, %0|%0, %b2}"
13208   [(set_attr "type" "rotate")
13209    (set_attr "mode" "SI")])
13210
13211 (define_insn "*rotrsi3_1_zext"
13212   [(set (match_operand:DI 0 "register_operand" "=r,r")
13213         (zero_extend:DI
13214           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13215                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13216    (clobber (reg:CC FLAGS_REG))]
13217   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13218   "@
13219    ror{l}\t{%2, %k0|%k0, %2}
13220    ror{l}\t{%b2, %k0|%k0, %b2}"
13221   [(set_attr "type" "rotate")
13222    (set_attr "mode" "SI")])
13223
13224 (define_expand "rotrhi3"
13225   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13226         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13227                      (match_operand:QI 2 "nonmemory_operand" "")))
13228    (clobber (reg:CC FLAGS_REG))]
13229   "TARGET_HIMODE_MATH"
13230   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13231
13232 (define_insn "*rotrhi3_one_bit"
13233   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13234         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13235                      (match_operand:QI 2 "const1_operand" "")))
13236    (clobber (reg:CC FLAGS_REG))]
13237   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
13238    && (TARGET_SHIFT1 || optimize_size)"
13239   "ror{w}\t%0"
13240   [(set_attr "type" "rotate")
13241    (set (attr "length")
13242      (if_then_else (match_operand 0 "register_operand" "")
13243         (const_string "2")
13244         (const_string "*")))])
13245
13246 (define_insn "*rotrhi3"
13247   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13248         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13249                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13250    (clobber (reg:CC FLAGS_REG))]
13251   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13252   "@
13253    ror{w}\t{%2, %0|%0, %2}
13254    ror{w}\t{%b2, %0|%0, %b2}"
13255   [(set_attr "type" "rotate")
13256    (set_attr "mode" "HI")])
13257
13258 (define_expand "rotrqi3"
13259   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13260         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13261                      (match_operand:QI 2 "nonmemory_operand" "")))
13262    (clobber (reg:CC FLAGS_REG))]
13263   "TARGET_QIMODE_MATH"
13264   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13265
13266 (define_insn "*rotrqi3_1_one_bit"
13267   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13268         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13269                      (match_operand:QI 2 "const1_operand" "")))
13270    (clobber (reg:CC FLAGS_REG))]
13271   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
13272    && (TARGET_SHIFT1 || optimize_size)"
13273   "ror{b}\t%0"
13274   [(set_attr "type" "rotate")
13275    (set (attr "length")
13276      (if_then_else (match_operand 0 "register_operand" "")
13277         (const_string "2")
13278         (const_string "*")))])
13279
13280 (define_insn "*rotrqi3_1_one_bit_slp"
13281   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13282         (rotatert:QI (match_dup 0)
13283                      (match_operand:QI 1 "const1_operand" "")))
13284    (clobber (reg:CC FLAGS_REG))]
13285   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13286    && (TARGET_SHIFT1 || optimize_size)"
13287   "ror{b}\t%0"
13288   [(set_attr "type" "rotate1")
13289    (set (attr "length")
13290      (if_then_else (match_operand 0 "register_operand" "")
13291         (const_string "2")
13292         (const_string "*")))])
13293
13294 (define_insn "*rotrqi3_1"
13295   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13296         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13297                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13298    (clobber (reg:CC FLAGS_REG))]
13299   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13300   "@
13301    ror{b}\t{%2, %0|%0, %2}
13302    ror{b}\t{%b2, %0|%0, %b2}"
13303   [(set_attr "type" "rotate")
13304    (set_attr "mode" "QI")])
13305
13306 (define_insn "*rotrqi3_1_slp"
13307   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13308         (rotatert:QI (match_dup 0)
13309                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13310    (clobber (reg:CC FLAGS_REG))]
13311   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13312    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13313   "@
13314    ror{b}\t{%1, %0|%0, %1}
13315    ror{b}\t{%b1, %0|%0, %b1}"
13316   [(set_attr "type" "rotate1")
13317    (set_attr "mode" "QI")])
13318 \f
13319 ;; Bit set / bit test instructions
13320
13321 (define_expand "extv"
13322   [(set (match_operand:SI 0 "register_operand" "")
13323         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13324                          (match_operand:SI 2 "const8_operand" "")
13325                          (match_operand:SI 3 "const8_operand" "")))]
13326   ""
13327 {
13328   /* Handle extractions from %ah et al.  */
13329   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13330     FAIL;
13331
13332   /* From mips.md: extract_bit_field doesn't verify that our source
13333      matches the predicate, so check it again here.  */
13334   if (! ext_register_operand (operands[1], VOIDmode))
13335     FAIL;
13336 })
13337
13338 (define_expand "extzv"
13339   [(set (match_operand:SI 0 "register_operand" "")
13340         (zero_extract:SI (match_operand 1 "ext_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 "insv"
13356   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13357                       (match_operand 1 "const8_operand" "")
13358                       (match_operand 2 "const8_operand" ""))
13359         (match_operand 3 "register_operand" ""))]
13360   ""
13361 {
13362   /* Handle insertions to %ah et al.  */
13363   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13364     FAIL;
13365
13366   /* From mips.md: insert_bit_field doesn't verify that our source
13367      matches the predicate, so check it again here.  */
13368   if (! ext_register_operand (operands[0], VOIDmode))
13369     FAIL;
13370
13371   if (TARGET_64BIT)
13372     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13373   else
13374     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13375
13376   DONE;
13377 })
13378
13379 ;; %%% bts, btr, btc, bt.
13380 ;; In general these instructions are *slow* when applied to memory,
13381 ;; since they enforce atomic operation.  When applied to registers,
13382 ;; it depends on the cpu implementation.  They're never faster than
13383 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13384 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13385 ;; within the instruction itself, so operating on bits in the high
13386 ;; 32-bits of a register becomes easier.
13387 ;;
13388 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13389 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13390 ;; negdf respectively, so they can never be disabled entirely.
13391
13392 (define_insn "*btsq"
13393   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13394                          (const_int 1)
13395                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13396         (const_int 1))
13397    (clobber (reg:CC FLAGS_REG))]
13398   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13399   "bts{q} %1,%0"
13400   [(set_attr "type" "alu1")])
13401
13402 (define_insn "*btrq"
13403   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13404                          (const_int 1)
13405                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13406         (const_int 0))
13407    (clobber (reg:CC FLAGS_REG))]
13408   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13409   "btr{q} %1,%0"
13410   [(set_attr "type" "alu1")])
13411
13412 (define_insn "*btcq"
13413   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13414                          (const_int 1)
13415                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13416         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13417    (clobber (reg:CC FLAGS_REG))]
13418   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13419   "btc{q} %1,%0"
13420   [(set_attr "type" "alu1")])
13421
13422 ;; Allow Nocona to avoid these instructions if a register is available.
13423
13424 (define_peephole2
13425   [(match_scratch:DI 2 "r")
13426    (parallel [(set (zero_extract:DI
13427                      (match_operand:DI 0 "register_operand" "")
13428                      (const_int 1)
13429                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13430                    (const_int 1))
13431               (clobber (reg:CC FLAGS_REG))])]
13432   "TARGET_64BIT && !TARGET_USE_BT"
13433   [(const_int 0)]
13434 {
13435   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13436   rtx op1;
13437
13438   if (HOST_BITS_PER_WIDE_INT >= 64)
13439     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13440   else if (i < HOST_BITS_PER_WIDE_INT)
13441     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13442   else
13443     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13444
13445   op1 = immed_double_const (lo, hi, DImode);
13446   if (i >= 31)
13447     {
13448       emit_move_insn (operands[2], op1);
13449       op1 = operands[2];
13450     }
13451
13452   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13453   DONE;
13454 })
13455
13456 (define_peephole2
13457   [(match_scratch:DI 2 "r")
13458    (parallel [(set (zero_extract:DI
13459                      (match_operand:DI 0 "register_operand" "")
13460                      (const_int 1)
13461                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13462                    (const_int 0))
13463               (clobber (reg:CC FLAGS_REG))])]
13464   "TARGET_64BIT && !TARGET_USE_BT"
13465   [(const_int 0)]
13466 {
13467   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13468   rtx op1;
13469
13470   if (HOST_BITS_PER_WIDE_INT >= 64)
13471     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13472   else if (i < HOST_BITS_PER_WIDE_INT)
13473     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13474   else
13475     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13476
13477   op1 = immed_double_const (~lo, ~hi, DImode);
13478   if (i >= 32)
13479     {
13480       emit_move_insn (operands[2], op1);
13481       op1 = operands[2];
13482     }
13483
13484   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13485   DONE;
13486 })
13487
13488 (define_peephole2
13489   [(match_scratch:DI 2 "r")
13490    (parallel [(set (zero_extract:DI
13491                      (match_operand:DI 0 "register_operand" "")
13492                      (const_int 1)
13493                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13494               (not:DI (zero_extract:DI
13495                         (match_dup 0) (const_int 1) (match_dup 1))))
13496               (clobber (reg:CC FLAGS_REG))])]
13497   "TARGET_64BIT && !TARGET_USE_BT"
13498   [(const_int 0)]
13499 {
13500   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13501   rtx op1;
13502
13503   if (HOST_BITS_PER_WIDE_INT >= 64)
13504     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13505   else if (i < HOST_BITS_PER_WIDE_INT)
13506     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13507   else
13508     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13509
13510   op1 = immed_double_const (lo, hi, DImode);
13511   if (i >= 31)
13512     {
13513       emit_move_insn (operands[2], op1);
13514       op1 = operands[2];
13515     }
13516
13517   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13518   DONE;
13519 })
13520 \f
13521 ;; Store-flag instructions.
13522
13523 ;; For all sCOND expanders, also expand the compare or test insn that
13524 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13525
13526 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13527 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13528 ;; way, which can later delete the movzx if only QImode is needed.
13529
13530 (define_expand "seq"
13531   [(set (match_operand:QI 0 "register_operand" "")
13532         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13533   ""
13534   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13535
13536 (define_expand "sne"
13537   [(set (match_operand:QI 0 "register_operand" "")
13538         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13539   ""
13540   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13541
13542 (define_expand "sgt"
13543   [(set (match_operand:QI 0 "register_operand" "")
13544         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13545   ""
13546   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13547
13548 (define_expand "sgtu"
13549   [(set (match_operand:QI 0 "register_operand" "")
13550         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13551   ""
13552   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13553
13554 (define_expand "slt"
13555   [(set (match_operand:QI 0 "register_operand" "")
13556         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13557   ""
13558   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13559
13560 (define_expand "sltu"
13561   [(set (match_operand:QI 0 "register_operand" "")
13562         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13563   ""
13564   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13565
13566 (define_expand "sge"
13567   [(set (match_operand:QI 0 "register_operand" "")
13568         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13569   ""
13570   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13571
13572 (define_expand "sgeu"
13573   [(set (match_operand:QI 0 "register_operand" "")
13574         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13575   ""
13576   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13577
13578 (define_expand "sle"
13579   [(set (match_operand:QI 0 "register_operand" "")
13580         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13581   ""
13582   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13583
13584 (define_expand "sleu"
13585   [(set (match_operand:QI 0 "register_operand" "")
13586         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13587   ""
13588   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13589
13590 (define_expand "sunordered"
13591   [(set (match_operand:QI 0 "register_operand" "")
13592         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13593   "TARGET_80387 || TARGET_SSE"
13594   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13595
13596 (define_expand "sordered"
13597   [(set (match_operand:QI 0 "register_operand" "")
13598         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13599   "TARGET_80387"
13600   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13601
13602 (define_expand "suneq"
13603   [(set (match_operand:QI 0 "register_operand" "")
13604         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13605   "TARGET_80387 || TARGET_SSE"
13606   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13607
13608 (define_expand "sunge"
13609   [(set (match_operand:QI 0 "register_operand" "")
13610         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13611   "TARGET_80387 || TARGET_SSE"
13612   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13613
13614 (define_expand "sungt"
13615   [(set (match_operand:QI 0 "register_operand" "")
13616         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13617   "TARGET_80387 || TARGET_SSE"
13618   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13619
13620 (define_expand "sunle"
13621   [(set (match_operand:QI 0 "register_operand" "")
13622         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13623   "TARGET_80387 || TARGET_SSE"
13624   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13625
13626 (define_expand "sunlt"
13627   [(set (match_operand:QI 0 "register_operand" "")
13628         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13629   "TARGET_80387 || TARGET_SSE"
13630   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13631
13632 (define_expand "sltgt"
13633   [(set (match_operand:QI 0 "register_operand" "")
13634         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13635   "TARGET_80387 || TARGET_SSE"
13636   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13637
13638 (define_insn "*setcc_1"
13639   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13640         (match_operator:QI 1 "ix86_comparison_operator"
13641           [(reg FLAGS_REG) (const_int 0)]))]
13642   ""
13643   "set%C1\t%0"
13644   [(set_attr "type" "setcc")
13645    (set_attr "mode" "QI")])
13646
13647 (define_insn "*setcc_2"
13648   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13649         (match_operator:QI 1 "ix86_comparison_operator"
13650           [(reg FLAGS_REG) (const_int 0)]))]
13651   ""
13652   "set%C1\t%0"
13653   [(set_attr "type" "setcc")
13654    (set_attr "mode" "QI")])
13655
13656 ;; In general it is not safe to assume too much about CCmode registers,
13657 ;; so simplify-rtx stops when it sees a second one.  Under certain
13658 ;; conditions this is safe on x86, so help combine not create
13659 ;;
13660 ;;      seta    %al
13661 ;;      testb   %al, %al
13662 ;;      sete    %al
13663
13664 (define_split
13665   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13666         (ne:QI (match_operator 1 "ix86_comparison_operator"
13667                  [(reg FLAGS_REG) (const_int 0)])
13668             (const_int 0)))]
13669   ""
13670   [(set (match_dup 0) (match_dup 1))]
13671 {
13672   PUT_MODE (operands[1], QImode);
13673 })
13674
13675 (define_split
13676   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13677         (ne:QI (match_operator 1 "ix86_comparison_operator"
13678                  [(reg FLAGS_REG) (const_int 0)])
13679             (const_int 0)))]
13680   ""
13681   [(set (match_dup 0) (match_dup 1))]
13682 {
13683   PUT_MODE (operands[1], QImode);
13684 })
13685
13686 (define_split
13687   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13688         (eq:QI (match_operator 1 "ix86_comparison_operator"
13689                  [(reg FLAGS_REG) (const_int 0)])
13690             (const_int 0)))]
13691   ""
13692   [(set (match_dup 0) (match_dup 1))]
13693 {
13694   rtx new_op1 = copy_rtx (operands[1]);
13695   operands[1] = new_op1;
13696   PUT_MODE (new_op1, QImode);
13697   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13698                                              GET_MODE (XEXP (new_op1, 0))));
13699
13700   /* Make sure that (a) the CCmode we have for the flags is strong
13701      enough for the reversed compare or (b) we have a valid FP compare.  */
13702   if (! ix86_comparison_operator (new_op1, VOIDmode))
13703     FAIL;
13704 })
13705
13706 (define_split
13707   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13708         (eq:QI (match_operator 1 "ix86_comparison_operator"
13709                  [(reg FLAGS_REG) (const_int 0)])
13710             (const_int 0)))]
13711   ""
13712   [(set (match_dup 0) (match_dup 1))]
13713 {
13714   rtx new_op1 = copy_rtx (operands[1]);
13715   operands[1] = new_op1;
13716   PUT_MODE (new_op1, QImode);
13717   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13718                                              GET_MODE (XEXP (new_op1, 0))));
13719
13720   /* Make sure that (a) the CCmode we have for the flags is strong
13721      enough for the reversed compare or (b) we have a valid FP compare.  */
13722   if (! ix86_comparison_operator (new_op1, VOIDmode))
13723     FAIL;
13724 })
13725
13726 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13727 ;; subsequent logical operations are used to imitate conditional moves.
13728 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13729 ;; it directly.
13730
13731 (define_insn "*sse_setccsf"
13732   [(set (match_operand:SF 0 "register_operand" "=x")
13733         (match_operator:SF 1 "sse_comparison_operator"
13734           [(match_operand:SF 2 "register_operand" "0")
13735            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13736   "TARGET_SSE"
13737   "cmp%D1ss\t{%3, %0|%0, %3}"
13738   [(set_attr "type" "ssecmp")
13739    (set_attr "mode" "SF")])
13740
13741 (define_insn "*sse_setccdf"
13742   [(set (match_operand:DF 0 "register_operand" "=x")
13743         (match_operator:DF 1 "sse_comparison_operator"
13744           [(match_operand:DF 2 "register_operand" "0")
13745            (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
13746   "TARGET_SSE2"
13747   "cmp%D1sd\t{%3, %0|%0, %3}"
13748   [(set_attr "type" "ssecmp")
13749    (set_attr "mode" "DF")])
13750 \f
13751 ;; Basic conditional jump instructions.
13752 ;; We ignore the overflow flag for signed branch instructions.
13753
13754 ;; For all bCOND expanders, also expand the compare or test insn that
13755 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13756
13757 (define_expand "beq"
13758   [(set (pc)
13759         (if_then_else (match_dup 1)
13760                       (label_ref (match_operand 0 "" ""))
13761                       (pc)))]
13762   ""
13763   "ix86_expand_branch (EQ, operands[0]); DONE;")
13764
13765 (define_expand "bne"
13766   [(set (pc)
13767         (if_then_else (match_dup 1)
13768                       (label_ref (match_operand 0 "" ""))
13769                       (pc)))]
13770   ""
13771   "ix86_expand_branch (NE, operands[0]); DONE;")
13772
13773 (define_expand "bgt"
13774   [(set (pc)
13775         (if_then_else (match_dup 1)
13776                       (label_ref (match_operand 0 "" ""))
13777                       (pc)))]
13778   ""
13779   "ix86_expand_branch (GT, operands[0]); DONE;")
13780
13781 (define_expand "bgtu"
13782   [(set (pc)
13783         (if_then_else (match_dup 1)
13784                       (label_ref (match_operand 0 "" ""))
13785                       (pc)))]
13786   ""
13787   "ix86_expand_branch (GTU, operands[0]); DONE;")
13788
13789 (define_expand "blt"
13790   [(set (pc)
13791         (if_then_else (match_dup 1)
13792                       (label_ref (match_operand 0 "" ""))
13793                       (pc)))]
13794   ""
13795   "ix86_expand_branch (LT, operands[0]); DONE;")
13796
13797 (define_expand "bltu"
13798   [(set (pc)
13799         (if_then_else (match_dup 1)
13800                       (label_ref (match_operand 0 "" ""))
13801                       (pc)))]
13802   ""
13803   "ix86_expand_branch (LTU, operands[0]); DONE;")
13804
13805 (define_expand "bge"
13806   [(set (pc)
13807         (if_then_else (match_dup 1)
13808                       (label_ref (match_operand 0 "" ""))
13809                       (pc)))]
13810   ""
13811   "ix86_expand_branch (GE, operands[0]); DONE;")
13812
13813 (define_expand "bgeu"
13814   [(set (pc)
13815         (if_then_else (match_dup 1)
13816                       (label_ref (match_operand 0 "" ""))
13817                       (pc)))]
13818   ""
13819   "ix86_expand_branch (GEU, operands[0]); DONE;")
13820
13821 (define_expand "ble"
13822   [(set (pc)
13823         (if_then_else (match_dup 1)
13824                       (label_ref (match_operand 0 "" ""))
13825                       (pc)))]
13826   ""
13827   "ix86_expand_branch (LE, operands[0]); DONE;")
13828
13829 (define_expand "bleu"
13830   [(set (pc)
13831         (if_then_else (match_dup 1)
13832                       (label_ref (match_operand 0 "" ""))
13833                       (pc)))]
13834   ""
13835   "ix86_expand_branch (LEU, operands[0]); DONE;")
13836
13837 (define_expand "bunordered"
13838   [(set (pc)
13839         (if_then_else (match_dup 1)
13840                       (label_ref (match_operand 0 "" ""))
13841                       (pc)))]
13842   "TARGET_80387 || TARGET_SSE_MATH"
13843   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13844
13845 (define_expand "bordered"
13846   [(set (pc)
13847         (if_then_else (match_dup 1)
13848                       (label_ref (match_operand 0 "" ""))
13849                       (pc)))]
13850   "TARGET_80387 || TARGET_SSE_MATH"
13851   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13852
13853 (define_expand "buneq"
13854   [(set (pc)
13855         (if_then_else (match_dup 1)
13856                       (label_ref (match_operand 0 "" ""))
13857                       (pc)))]
13858   "TARGET_80387 || TARGET_SSE_MATH"
13859   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13860
13861 (define_expand "bunge"
13862   [(set (pc)
13863         (if_then_else (match_dup 1)
13864                       (label_ref (match_operand 0 "" ""))
13865                       (pc)))]
13866   "TARGET_80387 || TARGET_SSE_MATH"
13867   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13868
13869 (define_expand "bungt"
13870   [(set (pc)
13871         (if_then_else (match_dup 1)
13872                       (label_ref (match_operand 0 "" ""))
13873                       (pc)))]
13874   "TARGET_80387 || TARGET_SSE_MATH"
13875   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13876
13877 (define_expand "bunle"
13878   [(set (pc)
13879         (if_then_else (match_dup 1)
13880                       (label_ref (match_operand 0 "" ""))
13881                       (pc)))]
13882   "TARGET_80387 || TARGET_SSE_MATH"
13883   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13884
13885 (define_expand "bunlt"
13886   [(set (pc)
13887         (if_then_else (match_dup 1)
13888                       (label_ref (match_operand 0 "" ""))
13889                       (pc)))]
13890   "TARGET_80387 || TARGET_SSE_MATH"
13891   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13892
13893 (define_expand "bltgt"
13894   [(set (pc)
13895         (if_then_else (match_dup 1)
13896                       (label_ref (match_operand 0 "" ""))
13897                       (pc)))]
13898   "TARGET_80387 || TARGET_SSE_MATH"
13899   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13900
13901 (define_insn "*jcc_1"
13902   [(set (pc)
13903         (if_then_else (match_operator 1 "ix86_comparison_operator"
13904                                       [(reg FLAGS_REG) (const_int 0)])
13905                       (label_ref (match_operand 0 "" ""))
13906                       (pc)))]
13907   ""
13908   "%+j%C1\t%l0"
13909   [(set_attr "type" "ibr")
13910    (set_attr "modrm" "0")
13911    (set (attr "length")
13912            (if_then_else (and (ge (minus (match_dup 0) (pc))
13913                                   (const_int -126))
13914                               (lt (minus (match_dup 0) (pc))
13915                                   (const_int 128)))
13916              (const_int 2)
13917              (const_int 6)))])
13918
13919 (define_insn "*jcc_2"
13920   [(set (pc)
13921         (if_then_else (match_operator 1 "ix86_comparison_operator"
13922                                       [(reg FLAGS_REG) (const_int 0)])
13923                       (pc)
13924                       (label_ref (match_operand 0 "" ""))))]
13925   ""
13926   "%+j%c1\t%l0"
13927   [(set_attr "type" "ibr")
13928    (set_attr "modrm" "0")
13929    (set (attr "length")
13930            (if_then_else (and (ge (minus (match_dup 0) (pc))
13931                                   (const_int -126))
13932                               (lt (minus (match_dup 0) (pc))
13933                                   (const_int 128)))
13934              (const_int 2)
13935              (const_int 6)))])
13936
13937 ;; In general it is not safe to assume too much about CCmode registers,
13938 ;; so simplify-rtx stops when it sees a second one.  Under certain
13939 ;; conditions this is safe on x86, so help combine not create
13940 ;;
13941 ;;      seta    %al
13942 ;;      testb   %al, %al
13943 ;;      je      Lfoo
13944
13945 (define_split
13946   [(set (pc)
13947         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13948                                       [(reg FLAGS_REG) (const_int 0)])
13949                           (const_int 0))
13950                       (label_ref (match_operand 1 "" ""))
13951                       (pc)))]
13952   ""
13953   [(set (pc)
13954         (if_then_else (match_dup 0)
13955                       (label_ref (match_dup 1))
13956                       (pc)))]
13957 {
13958   PUT_MODE (operands[0], VOIDmode);
13959 })
13960
13961 (define_split
13962   [(set (pc)
13963         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13964                                       [(reg FLAGS_REG) (const_int 0)])
13965                           (const_int 0))
13966                       (label_ref (match_operand 1 "" ""))
13967                       (pc)))]
13968   ""
13969   [(set (pc)
13970         (if_then_else (match_dup 0)
13971                       (label_ref (match_dup 1))
13972                       (pc)))]
13973 {
13974   rtx new_op0 = copy_rtx (operands[0]);
13975   operands[0] = new_op0;
13976   PUT_MODE (new_op0, VOIDmode);
13977   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13978                                              GET_MODE (XEXP (new_op0, 0))));
13979
13980   /* Make sure that (a) the CCmode we have for the flags is strong
13981      enough for the reversed compare or (b) we have a valid FP compare.  */
13982   if (! ix86_comparison_operator (new_op0, VOIDmode))
13983     FAIL;
13984 })
13985
13986 ;; Define combination compare-and-branch fp compare instructions to use
13987 ;; during early optimization.  Splitting the operation apart early makes
13988 ;; for bad code when we want to reverse the operation.
13989
13990 (define_insn "*fp_jcc_1_mixed"
13991   [(set (pc)
13992         (if_then_else (match_operator 0 "comparison_operator"
13993                         [(match_operand 1 "register_operand" "f,x")
13994                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13995           (label_ref (match_operand 3 "" ""))
13996           (pc)))
13997    (clobber (reg:CCFP FPSR_REG))
13998    (clobber (reg:CCFP FLAGS_REG))]
13999   "TARGET_MIX_SSE_I387
14000    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14001    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14002    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14003   "#")
14004
14005 (define_insn "*fp_jcc_1_sse"
14006   [(set (pc)
14007         (if_then_else (match_operator 0 "comparison_operator"
14008                         [(match_operand 1 "register_operand" "x")
14009                          (match_operand 2 "nonimmediate_operand" "xm")])
14010           (label_ref (match_operand 3 "" ""))
14011           (pc)))
14012    (clobber (reg:CCFP FPSR_REG))
14013    (clobber (reg:CCFP FLAGS_REG))]
14014   "TARGET_SSE_MATH
14015    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14016    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14017    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14018   "#")
14019
14020 (define_insn "*fp_jcc_1_387"
14021   [(set (pc)
14022         (if_then_else (match_operator 0 "comparison_operator"
14023                         [(match_operand 1 "register_operand" "f")
14024                          (match_operand 2 "register_operand" "f")])
14025           (label_ref (match_operand 3 "" ""))
14026           (pc)))
14027    (clobber (reg:CCFP FPSR_REG))
14028    (clobber (reg:CCFP FLAGS_REG))]
14029   "TARGET_CMOVE && TARGET_80387
14030    && FLOAT_MODE_P (GET_MODE (operands[1]))
14031    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14032    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14033   "#")
14034
14035 (define_insn "*fp_jcc_2_mixed"
14036   [(set (pc)
14037         (if_then_else (match_operator 0 "comparison_operator"
14038                         [(match_operand 1 "register_operand" "f,x")
14039                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14040           (pc)
14041           (label_ref (match_operand 3 "" ""))))
14042    (clobber (reg:CCFP FPSR_REG))
14043    (clobber (reg:CCFP FLAGS_REG))]
14044   "TARGET_MIX_SSE_I387
14045    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14046    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14047    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14048   "#")
14049
14050 (define_insn "*fp_jcc_2_sse"
14051   [(set (pc)
14052         (if_then_else (match_operator 0 "comparison_operator"
14053                         [(match_operand 1 "register_operand" "x")
14054                          (match_operand 2 "nonimmediate_operand" "xm")])
14055           (pc)
14056           (label_ref (match_operand 3 "" ""))))
14057    (clobber (reg:CCFP FPSR_REG))
14058    (clobber (reg:CCFP FLAGS_REG))]
14059   "TARGET_SSE_MATH
14060    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14061    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14062    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14063   "#")
14064
14065 (define_insn "*fp_jcc_2_387"
14066   [(set (pc)
14067         (if_then_else (match_operator 0 "comparison_operator"
14068                         [(match_operand 1 "register_operand" "f")
14069                          (match_operand 2 "register_operand" "f")])
14070           (pc)
14071           (label_ref (match_operand 3 "" ""))))
14072    (clobber (reg:CCFP FPSR_REG))
14073    (clobber (reg:CCFP FLAGS_REG))]
14074   "TARGET_CMOVE && TARGET_80387
14075    && FLOAT_MODE_P (GET_MODE (operands[1]))
14076    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14077    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14078   "#")
14079
14080 (define_insn "*fp_jcc_3_387"
14081   [(set (pc)
14082         (if_then_else (match_operator 0 "comparison_operator"
14083                         [(match_operand 1 "register_operand" "f")
14084                          (match_operand 2 "nonimmediate_operand" "fm")])
14085           (label_ref (match_operand 3 "" ""))
14086           (pc)))
14087    (clobber (reg:CCFP FPSR_REG))
14088    (clobber (reg:CCFP FLAGS_REG))
14089    (clobber (match_scratch:HI 4 "=a"))]
14090   "TARGET_80387
14091    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14092    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14093    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14094    && SELECT_CC_MODE (GET_CODE (operands[0]),
14095                       operands[1], operands[2]) == CCFPmode
14096    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14097   "#")
14098
14099 (define_insn "*fp_jcc_4_387"
14100   [(set (pc)
14101         (if_then_else (match_operator 0 "comparison_operator"
14102                         [(match_operand 1 "register_operand" "f")
14103                          (match_operand 2 "nonimmediate_operand" "fm")])
14104           (pc)
14105           (label_ref (match_operand 3 "" ""))))
14106    (clobber (reg:CCFP FPSR_REG))
14107    (clobber (reg:CCFP FLAGS_REG))
14108    (clobber (match_scratch:HI 4 "=a"))]
14109   "TARGET_80387
14110    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14111    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14112    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14113    && SELECT_CC_MODE (GET_CODE (operands[0]),
14114                       operands[1], operands[2]) == CCFPmode
14115    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14116   "#")
14117
14118 (define_insn "*fp_jcc_5_387"
14119   [(set (pc)
14120         (if_then_else (match_operator 0 "comparison_operator"
14121                         [(match_operand 1 "register_operand" "f")
14122                          (match_operand 2 "register_operand" "f")])
14123           (label_ref (match_operand 3 "" ""))
14124           (pc)))
14125    (clobber (reg:CCFP FPSR_REG))
14126    (clobber (reg:CCFP FLAGS_REG))
14127    (clobber (match_scratch:HI 4 "=a"))]
14128   "TARGET_80387
14129    && FLOAT_MODE_P (GET_MODE (operands[1]))
14130    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14131    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14132   "#")
14133
14134 (define_insn "*fp_jcc_6_387"
14135   [(set (pc)
14136         (if_then_else (match_operator 0 "comparison_operator"
14137                         [(match_operand 1 "register_operand" "f")
14138                          (match_operand 2 "register_operand" "f")])
14139           (pc)
14140           (label_ref (match_operand 3 "" ""))))
14141    (clobber (reg:CCFP FPSR_REG))
14142    (clobber (reg:CCFP FLAGS_REG))
14143    (clobber (match_scratch:HI 4 "=a"))]
14144   "TARGET_80387
14145    && FLOAT_MODE_P (GET_MODE (operands[1]))
14146    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14147    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14148   "#")
14149
14150 (define_insn "*fp_jcc_7_387"
14151   [(set (pc)
14152         (if_then_else (match_operator 0 "comparison_operator"
14153                         [(match_operand 1 "register_operand" "f")
14154                          (match_operand 2 "const0_operand" "X")])
14155           (label_ref (match_operand 3 "" ""))
14156           (pc)))
14157    (clobber (reg:CCFP FPSR_REG))
14158    (clobber (reg:CCFP FLAGS_REG))
14159    (clobber (match_scratch:HI 4 "=a"))]
14160   "TARGET_80387
14161    && FLOAT_MODE_P (GET_MODE (operands[1]))
14162    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14163    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14164    && SELECT_CC_MODE (GET_CODE (operands[0]),
14165                       operands[1], operands[2]) == CCFPmode
14166    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14167   "#")
14168
14169 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14170 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14171 ;; with a precedence over other operators and is always put in the first
14172 ;; place. Swap condition and operands to match ficom instruction.
14173
14174 (define_insn "*fp_jcc_8<mode>_387"
14175   [(set (pc)
14176         (if_then_else (match_operator 0 "comparison_operator"
14177                         [(match_operator 1 "float_operator"
14178                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14179                            (match_operand 3 "register_operand" "f,f")])
14180           (label_ref (match_operand 4 "" ""))
14181           (pc)))
14182    (clobber (reg:CCFP FPSR_REG))
14183    (clobber (reg:CCFP FLAGS_REG))
14184    (clobber (match_scratch:HI 5 "=a,a"))]
14185   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14186    && FLOAT_MODE_P (GET_MODE (operands[3]))
14187    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14188    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14189    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14190    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14191   "#")
14192
14193 (define_split
14194   [(set (pc)
14195         (if_then_else (match_operator 0 "comparison_operator"
14196                         [(match_operand 1 "register_operand" "")
14197                          (match_operand 2 "nonimmediate_operand" "")])
14198           (match_operand 3 "" "")
14199           (match_operand 4 "" "")))
14200    (clobber (reg:CCFP FPSR_REG))
14201    (clobber (reg:CCFP FLAGS_REG))]
14202   "reload_completed"
14203   [(const_int 0)]
14204 {
14205   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14206                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14207   DONE;
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 "general_operand" "")])
14215           (match_operand 3 "" "")
14216           (match_operand 4 "" "")))
14217    (clobber (reg:CCFP FPSR_REG))
14218    (clobber (reg:CCFP FLAGS_REG))
14219    (clobber (match_scratch:HI 5 "=a"))]
14220   "reload_completed"
14221   [(const_int 0)]
14222 {
14223   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14224                         operands[3], operands[4], operands[5], NULL_RTX);
14225   DONE;
14226 })
14227
14228 (define_split
14229   [(set (pc)
14230         (if_then_else (match_operator 0 "comparison_operator"
14231                         [(match_operator 1 "float_operator"
14232                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14233                            (match_operand 3 "register_operand" "")])
14234           (match_operand 4 "" "")
14235           (match_operand 5 "" "")))
14236    (clobber (reg:CCFP FPSR_REG))
14237    (clobber (reg:CCFP FLAGS_REG))
14238    (clobber (match_scratch:HI 6 "=a"))]
14239   "reload_completed"
14240   [(const_int 0)]
14241 {
14242   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14243   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14244                         operands[3], operands[7],
14245                         operands[4], operands[5], operands[6], NULL_RTX);
14246   DONE;
14247 })
14248
14249 ;; %%% Kill this when reload knows how to do it.
14250 (define_split
14251   [(set (pc)
14252         (if_then_else (match_operator 0 "comparison_operator"
14253                         [(match_operator 1 "float_operator"
14254                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14255                            (match_operand 3 "register_operand" "")])
14256           (match_operand 4 "" "")
14257           (match_operand 5 "" "")))
14258    (clobber (reg:CCFP FPSR_REG))
14259    (clobber (reg:CCFP FLAGS_REG))
14260    (clobber (match_scratch:HI 6 "=a"))]
14261   "reload_completed"
14262   [(const_int 0)]
14263 {
14264   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14265   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14266   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14267                         operands[3], operands[7],
14268                         operands[4], operands[5], operands[6], operands[2]);
14269   DONE;
14270 })
14271 \f
14272 ;; Unconditional and other jump instructions
14273
14274 (define_insn "jump"
14275   [(set (pc)
14276         (label_ref (match_operand 0 "" "")))]
14277   ""
14278   "jmp\t%l0"
14279   [(set_attr "type" "ibr")
14280    (set (attr "length")
14281            (if_then_else (and (ge (minus (match_dup 0) (pc))
14282                                   (const_int -126))
14283                               (lt (minus (match_dup 0) (pc))
14284                                   (const_int 128)))
14285              (const_int 2)
14286              (const_int 5)))
14287    (set_attr "modrm" "0")])
14288
14289 (define_expand "indirect_jump"
14290   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
14291   ""
14292   "")
14293
14294 (define_insn "*indirect_jump"
14295   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14296   "!TARGET_64BIT"
14297   "jmp\t%A0"
14298   [(set_attr "type" "ibr")
14299    (set_attr "length_immediate" "0")])
14300
14301 (define_insn "*indirect_jump_rtx64"
14302   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14303   "TARGET_64BIT"
14304   "jmp\t%A0"
14305   [(set_attr "type" "ibr")
14306    (set_attr "length_immediate" "0")])
14307
14308 (define_expand "tablejump"
14309   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14310               (use (label_ref (match_operand 1 "" "")))])]
14311   ""
14312 {
14313   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14314      relative.  Convert the relative address to an absolute address.  */
14315   if (flag_pic)
14316     {
14317       rtx op0, op1;
14318       enum rtx_code code;
14319
14320       if (TARGET_64BIT)
14321         {
14322           code = PLUS;
14323           op0 = operands[0];
14324           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14325         }
14326       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14327         {
14328           code = PLUS;
14329           op0 = operands[0];
14330           op1 = pic_offset_table_rtx;
14331         }
14332       else
14333         {
14334           code = MINUS;
14335           op0 = pic_offset_table_rtx;
14336           op1 = operands[0];
14337         }
14338
14339       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14340                                          OPTAB_DIRECT);
14341     }
14342 })
14343
14344 (define_insn "*tablejump_1"
14345   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14346    (use (label_ref (match_operand 1 "" "")))]
14347   "!TARGET_64BIT"
14348   "jmp\t%A0"
14349   [(set_attr "type" "ibr")
14350    (set_attr "length_immediate" "0")])
14351
14352 (define_insn "*tablejump_1_rtx64"
14353   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14354    (use (label_ref (match_operand 1 "" "")))]
14355   "TARGET_64BIT"
14356   "jmp\t%A0"
14357   [(set_attr "type" "ibr")
14358    (set_attr "length_immediate" "0")])
14359 \f
14360 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14361
14362 (define_peephole2
14363   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14364    (set (match_operand:QI 1 "register_operand" "")
14365         (match_operator:QI 2 "ix86_comparison_operator"
14366           [(reg FLAGS_REG) (const_int 0)]))
14367    (set (match_operand 3 "q_regs_operand" "")
14368         (zero_extend (match_dup 1)))]
14369   "(peep2_reg_dead_p (3, operands[1])
14370     || operands_match_p (operands[1], operands[3]))
14371    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14372   [(set (match_dup 4) (match_dup 0))
14373    (set (strict_low_part (match_dup 5))
14374         (match_dup 2))]
14375 {
14376   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14377   operands[5] = gen_lowpart (QImode, operands[3]);
14378   ix86_expand_clear (operands[3]);
14379 })
14380
14381 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14382
14383 (define_peephole2
14384   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14385    (set (match_operand:QI 1 "register_operand" "")
14386         (match_operator:QI 2 "ix86_comparison_operator"
14387           [(reg FLAGS_REG) (const_int 0)]))
14388    (parallel [(set (match_operand 3 "q_regs_operand" "")
14389                    (zero_extend (match_dup 1)))
14390               (clobber (reg:CC FLAGS_REG))])]
14391   "(peep2_reg_dead_p (3, operands[1])
14392     || operands_match_p (operands[1], operands[3]))
14393    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14394   [(set (match_dup 4) (match_dup 0))
14395    (set (strict_low_part (match_dup 5))
14396         (match_dup 2))]
14397 {
14398   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14399   operands[5] = gen_lowpart (QImode, operands[3]);
14400   ix86_expand_clear (operands[3]);
14401 })
14402 \f
14403 ;; Call instructions.
14404
14405 ;; The predicates normally associated with named expanders are not properly
14406 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14407 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14408
14409 ;; Call subroutine returning no value.
14410
14411 (define_expand "call_pop"
14412   [(parallel [(call (match_operand:QI 0 "" "")
14413                     (match_operand:SI 1 "" ""))
14414               (set (reg:SI SP_REG)
14415                    (plus:SI (reg:SI SP_REG)
14416                             (match_operand:SI 3 "" "")))])]
14417   "!TARGET_64BIT"
14418 {
14419   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14420   DONE;
14421 })
14422
14423 (define_insn "*call_pop_0"
14424   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14425          (match_operand:SI 1 "" ""))
14426    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14427                             (match_operand:SI 2 "immediate_operand" "")))]
14428   "!TARGET_64BIT"
14429 {
14430   if (SIBLING_CALL_P (insn))
14431     return "jmp\t%P0";
14432   else
14433     return "call\t%P0";
14434 }
14435   [(set_attr "type" "call")])
14436
14437 (define_insn "*call_pop_1"
14438   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14439          (match_operand:SI 1 "" ""))
14440    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14441                             (match_operand:SI 2 "immediate_operand" "i")))]
14442   "!TARGET_64BIT"
14443 {
14444   if (constant_call_address_operand (operands[0], Pmode))
14445     {
14446       if (SIBLING_CALL_P (insn))
14447         return "jmp\t%P0";
14448       else
14449         return "call\t%P0";
14450     }
14451   if (SIBLING_CALL_P (insn))
14452     return "jmp\t%A0";
14453   else
14454     return "call\t%A0";
14455 }
14456   [(set_attr "type" "call")])
14457
14458 (define_expand "call"
14459   [(call (match_operand:QI 0 "" "")
14460          (match_operand 1 "" ""))
14461    (use (match_operand 2 "" ""))]
14462   ""
14463 {
14464   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14465   DONE;
14466 })
14467
14468 (define_expand "sibcall"
14469   [(call (match_operand:QI 0 "" "")
14470          (match_operand 1 "" ""))
14471    (use (match_operand 2 "" ""))]
14472   ""
14473 {
14474   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14475   DONE;
14476 })
14477
14478 (define_insn "*call_0"
14479   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14480          (match_operand 1 "" ""))]
14481   ""
14482 {
14483   if (SIBLING_CALL_P (insn))
14484     return "jmp\t%P0";
14485   else
14486     return "call\t%P0";
14487 }
14488   [(set_attr "type" "call")])
14489
14490 (define_insn "*call_1"
14491   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14492          (match_operand 1 "" ""))]
14493   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14494 {
14495   if (constant_call_address_operand (operands[0], Pmode))
14496     return "call\t%P0";
14497   return "call\t%A0";
14498 }
14499   [(set_attr "type" "call")])
14500
14501 (define_insn "*sibcall_1"
14502   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14503          (match_operand 1 "" ""))]
14504   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14505 {
14506   if (constant_call_address_operand (operands[0], Pmode))
14507     return "jmp\t%P0";
14508   return "jmp\t%A0";
14509 }
14510   [(set_attr "type" "call")])
14511
14512 (define_insn "*call_1_rex64"
14513   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14514          (match_operand 1 "" ""))]
14515   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14516 {
14517   if (constant_call_address_operand (operands[0], Pmode))
14518     return "call\t%P0";
14519   return "call\t%A0";
14520 }
14521   [(set_attr "type" "call")])
14522
14523 (define_insn "*sibcall_1_rex64"
14524   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14525          (match_operand 1 "" ""))]
14526   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14527   "jmp\t%P0"
14528   [(set_attr "type" "call")])
14529
14530 (define_insn "*sibcall_1_rex64_v"
14531   [(call (mem:QI (reg:DI R11_REG))
14532          (match_operand 0 "" ""))]
14533   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14534   "jmp\t*%%r11"
14535   [(set_attr "type" "call")])
14536
14537
14538 ;; Call subroutine, returning value in operand 0
14539
14540 (define_expand "call_value_pop"
14541   [(parallel [(set (match_operand 0 "" "")
14542                    (call (match_operand:QI 1 "" "")
14543                          (match_operand:SI 2 "" "")))
14544               (set (reg:SI SP_REG)
14545                    (plus:SI (reg:SI SP_REG)
14546                             (match_operand:SI 4 "" "")))])]
14547   "!TARGET_64BIT"
14548 {
14549   ix86_expand_call (operands[0], operands[1], operands[2],
14550                     operands[3], operands[4], 0);
14551   DONE;
14552 })
14553
14554 (define_expand "call_value"
14555   [(set (match_operand 0 "" "")
14556         (call (match_operand:QI 1 "" "")
14557               (match_operand:SI 2 "" "")))
14558    (use (match_operand:SI 3 "" ""))]
14559   ;; Operand 2 not used on the i386.
14560   ""
14561 {
14562   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14563   DONE;
14564 })
14565
14566 (define_expand "sibcall_value"
14567   [(set (match_operand 0 "" "")
14568         (call (match_operand:QI 1 "" "")
14569               (match_operand:SI 2 "" "")))
14570    (use (match_operand:SI 3 "" ""))]
14571   ;; Operand 2 not used on the i386.
14572   ""
14573 {
14574   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14575   DONE;
14576 })
14577
14578 ;; Call subroutine returning any type.
14579
14580 (define_expand "untyped_call"
14581   [(parallel [(call (match_operand 0 "" "")
14582                     (const_int 0))
14583               (match_operand 1 "" "")
14584               (match_operand 2 "" "")])]
14585   ""
14586 {
14587   int i;
14588
14589   /* In order to give reg-stack an easier job in validating two
14590      coprocessor registers as containing a possible return value,
14591      simply pretend the untyped call returns a complex long double
14592      value.  */
14593
14594   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14595                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14596                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14597                     NULL, 0);
14598
14599   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14600     {
14601       rtx set = XVECEXP (operands[2], 0, i);
14602       emit_move_insn (SET_DEST (set), SET_SRC (set));
14603     }
14604
14605   /* The optimizer does not know that the call sets the function value
14606      registers we stored in the result block.  We avoid problems by
14607      claiming that all hard registers are used and clobbered at this
14608      point.  */
14609   emit_insn (gen_blockage (const0_rtx));
14610
14611   DONE;
14612 })
14613 \f
14614 ;; Prologue and epilogue instructions
14615
14616 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14617 ;; all of memory.  This blocks insns from being moved across this point.
14618
14619 (define_insn "blockage"
14620   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14621   ""
14622   ""
14623   [(set_attr "length" "0")])
14624
14625 ;; Insn emitted into the body of a function to return from a function.
14626 ;; This is only done if the function's epilogue is known to be simple.
14627 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14628
14629 (define_expand "return"
14630   [(return)]
14631   "ix86_can_use_return_insn_p ()"
14632 {
14633   if (current_function_pops_args)
14634     {
14635       rtx popc = GEN_INT (current_function_pops_args);
14636       emit_jump_insn (gen_return_pop_internal (popc));
14637       DONE;
14638     }
14639 })
14640
14641 (define_insn "return_internal"
14642   [(return)]
14643   "reload_completed"
14644   "ret"
14645   [(set_attr "length" "1")
14646    (set_attr "length_immediate" "0")
14647    (set_attr "modrm" "0")])
14648
14649 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14650 ;; instruction Athlon and K8 have.
14651
14652 (define_insn "return_internal_long"
14653   [(return)
14654    (unspec [(const_int 0)] UNSPEC_REP)]
14655   "reload_completed"
14656   "rep {;} ret"
14657   [(set_attr "length" "1")
14658    (set_attr "length_immediate" "0")
14659    (set_attr "prefix_rep" "1")
14660    (set_attr "modrm" "0")])
14661
14662 (define_insn "return_pop_internal"
14663   [(return)
14664    (use (match_operand:SI 0 "const_int_operand" ""))]
14665   "reload_completed"
14666   "ret\t%0"
14667   [(set_attr "length" "3")
14668    (set_attr "length_immediate" "2")
14669    (set_attr "modrm" "0")])
14670
14671 (define_insn "return_indirect_internal"
14672   [(return)
14673    (use (match_operand:SI 0 "register_operand" "r"))]
14674   "reload_completed"
14675   "jmp\t%A0"
14676   [(set_attr "type" "ibr")
14677    (set_attr "length_immediate" "0")])
14678
14679 (define_insn "nop"
14680   [(const_int 0)]
14681   ""
14682   "nop"
14683   [(set_attr "length" "1")
14684    (set_attr "length_immediate" "0")
14685    (set_attr "modrm" "0")])
14686
14687 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14688 ;; branch prediction penalty for the third jump in a 16-byte
14689 ;; block on K8.
14690
14691 (define_insn "align"
14692   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14693   ""
14694 {
14695 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14696   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14697 #else
14698   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14699      The align insn is used to avoid 3 jump instructions in the row to improve
14700      branch prediction and the benefits hardly outweigh the cost of extra 8
14701      nops on the average inserted by full alignment pseudo operation.  */
14702 #endif
14703   return "";
14704 }
14705   [(set_attr "length" "16")])
14706
14707 (define_expand "prologue"
14708   [(const_int 1)]
14709   ""
14710   "ix86_expand_prologue (); DONE;")
14711
14712 (define_insn "set_got"
14713   [(set (match_operand:SI 0 "register_operand" "=r")
14714         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14715    (clobber (reg:CC FLAGS_REG))]
14716   "!TARGET_64BIT"
14717   { return output_set_got (operands[0], NULL_RTX); }
14718   [(set_attr "type" "multi")
14719    (set_attr "length" "12")])
14720
14721 (define_insn "set_got_labelled"
14722   [(set (match_operand:SI 0 "register_operand" "=r")
14723         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14724          UNSPEC_SET_GOT))
14725    (clobber (reg:CC FLAGS_REG))]
14726   "!TARGET_64BIT"
14727   { return output_set_got (operands[0], operands[1]); }
14728   [(set_attr "type" "multi")
14729    (set_attr "length" "12")])
14730
14731 (define_insn "set_got_rex64"
14732   [(set (match_operand:DI 0 "register_operand" "=r")
14733         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14734   "TARGET_64BIT"
14735   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14736   [(set_attr "type" "lea")
14737    (set_attr "length" "6")])
14738
14739 (define_expand "epilogue"
14740   [(const_int 1)]
14741   ""
14742   "ix86_expand_epilogue (1); DONE;")
14743
14744 (define_expand "sibcall_epilogue"
14745   [(const_int 1)]
14746   ""
14747   "ix86_expand_epilogue (0); DONE;")
14748
14749 (define_expand "eh_return"
14750   [(use (match_operand 0 "register_operand" ""))]
14751   ""
14752 {
14753   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14754
14755   /* Tricky bit: we write the address of the handler to which we will
14756      be returning into someone else's stack frame, one word below the
14757      stack address we wish to restore.  */
14758   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14759   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14760   tmp = gen_rtx_MEM (Pmode, tmp);
14761   emit_move_insn (tmp, ra);
14762
14763   if (Pmode == SImode)
14764     emit_jump_insn (gen_eh_return_si (sa));
14765   else
14766     emit_jump_insn (gen_eh_return_di (sa));
14767   emit_barrier ();
14768   DONE;
14769 })
14770
14771 (define_insn_and_split "eh_return_si"
14772   [(set (pc)
14773         (unspec [(match_operand:SI 0 "register_operand" "c")]
14774                  UNSPEC_EH_RETURN))]
14775   "!TARGET_64BIT"
14776   "#"
14777   "reload_completed"
14778   [(const_int 1)]
14779   "ix86_expand_epilogue (2); DONE;")
14780
14781 (define_insn_and_split "eh_return_di"
14782   [(set (pc)
14783         (unspec [(match_operand:DI 0 "register_operand" "c")]
14784                  UNSPEC_EH_RETURN))]
14785   "TARGET_64BIT"
14786   "#"
14787   "reload_completed"
14788   [(const_int 1)]
14789   "ix86_expand_epilogue (2); DONE;")
14790
14791 (define_insn "leave"
14792   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14793    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14794    (clobber (mem:BLK (scratch)))]
14795   "!TARGET_64BIT"
14796   "leave"
14797   [(set_attr "type" "leave")])
14798
14799 (define_insn "leave_rex64"
14800   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14801    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14802    (clobber (mem:BLK (scratch)))]
14803   "TARGET_64BIT"
14804   "leave"
14805   [(set_attr "type" "leave")])
14806 \f
14807 (define_expand "ffssi2"
14808   [(parallel
14809      [(set (match_operand:SI 0 "register_operand" "")
14810            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14811       (clobber (match_scratch:SI 2 ""))
14812       (clobber (reg:CC FLAGS_REG))])]
14813   ""
14814   "")
14815
14816 (define_insn_and_split "*ffs_cmove"
14817   [(set (match_operand:SI 0 "register_operand" "=r")
14818         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14819    (clobber (match_scratch:SI 2 "=&r"))
14820    (clobber (reg:CC FLAGS_REG))]
14821   "TARGET_CMOVE"
14822   "#"
14823   "&& reload_completed"
14824   [(set (match_dup 2) (const_int -1))
14825    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14826               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14827    (set (match_dup 0) (if_then_else:SI
14828                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14829                         (match_dup 2)
14830                         (match_dup 0)))
14831    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14832               (clobber (reg:CC FLAGS_REG))])]
14833   "")
14834
14835 (define_insn_and_split "*ffs_no_cmove"
14836   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14837         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14838    (clobber (match_scratch:SI 2 "=&q"))
14839    (clobber (reg:CC FLAGS_REG))]
14840   ""
14841   "#"
14842   "reload_completed"
14843   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14844               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14845    (set (strict_low_part (match_dup 3))
14846         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14847    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14848               (clobber (reg:CC FLAGS_REG))])
14849    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14850               (clobber (reg:CC FLAGS_REG))])
14851    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14852               (clobber (reg:CC FLAGS_REG))])]
14853 {
14854   operands[3] = gen_lowpart (QImode, operands[2]);
14855   ix86_expand_clear (operands[2]);
14856 })
14857
14858 (define_insn "*ffssi_1"
14859   [(set (reg:CCZ FLAGS_REG)
14860         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14861                      (const_int 0)))
14862    (set (match_operand:SI 0 "register_operand" "=r")
14863         (ctz:SI (match_dup 1)))]
14864   ""
14865   "bsf{l}\t{%1, %0|%0, %1}"
14866   [(set_attr "prefix_0f" "1")])
14867
14868 (define_expand "ffsdi2"
14869   [(parallel
14870      [(set (match_operand:DI 0 "register_operand" "")
14871            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14872       (clobber (match_scratch:DI 2 ""))
14873       (clobber (reg:CC FLAGS_REG))])]
14874   "TARGET_64BIT && TARGET_CMOVE"
14875   "")
14876
14877 (define_insn_and_split "*ffs_rex64"
14878   [(set (match_operand:DI 0 "register_operand" "=r")
14879         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14880    (clobber (match_scratch:DI 2 "=&r"))
14881    (clobber (reg:CC FLAGS_REG))]
14882   "TARGET_64BIT && TARGET_CMOVE"
14883   "#"
14884   "&& reload_completed"
14885   [(set (match_dup 2) (const_int -1))
14886    (parallel [(set (reg:CCZ FLAGS_REG)
14887                    (compare:CCZ (match_dup 1) (const_int 0)))
14888               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14889    (set (match_dup 0) (if_then_else:DI
14890                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14891                         (match_dup 2)
14892                         (match_dup 0)))
14893    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14894               (clobber (reg:CC FLAGS_REG))])]
14895   "")
14896
14897 (define_insn "*ffsdi_1"
14898   [(set (reg:CCZ FLAGS_REG)
14899         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14900                      (const_int 0)))
14901    (set (match_operand:DI 0 "register_operand" "=r")
14902         (ctz:DI (match_dup 1)))]
14903   "TARGET_64BIT"
14904   "bsf{q}\t{%1, %0|%0, %1}"
14905   [(set_attr "prefix_0f" "1")])
14906
14907 (define_insn "ctzsi2"
14908   [(set (match_operand:SI 0 "register_operand" "=r")
14909         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14910    (clobber (reg:CC FLAGS_REG))]
14911   ""
14912   "bsf{l}\t{%1, %0|%0, %1}"
14913   [(set_attr "prefix_0f" "1")])
14914
14915 (define_insn "ctzdi2"
14916   [(set (match_operand:DI 0 "register_operand" "=r")
14917         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14918    (clobber (reg:CC FLAGS_REG))]
14919   "TARGET_64BIT"
14920   "bsf{q}\t{%1, %0|%0, %1}"
14921   [(set_attr "prefix_0f" "1")])
14922
14923 (define_expand "clzsi2"
14924   [(parallel
14925      [(set (match_operand:SI 0 "register_operand" "")
14926            (minus:SI (const_int 31)
14927                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14928       (clobber (reg:CC FLAGS_REG))])
14929    (parallel
14930      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14931       (clobber (reg:CC FLAGS_REG))])]
14932   ""
14933 {
14934   if (TARGET_ABM)
14935     {
14936       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14937       DONE;
14938     }
14939 })
14940
14941 (define_insn "clzsi2_abm"
14942   [(set (match_operand:SI 0 "register_operand" "=r")
14943         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14944    (clobber (reg:CC FLAGS_REG))]
14945   "TARGET_ABM"
14946   "lzcnt{l}\t{%1, %0|%0, %1}"
14947   [(set_attr "prefix_rep" "1")
14948    (set_attr "type" "bitmanip")
14949    (set_attr "mode" "SI")])
14950
14951 (define_insn "*bsr"
14952   [(set (match_operand:SI 0 "register_operand" "=r")
14953         (minus:SI (const_int 31)
14954                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14955    (clobber (reg:CC FLAGS_REG))]
14956   ""
14957   "bsr{l}\t{%1, %0|%0, %1}"
14958   [(set_attr "prefix_0f" "1")
14959    (set_attr "mode" "SI")])
14960
14961 (define_insn "popcountsi2"
14962   [(set (match_operand:SI 0 "register_operand" "=r")
14963         (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14964    (clobber (reg:CC FLAGS_REG))]
14965   "TARGET_POPCNT"
14966   "popcnt{l}\t{%1, %0|%0, %1}"
14967   [(set_attr "prefix_rep" "1")
14968    (set_attr "type" "bitmanip")
14969    (set_attr "mode" "SI")])
14970
14971 (define_insn "*popcountsi2_cmp"
14972   [(set (reg FLAGS_REG)
14973         (compare
14974           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14975           (const_int 0)))
14976    (set (match_operand:SI 0 "register_operand" "=r")
14977         (popcount:SI (match_dup 1)))]
14978   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14979   "popcnt{l}\t{%1, %0|%0, %1}"
14980   [(set_attr "prefix_rep" "1")
14981    (set_attr "type" "bitmanip")
14982    (set_attr "mode" "SI")])
14983
14984 (define_insn "*popcountsi2_cmp_zext"
14985   [(set (reg FLAGS_REG)
14986         (compare
14987           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14988           (const_int 0)))
14989    (set (match_operand:DI 0 "register_operand" "=r")
14990         (zero_extend:DI(popcount:SI (match_dup 1))))]
14991   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14992   "popcnt{l}\t{%1, %0|%0, %1}"
14993   [(set_attr "prefix_rep" "1")
14994    (set_attr "type" "bitmanip")
14995    (set_attr "mode" "SI")])
14996
14997 (define_insn "bswapsi2"
14998   [(set (match_operand:SI 0 "register_operand" "=r")
14999         (bswap:SI (match_operand:SI 1 "register_operand" "0")))
15000    (clobber (reg:CC FLAGS_REG))]
15001   "TARGET_BSWAP"
15002   "bswap\t%k0"
15003   [(set_attr "prefix_0f" "1")
15004    (set_attr "length" "2")])
15005
15006 (define_insn "*bswapdi2_rex"
15007   [(set (match_operand:DI 0 "register_operand" "=r")
15008         (bswap:DI (match_operand:DI 1 "register_operand" "0")))
15009    (clobber (reg:CC FLAGS_REG))]
15010   "TARGET_64BIT && TARGET_BSWAP"
15011   "bswap\t%0"
15012   [(set_attr "prefix_0f" "1")
15013    (set_attr "length" "3")])
15014
15015 (define_expand "bswapdi2"
15016   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15017                    (bswap:DI (match_operand:DI 1 "register_operand" "")))
15018               (clobber (reg:CC FLAGS_REG))])]
15019   "TARGET_BSWAP"
15020   {
15021     if (!TARGET_64BIT)
15022       {
15023         rtx tmp1, tmp2;
15024         tmp1 = gen_reg_rtx (SImode);
15025         tmp2 = gen_reg_rtx (SImode);
15026         emit_insn (gen_bswapsi2 (tmp1, gen_lowpart (SImode, operands[1])));
15027         emit_insn (gen_bswapsi2 (tmp2, gen_highpart (SImode, operands[1])));
15028         emit_move_insn (gen_lowpart (SImode, operands[0]), tmp2);
15029         emit_move_insn (gen_highpart (SImode, operands[0]), tmp1);
15030         DONE;
15031       }
15032   })
15033
15034 (define_expand "clzdi2"
15035   [(parallel
15036      [(set (match_operand:DI 0 "register_operand" "")
15037            (minus:DI (const_int 63)
15038                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15039       (clobber (reg:CC FLAGS_REG))])
15040    (parallel
15041      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15042       (clobber (reg:CC FLAGS_REG))])]
15043   "TARGET_64BIT"
15044 {
15045   if (TARGET_ABM)
15046     {
15047       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15048       DONE;
15049     }
15050 })
15051
15052 (define_insn "clzdi2_abm"
15053   [(set (match_operand:DI 0 "register_operand" "=r")
15054         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15055    (clobber (reg:CC FLAGS_REG))]
15056   "TARGET_64BIT && TARGET_ABM"
15057   "lzcnt{q}\t{%1, %0|%0, %1}"
15058   [(set_attr "prefix_rep" "1")
15059    (set_attr "type" "bitmanip")
15060    (set_attr "mode" "DI")])
15061
15062 (define_insn "*bsr_rex64"
15063   [(set (match_operand:DI 0 "register_operand" "=r")
15064         (minus:DI (const_int 63)
15065                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15066    (clobber (reg:CC FLAGS_REG))]
15067   "TARGET_64BIT"
15068   "bsr{q}\t{%1, %0|%0, %1}"
15069   [(set_attr "prefix_0f" "1")
15070    (set_attr "mode" "DI")])
15071
15072 (define_insn "popcountdi2"
15073   [(set (match_operand:DI 0 "register_operand" "=r")
15074         (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15075    (clobber (reg:CC FLAGS_REG))]
15076   "TARGET_64BIT && TARGET_POPCNT"
15077   "popcnt{q}\t{%1, %0|%0, %1}"
15078   [(set_attr "prefix_rep" "1")
15079    (set_attr "type" "bitmanip")
15080    (set_attr "mode" "DI")])
15081
15082 (define_insn "*popcountdi2_cmp"
15083   [(set (reg FLAGS_REG)
15084         (compare
15085           (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15086           (const_int 0)))
15087    (set (match_operand:DI 0 "register_operand" "=r")
15088         (popcount:DI (match_dup 1)))]
15089   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15090   "popcnt{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_expand "clzhi2"
15096   [(parallel
15097      [(set (match_operand:HI 0 "register_operand" "")
15098            (minus:HI (const_int 15)
15099                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15100       (clobber (reg:CC FLAGS_REG))])
15101    (parallel
15102      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15103       (clobber (reg:CC FLAGS_REG))])]
15104   ""
15105 {
15106   if (TARGET_ABM)
15107     {
15108       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15109       DONE;
15110     }
15111 })
15112
15113 (define_insn "clzhi2_abm"
15114   [(set (match_operand:HI 0 "register_operand" "=r")
15115         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15116    (clobber (reg:CC FLAGS_REG))]
15117   "TARGET_ABM"
15118   "lzcnt{w}\t{%1, %0|%0, %1}"
15119   [(set_attr "prefix_rep" "1")
15120    (set_attr "type" "bitmanip")
15121    (set_attr "mode" "HI")])
15122
15123 (define_insn "*bsrhi"
15124   [(set (match_operand:HI 0 "register_operand" "=r")
15125         (minus:HI (const_int 15)
15126                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15127    (clobber (reg:CC FLAGS_REG))]
15128   ""
15129   "bsr{w}\t{%1, %0|%0, %1}"
15130   [(set_attr "prefix_0f" "1")
15131    (set_attr "mode" "HI")])
15132
15133 (define_insn "popcounthi2"
15134   [(set (match_operand:HI 0 "register_operand" "=r")
15135         (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15136    (clobber (reg:CC FLAGS_REG))]
15137   "TARGET_POPCNT"
15138   "popcnt{w}\t{%1, %0|%0, %1}"
15139   [(set_attr "prefix_rep" "1")
15140    (set_attr "type" "bitmanip")
15141    (set_attr "mode" "HI")])
15142
15143 (define_insn "*popcounthi2_cmp"
15144   [(set (reg FLAGS_REG)
15145         (compare
15146           (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15147           (const_int 0)))
15148    (set (match_operand:HI 0 "register_operand" "=r")
15149         (popcount:HI (match_dup 1)))]
15150   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15151   "popcnt{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_expand "paritydi2"
15157   [(set (match_operand:DI 0 "register_operand" "")
15158         (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
15159   "! TARGET_POPCNT"
15160 {
15161   rtx scratch = gen_reg_rtx (QImode);
15162   rtx cond;
15163
15164   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15165                                 NULL_RTX, operands[1]));
15166
15167   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15168                          gen_rtx_REG (CCmode, FLAGS_REG),
15169                          const0_rtx);
15170   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15171
15172   if (TARGET_64BIT)
15173     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15174   else
15175     {
15176       rtx tmp = gen_reg_rtx (SImode);
15177
15178       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15179       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15180     }
15181   DONE;
15182 })
15183
15184 (define_insn_and_split "paritydi2_cmp"
15185   [(set (reg:CC FLAGS_REG)
15186         (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m")))
15187    (clobber (match_scratch:DI 0 "=r,X"))
15188    (clobber (match_scratch:SI 1 "=r,r"))
15189    (clobber (match_scratch:HI 2 "=Q,Q"))]
15190   "! TARGET_POPCNT"
15191   "#"
15192   "&& reload_completed"
15193   [(parallel
15194      [(set (match_dup 1)
15195            (xor:SI (match_dup 1) (match_dup 4)))
15196       (clobber (reg:CC FLAGS_REG))])
15197    (parallel
15198      [(set (reg:CC FLAGS_REG)
15199            (parity:CC (match_dup 1)))
15200       (clobber (match_dup 1))
15201       (clobber (match_dup 2))])]
15202 {
15203   operands[4] = gen_lowpart (SImode, operands[3]);
15204
15205   if (MEM_P (operands[3]))
15206     emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
15207   else if (! TARGET_64BIT)
15208     operands[1] = gen_highpart (SImode, operands[3]);
15209   else
15210     {
15211       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15212       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15213     }
15214 })
15215
15216 (define_expand "paritysi2"
15217   [(set (match_operand:SI 0 "register_operand" "")
15218         (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
15219   "! TARGET_POPCNT"
15220 {
15221   rtx scratch = gen_reg_rtx (QImode);
15222   rtx cond;
15223
15224   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15225
15226   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15227                          gen_rtx_REG (CCmode, FLAGS_REG),
15228                          const0_rtx);
15229   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15230
15231   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15232   DONE;
15233 })
15234
15235 (define_insn_and_split "paritysi2_cmp"
15236   [(set (reg:CC FLAGS_REG)
15237         (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
15238    (clobber (match_scratch:SI 0 "=r,X"))
15239    (clobber (match_scratch:HI 1 "=Q,Q"))]
15240   "! TARGET_POPCNT"
15241   "#"
15242   "&& reload_completed"
15243   [(parallel
15244      [(set (match_dup 1)
15245            (xor:HI (match_dup 1) (match_dup 3)))
15246       (clobber (reg:CC FLAGS_REG))])
15247    (parallel
15248      [(set (reg:CC FLAGS_REG)
15249            (parity:CC (match_dup 1)))
15250       (clobber (match_dup 1))])]
15251 {
15252   operands[3] = gen_lowpart (HImode, operands[2]);
15253
15254   if (MEM_P (operands[2]))
15255     emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
15256   else
15257     {
15258       emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15259       emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15260     }
15261 })
15262
15263 (define_insn "*parityhi2_cmp"
15264   [(set (reg:CC FLAGS_REG)
15265         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15266    (clobber (match_scratch:HI 0 "=Q"))]
15267   "! TARGET_POPCNT"
15268   "xor{b}\t{%h0, %b0|%b0, %h0}"
15269   [(set_attr "length" "2")
15270    (set_attr "mode" "HI")])
15271
15272 (define_insn "*parityqi2_cmp"
15273   [(set (reg:CC FLAGS_REG)
15274         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15275   "! TARGET_POPCNT"
15276   "test{b}\t%0, %0"
15277   [(set_attr "length" "2")
15278    (set_attr "mode" "QI")])
15279 \f
15280 ;; Thread-local storage patterns for ELF.
15281 ;;
15282 ;; Note that these code sequences must appear exactly as shown
15283 ;; in order to allow linker relaxation.
15284
15285 (define_insn "*tls_global_dynamic_32_gnu"
15286   [(set (match_operand:SI 0 "register_operand" "=a")
15287         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15288                     (match_operand:SI 2 "tls_symbolic_operand" "")
15289                     (match_operand:SI 3 "call_insn_operand" "")]
15290                     UNSPEC_TLS_GD))
15291    (clobber (match_scratch:SI 4 "=d"))
15292    (clobber (match_scratch:SI 5 "=c"))
15293    (clobber (reg:CC FLAGS_REG))]
15294   "!TARGET_64BIT && TARGET_GNU_TLS"
15295   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15296   [(set_attr "type" "multi")
15297    (set_attr "length" "12")])
15298
15299 (define_insn "*tls_global_dynamic_32_sun"
15300   [(set (match_operand:SI 0 "register_operand" "=a")
15301         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15302                     (match_operand:SI 2 "tls_symbolic_operand" "")
15303                     (match_operand:SI 3 "call_insn_operand" "")]
15304                     UNSPEC_TLS_GD))
15305    (clobber (match_scratch:SI 4 "=d"))
15306    (clobber (match_scratch:SI 5 "=c"))
15307    (clobber (reg:CC FLAGS_REG))]
15308   "!TARGET_64BIT && TARGET_SUN_TLS"
15309   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15310         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15311   [(set_attr "type" "multi")
15312    (set_attr "length" "14")])
15313
15314 (define_expand "tls_global_dynamic_32"
15315   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15316                    (unspec:SI
15317                     [(match_dup 2)
15318                      (match_operand:SI 1 "tls_symbolic_operand" "")
15319                      (match_dup 3)]
15320                     UNSPEC_TLS_GD))
15321               (clobber (match_scratch:SI 4 ""))
15322               (clobber (match_scratch:SI 5 ""))
15323               (clobber (reg:CC FLAGS_REG))])]
15324   ""
15325 {
15326   if (flag_pic)
15327     operands[2] = pic_offset_table_rtx;
15328   else
15329     {
15330       operands[2] = gen_reg_rtx (Pmode);
15331       emit_insn (gen_set_got (operands[2]));
15332     }
15333   if (TARGET_GNU2_TLS)
15334     {
15335        emit_insn (gen_tls_dynamic_gnu2_32
15336                   (operands[0], operands[1], operands[2]));
15337        DONE;
15338     }
15339   operands[3] = ix86_tls_get_addr ();
15340 })
15341
15342 (define_insn "*tls_global_dynamic_64"
15343   [(set (match_operand:DI 0 "register_operand" "=a")
15344         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15345                  (match_operand:DI 3 "" "")))
15346    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15347               UNSPEC_TLS_GD)]
15348   "TARGET_64BIT"
15349   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15350   [(set_attr "type" "multi")
15351    (set_attr "length" "16")])
15352
15353 (define_expand "tls_global_dynamic_64"
15354   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15355                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15356               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15357                          UNSPEC_TLS_GD)])]
15358   ""
15359 {
15360   if (TARGET_GNU2_TLS)
15361     {
15362        emit_insn (gen_tls_dynamic_gnu2_64
15363                   (operands[0], operands[1]));
15364        DONE;
15365     }
15366   operands[2] = ix86_tls_get_addr ();
15367 })
15368
15369 (define_insn "*tls_local_dynamic_base_32_gnu"
15370   [(set (match_operand:SI 0 "register_operand" "=a")
15371         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15372                     (match_operand:SI 2 "call_insn_operand" "")]
15373                    UNSPEC_TLS_LD_BASE))
15374    (clobber (match_scratch:SI 3 "=d"))
15375    (clobber (match_scratch:SI 4 "=c"))
15376    (clobber (reg:CC FLAGS_REG))]
15377   "!TARGET_64BIT && TARGET_GNU_TLS"
15378   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15379   [(set_attr "type" "multi")
15380    (set_attr "length" "11")])
15381
15382 (define_insn "*tls_local_dynamic_base_32_sun"
15383   [(set (match_operand:SI 0 "register_operand" "=a")
15384         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15385                     (match_operand:SI 2 "call_insn_operand" "")]
15386                    UNSPEC_TLS_LD_BASE))
15387    (clobber (match_scratch:SI 3 "=d"))
15388    (clobber (match_scratch:SI 4 "=c"))
15389    (clobber (reg:CC FLAGS_REG))]
15390   "!TARGET_64BIT && TARGET_SUN_TLS"
15391   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15392         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15393   [(set_attr "type" "multi")
15394    (set_attr "length" "13")])
15395
15396 (define_expand "tls_local_dynamic_base_32"
15397   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15398                    (unspec:SI [(match_dup 1) (match_dup 2)]
15399                               UNSPEC_TLS_LD_BASE))
15400               (clobber (match_scratch:SI 3 ""))
15401               (clobber (match_scratch:SI 4 ""))
15402               (clobber (reg:CC FLAGS_REG))])]
15403   ""
15404 {
15405   if (flag_pic)
15406     operands[1] = pic_offset_table_rtx;
15407   else
15408     {
15409       operands[1] = gen_reg_rtx (Pmode);
15410       emit_insn (gen_set_got (operands[1]));
15411     }
15412   if (TARGET_GNU2_TLS)
15413     {
15414        emit_insn (gen_tls_dynamic_gnu2_32
15415                   (operands[0], ix86_tls_module_base (), operands[1]));
15416        DONE;
15417     }
15418   operands[2] = ix86_tls_get_addr ();
15419 })
15420
15421 (define_insn "*tls_local_dynamic_base_64"
15422   [(set (match_operand:DI 0 "register_operand" "=a")
15423         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15424                  (match_operand:DI 2 "" "")))
15425    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15426   "TARGET_64BIT"
15427   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15428   [(set_attr "type" "multi")
15429    (set_attr "length" "12")])
15430
15431 (define_expand "tls_local_dynamic_base_64"
15432   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15433                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15434               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15435   ""
15436 {
15437   if (TARGET_GNU2_TLS)
15438     {
15439        emit_insn (gen_tls_dynamic_gnu2_64
15440                   (operands[0], ix86_tls_module_base ()));
15441        DONE;
15442     }
15443   operands[1] = ix86_tls_get_addr ();
15444 })
15445
15446 ;; Local dynamic of a single variable is a lose.  Show combine how
15447 ;; to convert that back to global dynamic.
15448
15449 (define_insn_and_split "*tls_local_dynamic_32_once"
15450   [(set (match_operand:SI 0 "register_operand" "=a")
15451         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15452                              (match_operand:SI 2 "call_insn_operand" "")]
15453                             UNSPEC_TLS_LD_BASE)
15454                  (const:SI (unspec:SI
15455                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15456                             UNSPEC_DTPOFF))))
15457    (clobber (match_scratch:SI 4 "=d"))
15458    (clobber (match_scratch:SI 5 "=c"))
15459    (clobber (reg:CC FLAGS_REG))]
15460   ""
15461   "#"
15462   ""
15463   [(parallel [(set (match_dup 0)
15464                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15465                               UNSPEC_TLS_GD))
15466               (clobber (match_dup 4))
15467               (clobber (match_dup 5))
15468               (clobber (reg:CC FLAGS_REG))])]
15469   "")
15470
15471 ;; Load and add the thread base pointer from %gs:0.
15472
15473 (define_insn "*load_tp_si"
15474   [(set (match_operand:SI 0 "register_operand" "=r")
15475         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15476   "!TARGET_64BIT"
15477   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15478   [(set_attr "type" "imov")
15479    (set_attr "modrm" "0")
15480    (set_attr "length" "7")
15481    (set_attr "memory" "load")
15482    (set_attr "imm_disp" "false")])
15483
15484 (define_insn "*add_tp_si"
15485   [(set (match_operand:SI 0 "register_operand" "=r")
15486         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15487                  (match_operand:SI 1 "register_operand" "0")))
15488    (clobber (reg:CC FLAGS_REG))]
15489   "!TARGET_64BIT"
15490   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15491   [(set_attr "type" "alu")
15492    (set_attr "modrm" "0")
15493    (set_attr "length" "7")
15494    (set_attr "memory" "load")
15495    (set_attr "imm_disp" "false")])
15496
15497 (define_insn "*load_tp_di"
15498   [(set (match_operand:DI 0 "register_operand" "=r")
15499         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15500   "TARGET_64BIT"
15501   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15502   [(set_attr "type" "imov")
15503    (set_attr "modrm" "0")
15504    (set_attr "length" "7")
15505    (set_attr "memory" "load")
15506    (set_attr "imm_disp" "false")])
15507
15508 (define_insn "*add_tp_di"
15509   [(set (match_operand:DI 0 "register_operand" "=r")
15510         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15511                  (match_operand:DI 1 "register_operand" "0")))
15512    (clobber (reg:CC FLAGS_REG))]
15513   "TARGET_64BIT"
15514   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15515   [(set_attr "type" "alu")
15516    (set_attr "modrm" "0")
15517    (set_attr "length" "7")
15518    (set_attr "memory" "load")
15519    (set_attr "imm_disp" "false")])
15520
15521 ;; GNU2 TLS patterns can be split.
15522
15523 (define_expand "tls_dynamic_gnu2_32"
15524   [(set (match_dup 3)
15525         (plus:SI (match_operand:SI 2 "register_operand" "")
15526                  (const:SI
15527                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15528                              UNSPEC_TLSDESC))))
15529    (parallel
15530     [(set (match_operand:SI 0 "register_operand" "")
15531           (unspec:SI [(match_dup 1) (match_dup 3)
15532                       (match_dup 2) (reg:SI SP_REG)]
15533                       UNSPEC_TLSDESC))
15534      (clobber (reg:CC FLAGS_REG))])]
15535   "!TARGET_64BIT && TARGET_GNU2_TLS"
15536 {
15537   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15538   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15539 })
15540
15541 (define_insn "*tls_dynamic_lea_32"
15542   [(set (match_operand:SI 0 "register_operand" "=r")
15543         (plus:SI (match_operand:SI 1 "register_operand" "b")
15544                  (const:SI
15545                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15546                               UNSPEC_TLSDESC))))]
15547   "!TARGET_64BIT && TARGET_GNU2_TLS"
15548   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15549   [(set_attr "type" "lea")
15550    (set_attr "mode" "SI")
15551    (set_attr "length" "6")
15552    (set_attr "length_address" "4")])
15553
15554 (define_insn "*tls_dynamic_call_32"
15555   [(set (match_operand:SI 0 "register_operand" "=a")
15556         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15557                     (match_operand:SI 2 "register_operand" "0")
15558                     ;; we have to make sure %ebx still points to the GOT
15559                     (match_operand:SI 3 "register_operand" "b")
15560                     (reg:SI SP_REG)]
15561                    UNSPEC_TLSDESC))
15562    (clobber (reg:CC FLAGS_REG))]
15563   "!TARGET_64BIT && TARGET_GNU2_TLS"
15564   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15565   [(set_attr "type" "call")
15566    (set_attr "length" "2")
15567    (set_attr "length_address" "0")])
15568
15569 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15570   [(set (match_operand:SI 0 "register_operand" "=&a")
15571         (plus:SI
15572          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15573                      (match_operand:SI 4 "" "")
15574                      (match_operand:SI 2 "register_operand" "b")
15575                      (reg:SI SP_REG)]
15576                     UNSPEC_TLSDESC)
15577          (const:SI (unspec:SI
15578                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15579                     UNSPEC_DTPOFF))))
15580    (clobber (reg:CC FLAGS_REG))]
15581   "!TARGET_64BIT && TARGET_GNU2_TLS"
15582   "#"
15583   ""
15584   [(set (match_dup 0) (match_dup 5))]
15585 {
15586   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15587   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15588 })
15589
15590 (define_expand "tls_dynamic_gnu2_64"
15591   [(set (match_dup 2)
15592         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15593                    UNSPEC_TLSDESC))
15594    (parallel
15595     [(set (match_operand:DI 0 "register_operand" "")
15596           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15597                      UNSPEC_TLSDESC))
15598      (clobber (reg:CC FLAGS_REG))])]
15599   "TARGET_64BIT && TARGET_GNU2_TLS"
15600 {
15601   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15602   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15603 })
15604
15605 (define_insn "*tls_dynamic_lea_64"
15606   [(set (match_operand:DI 0 "register_operand" "=r")
15607         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15608                    UNSPEC_TLSDESC))]
15609   "TARGET_64BIT && TARGET_GNU2_TLS"
15610   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15611   [(set_attr "type" "lea")
15612    (set_attr "mode" "DI")
15613    (set_attr "length" "7")
15614    (set_attr "length_address" "4")])
15615
15616 (define_insn "*tls_dynamic_call_64"
15617   [(set (match_operand:DI 0 "register_operand" "=a")
15618         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15619                     (match_operand:DI 2 "register_operand" "0")
15620                     (reg:DI SP_REG)]
15621                    UNSPEC_TLSDESC))
15622    (clobber (reg:CC FLAGS_REG))]
15623   "TARGET_64BIT && TARGET_GNU2_TLS"
15624   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15625   [(set_attr "type" "call")
15626    (set_attr "length" "2")
15627    (set_attr "length_address" "0")])
15628
15629 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15630   [(set (match_operand:DI 0 "register_operand" "=&a")
15631         (plus:DI
15632          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15633                      (match_operand:DI 3 "" "")
15634                      (reg:DI SP_REG)]
15635                     UNSPEC_TLSDESC)
15636          (const:DI (unspec:DI
15637                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15638                     UNSPEC_DTPOFF))))
15639    (clobber (reg:CC FLAGS_REG))]
15640   "TARGET_64BIT && TARGET_GNU2_TLS"
15641   "#"
15642   ""
15643   [(set (match_dup 0) (match_dup 4))]
15644 {
15645   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15646   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15647 })
15648
15649 ;;
15650 \f
15651 ;; These patterns match the binary 387 instructions for addM3, subM3,
15652 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15653 ;; SFmode.  The first is the normal insn, the second the same insn but
15654 ;; with one operand a conversion, and the third the same insn but with
15655 ;; the other operand a conversion.  The conversion may be SFmode or
15656 ;; SImode if the target mode DFmode, but only SImode if the target mode
15657 ;; is SFmode.
15658
15659 ;; Gcc is slightly more smart about handling normal two address instructions
15660 ;; so use special patterns for add and mull.
15661
15662 (define_insn "*fop_sf_comm_mixed"
15663   [(set (match_operand:SF 0 "register_operand" "=f,x")
15664         (match_operator:SF 3 "binary_fp_operator"
15665                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15666                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15667   "TARGET_MIX_SSE_I387
15668    && COMMUTATIVE_ARITH_P (operands[3])
15669    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15670   "* return output_387_binary_op (insn, operands);"
15671   [(set (attr "type")
15672         (if_then_else (eq_attr "alternative" "1")
15673            (if_then_else (match_operand:SF 3 "mult_operator" "")
15674               (const_string "ssemul")
15675               (const_string "sseadd"))
15676            (if_then_else (match_operand:SF 3 "mult_operator" "")
15677               (const_string "fmul")
15678               (const_string "fop"))))
15679    (set_attr "mode" "SF")])
15680
15681 (define_insn "*fop_sf_comm_sse"
15682   [(set (match_operand:SF 0 "register_operand" "=x")
15683         (match_operator:SF 3 "binary_fp_operator"
15684                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15685                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15686   "TARGET_SSE_MATH
15687    && COMMUTATIVE_ARITH_P (operands[3])
15688    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15689   "* return output_387_binary_op (insn, operands);"
15690   [(set (attr "type")
15691         (if_then_else (match_operand:SF 3 "mult_operator" "")
15692            (const_string "ssemul")
15693            (const_string "sseadd")))
15694    (set_attr "mode" "SF")])
15695
15696 (define_insn "*fop_sf_comm_i387"
15697   [(set (match_operand:SF 0 "register_operand" "=f")
15698         (match_operator:SF 3 "binary_fp_operator"
15699                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15700                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15701   "TARGET_80387
15702    && COMMUTATIVE_ARITH_P (operands[3])
15703    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15704   "* return output_387_binary_op (insn, operands);"
15705   [(set (attr "type")
15706         (if_then_else (match_operand:SF 3 "mult_operator" "")
15707            (const_string "fmul")
15708            (const_string "fop")))
15709    (set_attr "mode" "SF")])
15710
15711 (define_insn "*fop_sf_1_mixed"
15712   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15713         (match_operator:SF 3 "binary_fp_operator"
15714                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15715                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15716   "TARGET_MIX_SSE_I387
15717    && !COMMUTATIVE_ARITH_P (operands[3])
15718    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15719   "* return output_387_binary_op (insn, operands);"
15720   [(set (attr "type")
15721         (cond [(and (eq_attr "alternative" "2")
15722                     (match_operand:SF 3 "mult_operator" ""))
15723                  (const_string "ssemul")
15724                (and (eq_attr "alternative" "2")
15725                     (match_operand:SF 3 "div_operator" ""))
15726                  (const_string "ssediv")
15727                (eq_attr "alternative" "2")
15728                  (const_string "sseadd")
15729                (match_operand:SF 3 "mult_operator" "")
15730                  (const_string "fmul")
15731                (match_operand:SF 3 "div_operator" "")
15732                  (const_string "fdiv")
15733               ]
15734               (const_string "fop")))
15735    (set_attr "mode" "SF")])
15736
15737 (define_insn "*fop_sf_1_sse"
15738   [(set (match_operand:SF 0 "register_operand" "=x")
15739         (match_operator:SF 3 "binary_fp_operator"
15740                         [(match_operand:SF 1 "register_operand" "0")
15741                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15742   "TARGET_SSE_MATH
15743    && !COMMUTATIVE_ARITH_P (operands[3])"
15744   "* return output_387_binary_op (insn, operands);"
15745   [(set (attr "type")
15746         (cond [(match_operand:SF 3 "mult_operator" "")
15747                  (const_string "ssemul")
15748                (match_operand:SF 3 "div_operator" "")
15749                  (const_string "ssediv")
15750               ]
15751               (const_string "sseadd")))
15752    (set_attr "mode" "SF")])
15753
15754 ;; This pattern is not fully shadowed by the pattern above.
15755 (define_insn "*fop_sf_1_i387"
15756   [(set (match_operand:SF 0 "register_operand" "=f,f")
15757         (match_operator:SF 3 "binary_fp_operator"
15758                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15759                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15760   "TARGET_80387 && !TARGET_SSE_MATH
15761    && !COMMUTATIVE_ARITH_P (operands[3])
15762    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15763   "* return output_387_binary_op (insn, operands);"
15764   [(set (attr "type")
15765         (cond [(match_operand:SF 3 "mult_operator" "")
15766                  (const_string "fmul")
15767                (match_operand:SF 3 "div_operator" "")
15768                  (const_string "fdiv")
15769               ]
15770               (const_string "fop")))
15771    (set_attr "mode" "SF")])
15772
15773 ;; ??? Add SSE splitters for these!
15774 (define_insn "*fop_sf_2<mode>_i387"
15775   [(set (match_operand:SF 0 "register_operand" "=f,f")
15776         (match_operator:SF 3 "binary_fp_operator"
15777           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15778            (match_operand:SF 2 "register_operand" "0,0")]))]
15779   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15780   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15781   [(set (attr "type")
15782         (cond [(match_operand:SF 3 "mult_operator" "")
15783                  (const_string "fmul")
15784                (match_operand:SF 3 "div_operator" "")
15785                  (const_string "fdiv")
15786               ]
15787               (const_string "fop")))
15788    (set_attr "fp_int_src" "true")
15789    (set_attr "mode" "<MODE>")])
15790
15791 (define_insn "*fop_sf_3<mode>_i387"
15792   [(set (match_operand:SF 0 "register_operand" "=f,f")
15793         (match_operator:SF 3 "binary_fp_operator"
15794           [(match_operand:SF 1 "register_operand" "0,0")
15795            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15796   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15797   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15798   [(set (attr "type")
15799         (cond [(match_operand:SF 3 "mult_operator" "")
15800                  (const_string "fmul")
15801                (match_operand:SF 3 "div_operator" "")
15802                  (const_string "fdiv")
15803               ]
15804               (const_string "fop")))
15805    (set_attr "fp_int_src" "true")
15806    (set_attr "mode" "<MODE>")])
15807
15808 (define_insn "*fop_df_comm_mixed"
15809   [(set (match_operand:DF 0 "register_operand" "=f,x")
15810         (match_operator:DF 3 "binary_fp_operator"
15811           [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15812            (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15813   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15814    && COMMUTATIVE_ARITH_P (operands[3])
15815    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15816   "* return output_387_binary_op (insn, operands);"
15817   [(set (attr "type")
15818         (if_then_else (eq_attr "alternative" "1")
15819            (if_then_else (match_operand:DF 3 "mult_operator" "")
15820               (const_string "ssemul")
15821               (const_string "sseadd"))
15822            (if_then_else (match_operand:DF 3 "mult_operator" "")
15823               (const_string "fmul")
15824               (const_string "fop"))))
15825    (set_attr "mode" "DF")])
15826
15827 (define_insn "*fop_df_comm_sse"
15828   [(set (match_operand:DF 0 "register_operand" "=x")
15829         (match_operator:DF 3 "binary_fp_operator"
15830           [(match_operand:DF 1 "nonimmediate_operand" "%0")
15831            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15832   "TARGET_SSE2 && TARGET_SSE_MATH
15833    && COMMUTATIVE_ARITH_P (operands[3])
15834    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15835   "* return output_387_binary_op (insn, operands);"
15836   [(set (attr "type")
15837         (if_then_else (match_operand:DF 3 "mult_operator" "")
15838            (const_string "ssemul")
15839            (const_string "sseadd")))
15840    (set_attr "mode" "DF")])
15841
15842 (define_insn "*fop_df_comm_i387"
15843   [(set (match_operand:DF 0 "register_operand" "=f")
15844         (match_operator:DF 3 "binary_fp_operator"
15845                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15846                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15847   "TARGET_80387
15848    && COMMUTATIVE_ARITH_P (operands[3])
15849    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15850   "* return output_387_binary_op (insn, operands);"
15851   [(set (attr "type")
15852         (if_then_else (match_operand:DF 3 "mult_operator" "")
15853            (const_string "fmul")
15854            (const_string "fop")))
15855    (set_attr "mode" "DF")])
15856
15857 (define_insn "*fop_df_1_mixed"
15858   [(set (match_operand:DF 0 "register_operand" "=f,f,x")
15859         (match_operator:DF 3 "binary_fp_operator"
15860           [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15861            (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
15862   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15863    && !COMMUTATIVE_ARITH_P (operands[3])
15864    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15865   "* return output_387_binary_op (insn, operands);"
15866   [(set (attr "type")
15867         (cond [(and (eq_attr "alternative" "2")
15868                     (match_operand:DF 3 "mult_operator" ""))
15869                  (const_string "ssemul")
15870                (and (eq_attr "alternative" "2")
15871                     (match_operand:DF 3 "div_operator" ""))
15872                  (const_string "ssediv")
15873                (eq_attr "alternative" "2")
15874                  (const_string "sseadd")
15875                (match_operand:DF 3 "mult_operator" "")
15876                  (const_string "fmul")
15877                (match_operand:DF 3 "div_operator" "")
15878                  (const_string "fdiv")
15879               ]
15880               (const_string "fop")))
15881    (set_attr "mode" "DF")])
15882
15883 (define_insn "*fop_df_1_sse"
15884   [(set (match_operand:DF 0 "register_operand" "=x")
15885         (match_operator:DF 3 "binary_fp_operator"
15886           [(match_operand:DF 1 "register_operand" "0")
15887            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15888   "TARGET_SSE2 && TARGET_SSE_MATH
15889    && !COMMUTATIVE_ARITH_P (operands[3])"
15890   "* return output_387_binary_op (insn, operands);"
15891   [(set_attr "mode" "DF")
15892    (set (attr "type")
15893         (cond [(match_operand:DF 3 "mult_operator" "")
15894                  (const_string "ssemul")
15895                (match_operand:DF 3 "div_operator" "")
15896                  (const_string "ssediv")
15897               ]
15898               (const_string "sseadd")))])
15899
15900 ;; This pattern is not fully shadowed by the pattern above.
15901 (define_insn "*fop_df_1_i387"
15902   [(set (match_operand:DF 0 "register_operand" "=f,f")
15903         (match_operator:DF 3 "binary_fp_operator"
15904                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15905                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15906   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15907    && !COMMUTATIVE_ARITH_P (operands[3])
15908    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15909   "* return output_387_binary_op (insn, operands);"
15910   [(set (attr "type")
15911         (cond [(match_operand:DF 3 "mult_operator" "")
15912                  (const_string "fmul")
15913                (match_operand:DF 3 "div_operator" "")
15914                  (const_string "fdiv")
15915               ]
15916               (const_string "fop")))
15917    (set_attr "mode" "DF")])
15918
15919 ;; ??? Add SSE splitters for these!
15920 (define_insn "*fop_df_2<mode>_i387"
15921   [(set (match_operand:DF 0 "register_operand" "=f,f")
15922         (match_operator:DF 3 "binary_fp_operator"
15923            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15924             (match_operand:DF 2 "register_operand" "0,0")]))]
15925   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15926    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15927   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15928   [(set (attr "type")
15929         (cond [(match_operand:DF 3 "mult_operator" "")
15930                  (const_string "fmul")
15931                (match_operand:DF 3 "div_operator" "")
15932                  (const_string "fdiv")
15933               ]
15934               (const_string "fop")))
15935    (set_attr "fp_int_src" "true")
15936    (set_attr "mode" "<MODE>")])
15937
15938 (define_insn "*fop_df_3<mode>_i387"
15939   [(set (match_operand:DF 0 "register_operand" "=f,f")
15940         (match_operator:DF 3 "binary_fp_operator"
15941            [(match_operand:DF 1 "register_operand" "0,0")
15942             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15943   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15944    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15945   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15946   [(set (attr "type")
15947         (cond [(match_operand:DF 3 "mult_operator" "")
15948                  (const_string "fmul")
15949                (match_operand:DF 3 "div_operator" "")
15950                  (const_string "fdiv")
15951               ]
15952               (const_string "fop")))
15953    (set_attr "fp_int_src" "true")
15954    (set_attr "mode" "<MODE>")])
15955
15956 (define_insn "*fop_df_4_i387"
15957   [(set (match_operand:DF 0 "register_operand" "=f,f")
15958         (match_operator:DF 3 "binary_fp_operator"
15959            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15960             (match_operand:DF 2 "register_operand" "0,f")]))]
15961   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15962    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15963   "* return output_387_binary_op (insn, operands);"
15964   [(set (attr "type")
15965         (cond [(match_operand:DF 3 "mult_operator" "")
15966                  (const_string "fmul")
15967                (match_operand:DF 3 "div_operator" "")
15968                  (const_string "fdiv")
15969               ]
15970               (const_string "fop")))
15971    (set_attr "mode" "SF")])
15972
15973 (define_insn "*fop_df_5_i387"
15974   [(set (match_operand:DF 0 "register_operand" "=f,f")
15975         (match_operator:DF 3 "binary_fp_operator"
15976           [(match_operand:DF 1 "register_operand" "0,f")
15977            (float_extend:DF
15978             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15979   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15980   "* return output_387_binary_op (insn, operands);"
15981   [(set (attr "type")
15982         (cond [(match_operand:DF 3 "mult_operator" "")
15983                  (const_string "fmul")
15984                (match_operand:DF 3 "div_operator" "")
15985                  (const_string "fdiv")
15986               ]
15987               (const_string "fop")))
15988    (set_attr "mode" "SF")])
15989
15990 (define_insn "*fop_df_6_i387"
15991   [(set (match_operand:DF 0 "register_operand" "=f,f")
15992         (match_operator:DF 3 "binary_fp_operator"
15993           [(float_extend:DF
15994             (match_operand:SF 1 "register_operand" "0,f"))
15995            (float_extend:DF
15996             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15997   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15998   "* return output_387_binary_op (insn, operands);"
15999   [(set (attr "type")
16000         (cond [(match_operand:DF 3 "mult_operator" "")
16001                  (const_string "fmul")
16002                (match_operand:DF 3 "div_operator" "")
16003                  (const_string "fdiv")
16004               ]
16005               (const_string "fop")))
16006    (set_attr "mode" "SF")])
16007
16008 (define_insn "*fop_xf_comm_i387"
16009   [(set (match_operand:XF 0 "register_operand" "=f")
16010         (match_operator:XF 3 "binary_fp_operator"
16011                         [(match_operand:XF 1 "register_operand" "%0")
16012                          (match_operand:XF 2 "register_operand" "f")]))]
16013   "TARGET_80387
16014    && COMMUTATIVE_ARITH_P (operands[3])"
16015   "* return output_387_binary_op (insn, operands);"
16016   [(set (attr "type")
16017         (if_then_else (match_operand:XF 3 "mult_operator" "")
16018            (const_string "fmul")
16019            (const_string "fop")))
16020    (set_attr "mode" "XF")])
16021
16022 (define_insn "*fop_xf_1_i387"
16023   [(set (match_operand:XF 0 "register_operand" "=f,f")
16024         (match_operator:XF 3 "binary_fp_operator"
16025                         [(match_operand:XF 1 "register_operand" "0,f")
16026                          (match_operand:XF 2 "register_operand" "f,0")]))]
16027   "TARGET_80387
16028    && !COMMUTATIVE_ARITH_P (operands[3])"
16029   "* return output_387_binary_op (insn, operands);"
16030   [(set (attr "type")
16031         (cond [(match_operand:XF 3 "mult_operator" "")
16032                  (const_string "fmul")
16033                (match_operand:XF 3 "div_operator" "")
16034                  (const_string "fdiv")
16035               ]
16036               (const_string "fop")))
16037    (set_attr "mode" "XF")])
16038
16039 (define_insn "*fop_xf_2<mode>_i387"
16040   [(set (match_operand:XF 0 "register_operand" "=f,f")
16041         (match_operator:XF 3 "binary_fp_operator"
16042            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16043             (match_operand:XF 2 "register_operand" "0,0")]))]
16044   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16045   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16046   [(set (attr "type")
16047         (cond [(match_operand:XF 3 "mult_operator" "")
16048                  (const_string "fmul")
16049                (match_operand:XF 3 "div_operator" "")
16050                  (const_string "fdiv")
16051               ]
16052               (const_string "fop")))
16053    (set_attr "fp_int_src" "true")
16054    (set_attr "mode" "<MODE>")])
16055
16056 (define_insn "*fop_xf_3<mode>_i387"
16057   [(set (match_operand:XF 0 "register_operand" "=f,f")
16058         (match_operator:XF 3 "binary_fp_operator"
16059           [(match_operand:XF 1 "register_operand" "0,0")
16060            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16061   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16062   "* return which_alternative ? \"#\" : 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 "fp_int_src" "true")
16071    (set_attr "mode" "<MODE>")])
16072
16073 (define_insn "*fop_xf_4_i387"
16074   [(set (match_operand:XF 0 "register_operand" "=f,f")
16075         (match_operator:XF 3 "binary_fp_operator"
16076            [(float_extend:XF
16077               (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
16078             (match_operand:XF 2 "register_operand" "0,f")]))]
16079   "TARGET_80387"
16080   "* return output_387_binary_op (insn, operands);"
16081   [(set (attr "type")
16082         (cond [(match_operand:XF 3 "mult_operator" "")
16083                  (const_string "fmul")
16084                (match_operand:XF 3 "div_operator" "")
16085                  (const_string "fdiv")
16086               ]
16087               (const_string "fop")))
16088    (set_attr "mode" "SF")])
16089
16090 (define_insn "*fop_xf_5_i387"
16091   [(set (match_operand:XF 0 "register_operand" "=f,f")
16092         (match_operator:XF 3 "binary_fp_operator"
16093           [(match_operand:XF 1 "register_operand" "0,f")
16094            (float_extend:XF
16095              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
16096   "TARGET_80387"
16097   "* return output_387_binary_op (insn, operands);"
16098   [(set (attr "type")
16099         (cond [(match_operand:XF 3 "mult_operator" "")
16100                  (const_string "fmul")
16101                (match_operand:XF 3 "div_operator" "")
16102                  (const_string "fdiv")
16103               ]
16104               (const_string "fop")))
16105    (set_attr "mode" "SF")])
16106
16107 (define_insn "*fop_xf_6_i387"
16108   [(set (match_operand:XF 0 "register_operand" "=f,f")
16109         (match_operator:XF 3 "binary_fp_operator"
16110           [(float_extend:XF
16111              (match_operand:X87MODEF12 1 "register_operand" "0,f"))
16112            (float_extend:XF
16113              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
16114   "TARGET_80387"
16115   "* return output_387_binary_op (insn, operands);"
16116   [(set (attr "type")
16117         (cond [(match_operand:XF 3 "mult_operator" "")
16118                  (const_string "fmul")
16119                (match_operand:XF 3 "div_operator" "")
16120                  (const_string "fdiv")
16121               ]
16122               (const_string "fop")))
16123    (set_attr "mode" "SF")])
16124
16125 (define_split
16126   [(set (match_operand 0 "register_operand" "")
16127         (match_operator 3 "binary_fp_operator"
16128            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16129             (match_operand 2 "register_operand" "")]))]
16130   "TARGET_80387 && reload_completed
16131    && FLOAT_MODE_P (GET_MODE (operands[0]))"
16132   [(const_int 0)]
16133 {
16134   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16135   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16136   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16137                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16138                                           GET_MODE (operands[3]),
16139                                           operands[4],
16140                                           operands[2])));
16141   ix86_free_from_memory (GET_MODE (operands[1]));
16142   DONE;
16143 })
16144
16145 (define_split
16146   [(set (match_operand 0 "register_operand" "")
16147         (match_operator 3 "binary_fp_operator"
16148            [(match_operand 1 "register_operand" "")
16149             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16150   "TARGET_80387 && reload_completed
16151    && FLOAT_MODE_P (GET_MODE (operands[0]))"
16152   [(const_int 0)]
16153 {
16154   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16155   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16156   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16157                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16158                                           GET_MODE (operands[3]),
16159                                           operands[1],
16160                                           operands[4])));
16161   ix86_free_from_memory (GET_MODE (operands[2]));
16162   DONE;
16163 })
16164 \f
16165 ;; FPU special functions.
16166
16167 ;; This pattern implements a no-op XFmode truncation for
16168 ;; all fancy i386 XFmode math functions.
16169
16170 (define_insn "truncxf<mode>2_i387_noop_unspec"
16171   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16172         (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
16173         UNSPEC_TRUNC_NOOP))]
16174   "TARGET_USE_FANCY_MATH_387"
16175   "* return output_387_reg_move (insn, operands);"
16176   [(set_attr "type" "fmov")
16177    (set_attr "mode" "<MODE>")])
16178
16179 (define_insn "sqrtxf2"
16180   [(set (match_operand:XF 0 "register_operand" "=f")
16181         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16182   "TARGET_USE_FANCY_MATH_387"
16183   "fsqrt"
16184   [(set_attr "type" "fpspc")
16185    (set_attr "mode" "XF")
16186    (set_attr "athlon_decode" "direct")
16187    (set_attr "amdfam10_decode" "direct")])
16188
16189 (define_insn "sqrt_extend<mode>xf2_i387"
16190   [(set (match_operand:XF 0 "register_operand" "=f")
16191         (sqrt:XF
16192           (float_extend:XF
16193             (match_operand:X87MODEF12 1 "register_operand" "0"))))]
16194   "TARGET_USE_FANCY_MATH_387"
16195   "fsqrt"
16196   [(set_attr "type" "fpspc")
16197    (set_attr "mode" "XF")
16198    (set_attr "athlon_decode" "direct")   
16199    (set_attr "amdfam10_decode" "direct")])
16200
16201 (define_insn "*sqrt<mode>2_sse"
16202   [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
16203         (sqrt:SSEMODEF
16204           (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
16205   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16206   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16207   [(set_attr "type" "sse")
16208    (set_attr "mode" "<MODE>")
16209    (set_attr "athlon_decode" "*")
16210    (set_attr "amdfam10_decode" "*")])
16211
16212 (define_expand "sqrt<mode>2"
16213   [(set (match_operand:X87MODEF12 0 "register_operand" "")
16214         (sqrt:X87MODEF12
16215           (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
16216   "TARGET_USE_FANCY_MATH_387
16217    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16218 {
16219   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16220     {
16221       rtx op0 = gen_reg_rtx (XFmode);
16222       rtx op1 = force_reg (<MODE>mode, operands[1]);
16223
16224       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16225       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16226       DONE;
16227    }
16228 })
16229
16230 (define_insn "fpremxf4_i387"
16231   [(set (match_operand:XF 0 "register_operand" "=f")
16232         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16233                     (match_operand:XF 3 "register_operand" "1")]
16234                    UNSPEC_FPREM_F))
16235    (set (match_operand:XF 1 "register_operand" "=u")
16236         (unspec:XF [(match_dup 2) (match_dup 3)]
16237                    UNSPEC_FPREM_U))
16238    (set (reg:CCFP FPSR_REG)
16239         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
16240   "TARGET_USE_FANCY_MATH_387"
16241   "fprem"
16242   [(set_attr "type" "fpspc")
16243    (set_attr "mode" "XF")])
16244
16245 (define_expand "fmodxf3"
16246   [(use (match_operand:XF 0 "register_operand" ""))
16247    (use (match_operand:XF 1 "register_operand" ""))
16248    (use (match_operand:XF 2 "register_operand" ""))]
16249   "TARGET_USE_FANCY_MATH_387"
16250 {
16251   rtx label = gen_label_rtx ();
16252
16253   emit_label (label);
16254
16255   emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
16256                                 operands[1], operands[2]));
16257   ix86_emit_fp_unordered_jump (label);
16258
16259   emit_move_insn (operands[0], operands[1]);
16260   DONE;
16261 })
16262
16263 (define_expand "fmod<mode>3"
16264   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16265    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16266    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16267   "TARGET_USE_FANCY_MATH_387"
16268 {
16269   rtx label = gen_label_rtx ();
16270
16271   rtx op1 = gen_reg_rtx (XFmode);
16272   rtx op2 = gen_reg_rtx (XFmode);
16273
16274   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16275   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16276
16277   emit_label (label);
16278   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16279   ix86_emit_fp_unordered_jump (label);
16280
16281   /* Truncate the result properly for strict SSE math.  */
16282   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16283       && !TARGET_MIX_SSE_I387)
16284     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16285   else
16286     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16287
16288   DONE;
16289 })
16290
16291 (define_insn "fprem1xf4_i387"
16292   [(set (match_operand:XF 0 "register_operand" "=f")
16293         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16294                     (match_operand:XF 3 "register_operand" "1")]
16295                    UNSPEC_FPREM1_F))
16296    (set (match_operand:XF 1 "register_operand" "=u")
16297         (unspec:XF [(match_dup 2) (match_dup 3)]
16298                    UNSPEC_FPREM1_U))
16299    (set (reg:CCFP FPSR_REG)
16300         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
16301   "TARGET_USE_FANCY_MATH_387"
16302   "fprem1"
16303   [(set_attr "type" "fpspc")
16304    (set_attr "mode" "XF")])
16305
16306 (define_expand "remainderxf3"
16307   [(use (match_operand:XF 0 "register_operand" ""))
16308    (use (match_operand:XF 1 "register_operand" ""))
16309    (use (match_operand:XF 2 "register_operand" ""))]
16310   "TARGET_USE_FANCY_MATH_387"
16311 {
16312   rtx label = gen_label_rtx ();
16313
16314   emit_label (label);
16315
16316   emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
16317                                  operands[1], operands[2]));
16318   ix86_emit_fp_unordered_jump (label);
16319
16320   emit_move_insn (operands[0], operands[1]);
16321   DONE;
16322 })
16323
16324 (define_expand "remainder<mode>3"
16325   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16326    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16327    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16328   "TARGET_USE_FANCY_MATH_387"
16329 {
16330   rtx label = gen_label_rtx ();
16331
16332   rtx op1 = gen_reg_rtx (XFmode);
16333   rtx op2 = gen_reg_rtx (XFmode);
16334
16335   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16336   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16337
16338   emit_label (label);
16339
16340   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16341   ix86_emit_fp_unordered_jump (label);
16342
16343   /* Truncate the result properly for strict SSE math.  */
16344   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16345       && !TARGET_MIX_SSE_I387)
16346     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16347   else
16348     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16349
16350   DONE;
16351 })
16352
16353 (define_insn "*sinxf2_i387"
16354   [(set (match_operand:XF 0 "register_operand" "=f")
16355         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16356   "TARGET_USE_FANCY_MATH_387
16357    && flag_unsafe_math_optimizations"
16358   "fsin"
16359   [(set_attr "type" "fpspc")
16360    (set_attr "mode" "XF")])
16361
16362 (define_insn "*sin_extend<mode>xf2_i387"
16363   [(set (match_operand:XF 0 "register_operand" "=f")
16364         (unspec:XF [(float_extend:XF
16365                       (match_operand:X87MODEF12 1 "register_operand" "0"))]
16366                    UNSPEC_SIN))]
16367   "TARGET_USE_FANCY_MATH_387
16368    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16369        || TARGET_MIX_SSE_I387)
16370    && flag_unsafe_math_optimizations"
16371   "fsin"
16372   [(set_attr "type" "fpspc")
16373    (set_attr "mode" "XF")])
16374
16375 (define_insn "*cosxf2_i387"
16376   [(set (match_operand:XF 0 "register_operand" "=f")
16377         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16378   "TARGET_USE_FANCY_MATH_387
16379    && flag_unsafe_math_optimizations"
16380   "fcos"
16381   [(set_attr "type" "fpspc")
16382    (set_attr "mode" "XF")])
16383
16384 (define_insn "*cos_extend<mode>xf2_i387"
16385   [(set (match_operand:XF 0 "register_operand" "=f")
16386         (unspec:XF [(float_extend:XF
16387                       (match_operand:X87MODEF12 1 "register_operand" "0"))]
16388                    UNSPEC_COS))]
16389   "TARGET_USE_FANCY_MATH_387
16390    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16391        || TARGET_MIX_SSE_I387)
16392    && flag_unsafe_math_optimizations"
16393   "fcos"
16394   [(set_attr "type" "fpspc")
16395    (set_attr "mode" "XF")])
16396
16397 ;; When sincos pattern is defined, sin and cos builtin functions will be
16398 ;; expanded to sincos pattern with one of its outputs left unused.
16399 ;; CSE pass will figure out if two sincos patterns can be combined,
16400 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16401 ;; depending on the unused output.
16402
16403 (define_insn "sincosxf3"
16404   [(set (match_operand:XF 0 "register_operand" "=f")
16405         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16406                    UNSPEC_SINCOS_COS))
16407    (set (match_operand:XF 1 "register_operand" "=u")
16408         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16409   "TARGET_USE_FANCY_MATH_387
16410    && flag_unsafe_math_optimizations"
16411   "fsincos"
16412   [(set_attr "type" "fpspc")
16413    (set_attr "mode" "XF")])
16414
16415 (define_split
16416   [(set (match_operand:XF 0 "register_operand" "")
16417         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16418                    UNSPEC_SINCOS_COS))
16419    (set (match_operand:XF 1 "register_operand" "")
16420         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16421   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16422    && !reload_completed && !reload_in_progress"
16423   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16424   "")
16425
16426 (define_split
16427   [(set (match_operand:XF 0 "register_operand" "")
16428         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16429                    UNSPEC_SINCOS_COS))
16430    (set (match_operand:XF 1 "register_operand" "")
16431         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16432   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16433    && !reload_completed && !reload_in_progress"
16434   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16435   "")
16436
16437 (define_insn "sincos_extend<mode>xf3_i387"
16438   [(set (match_operand:XF 0 "register_operand" "=f")
16439         (unspec:XF [(float_extend:XF
16440                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16441                    UNSPEC_SINCOS_COS))
16442    (set (match_operand:XF 1 "register_operand" "=u")
16443         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16444   "TARGET_USE_FANCY_MATH_387
16445    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16446        || TARGET_MIX_SSE_I387)
16447    && flag_unsafe_math_optimizations"
16448   "fsincos"
16449   [(set_attr "type" "fpspc")
16450    (set_attr "mode" "XF")])
16451
16452 (define_split
16453   [(set (match_operand:XF 0 "register_operand" "")
16454         (unspec:XF [(float_extend:XF
16455                       (match_operand:X87MODEF12 2 "register_operand" ""))]
16456                    UNSPEC_SINCOS_COS))
16457    (set (match_operand:XF 1 "register_operand" "")
16458         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16459   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16460    && !reload_completed && !reload_in_progress"
16461   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16462   "")
16463
16464 (define_split
16465   [(set (match_operand:XF 0 "register_operand" "")
16466         (unspec:XF [(float_extend:XF
16467                       (match_operand:X87MODEF12 2 "register_operand" ""))]
16468                    UNSPEC_SINCOS_COS))
16469    (set (match_operand:XF 1 "register_operand" "")
16470         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16471   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16472    && !reload_completed && !reload_in_progress"
16473   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16474   "")
16475
16476 (define_expand "sincos<mode>3"
16477   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16478    (use (match_operand:X87MODEF12 1 "register_operand" ""))
16479    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16480   "TARGET_USE_FANCY_MATH_387
16481    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16482        || TARGET_MIX_SSE_I387)
16483    && flag_unsafe_math_optimizations"
16484 {
16485   rtx op0 = gen_reg_rtx (XFmode);
16486   rtx op1 = gen_reg_rtx (XFmode);
16487
16488   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16489   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16490   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16491   DONE;
16492 })
16493
16494 (define_insn "fptanxf4_i387"
16495   [(set (match_operand:XF 0 "register_operand" "=f")
16496         (match_operand:XF 3 "const_double_operand" "F"))
16497    (set (match_operand:XF 1 "register_operand" "=u")
16498         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16499                    UNSPEC_TAN))]
16500   "TARGET_USE_FANCY_MATH_387
16501    && flag_unsafe_math_optimizations
16502    && standard_80387_constant_p (operands[3]) == 2"
16503   "fptan"
16504   [(set_attr "type" "fpspc")
16505    (set_attr "mode" "XF")])
16506
16507 (define_insn "fptan_extend<mode>xf4_i387"
16508   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16509         (match_operand:X87MODEF12 3 "const_double_operand" "F"))
16510    (set (match_operand:XF 1 "register_operand" "=u")
16511         (unspec:XF [(float_extend:XF
16512                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16513                    UNSPEC_TAN))]
16514   "TARGET_USE_FANCY_MATH_387
16515    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16516        || TARGET_MIX_SSE_I387)
16517    && flag_unsafe_math_optimizations
16518    && standard_80387_constant_p (operands[3]) == 2"
16519   "fptan"
16520   [(set_attr "type" "fpspc")
16521    (set_attr "mode" "XF")])
16522
16523 (define_expand "tanxf2"
16524   [(use (match_operand:XF 0 "register_operand" ""))
16525    (use (match_operand:XF 1 "register_operand" ""))]
16526   "TARGET_USE_FANCY_MATH_387
16527    && flag_unsafe_math_optimizations"
16528 {
16529   rtx one = gen_reg_rtx (XFmode);
16530   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16531
16532   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16533   DONE;
16534 })
16535
16536 (define_expand "tan<mode>2"
16537   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16538    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16539   "TARGET_USE_FANCY_MATH_387
16540    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16541        || TARGET_MIX_SSE_I387)
16542    && flag_unsafe_math_optimizations"
16543 {
16544   rtx op0 = gen_reg_rtx (XFmode);
16545
16546   rtx one = gen_reg_rtx (<MODE>mode);
16547   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16548
16549   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16550                                              operands[1], op2));
16551   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16552   DONE;
16553 })
16554
16555 (define_insn "*fpatanxf3_i387"
16556   [(set (match_operand:XF 0 "register_operand" "=f")
16557         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16558                     (match_operand:XF 2 "register_operand" "u")]
16559                    UNSPEC_FPATAN))
16560    (clobber (match_scratch:XF 3 "=2"))]
16561   "TARGET_USE_FANCY_MATH_387
16562    && flag_unsafe_math_optimizations"
16563   "fpatan"
16564   [(set_attr "type" "fpspc")
16565    (set_attr "mode" "XF")])
16566
16567 (define_insn "fpatan_extend<mode>xf3_i387"
16568   [(set (match_operand:XF 0 "register_operand" "=f")
16569         (unspec:XF [(float_extend:XF
16570                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16571                     (float_extend:XF
16572                       (match_operand:X87MODEF12 2 "register_operand" "u"))]
16573                    UNSPEC_FPATAN))
16574    (clobber (match_scratch:XF 3 "=2"))]
16575   "TARGET_USE_FANCY_MATH_387
16576    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16577        || TARGET_MIX_SSE_I387)
16578    && flag_unsafe_math_optimizations"
16579   "fpatan"
16580   [(set_attr "type" "fpspc")
16581    (set_attr "mode" "XF")])
16582
16583 (define_expand "atan2xf3"
16584   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16585                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
16586                                (match_operand:XF 1 "register_operand" "")]
16587                               UNSPEC_FPATAN))
16588               (clobber (match_scratch:XF 3 ""))])]
16589   "TARGET_USE_FANCY_MATH_387
16590    && flag_unsafe_math_optimizations"
16591   "")
16592
16593 (define_expand "atan2<mode>3"
16594   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16595    (use (match_operand:X87MODEF12 1 "register_operand" ""))
16596    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16597   "TARGET_USE_FANCY_MATH_387
16598    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16599        || TARGET_MIX_SSE_I387)
16600    && flag_unsafe_math_optimizations"
16601 {
16602   rtx op0 = gen_reg_rtx (XFmode);
16603
16604   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16605   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16606   DONE;
16607 })
16608
16609 (define_expand "atanxf2"
16610   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16611                    (unspec:XF [(match_dup 2)
16612                                (match_operand:XF 1 "register_operand" "")]
16613                               UNSPEC_FPATAN))
16614               (clobber (match_scratch:XF 3 ""))])]
16615   "TARGET_USE_FANCY_MATH_387
16616    && flag_unsafe_math_optimizations"
16617 {
16618   operands[2] = gen_reg_rtx (XFmode);
16619   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16620 })
16621
16622 (define_expand "atan<mode>2"
16623   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16624    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16625   "TARGET_USE_FANCY_MATH_387
16626    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16627        || TARGET_MIX_SSE_I387)
16628    && flag_unsafe_math_optimizations"
16629 {
16630   rtx op0 = gen_reg_rtx (XFmode);
16631
16632   rtx op2 = gen_reg_rtx (<MODE>mode);
16633   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
16634
16635   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16636   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16637   DONE;
16638 })
16639
16640 (define_expand "asinxf2"
16641   [(set (match_dup 2)
16642         (mult:XF (match_operand:XF 1 "register_operand" "")
16643                  (match_dup 1)))
16644    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16645    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16646    (parallel [(set (match_operand:XF 0 "register_operand" "")
16647                    (unspec:XF [(match_dup 5) (match_dup 1)]
16648                               UNSPEC_FPATAN))
16649               (clobber (match_scratch:XF 6 ""))])]
16650   "TARGET_USE_FANCY_MATH_387
16651    && flag_unsafe_math_optimizations && !optimize_size"
16652 {
16653   int i;
16654
16655   for (i = 2; i < 6; i++)
16656     operands[i] = gen_reg_rtx (XFmode);
16657
16658   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16659 })
16660
16661 (define_expand "asin<mode>2"
16662   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16663    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16664  "TARGET_USE_FANCY_MATH_387
16665    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16666        || TARGET_MIX_SSE_I387)
16667    && flag_unsafe_math_optimizations && !optimize_size"
16668 {
16669   rtx op0 = gen_reg_rtx (XFmode);
16670   rtx op1 = gen_reg_rtx (XFmode);
16671
16672   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16673   emit_insn (gen_asinxf2 (op0, op1));
16674   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16675   DONE;
16676 })
16677
16678 (define_expand "acosxf2"
16679   [(set (match_dup 2)
16680         (mult:XF (match_operand:XF 1 "register_operand" "")
16681                  (match_dup 1)))
16682    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16683    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16684    (parallel [(set (match_operand:XF 0 "register_operand" "")
16685                    (unspec:XF [(match_dup 1) (match_dup 5)]
16686                               UNSPEC_FPATAN))
16687               (clobber (match_scratch:XF 6 ""))])]
16688   "TARGET_USE_FANCY_MATH_387
16689    && flag_unsafe_math_optimizations && !optimize_size"
16690 {
16691   int i;
16692
16693   for (i = 2; i < 6; i++)
16694     operands[i] = gen_reg_rtx (XFmode);
16695
16696   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16697 })
16698
16699 (define_expand "acos<mode>2"
16700   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16701    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16702  "TARGET_USE_FANCY_MATH_387
16703    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16704        || TARGET_MIX_SSE_I387)
16705    && flag_unsafe_math_optimizations && !optimize_size"
16706 {
16707   rtx op0 = gen_reg_rtx (XFmode);
16708   rtx op1 = gen_reg_rtx (XFmode);
16709
16710   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16711   emit_insn (gen_acosxf2 (op0, op1));
16712   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16713   DONE;
16714 })
16715
16716 (define_insn "fyl2xxf3_i387"
16717   [(set (match_operand:XF 0 "register_operand" "=f")
16718         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16719                     (match_operand:XF 2 "register_operand" "u")]
16720                    UNSPEC_FYL2X))
16721    (clobber (match_scratch:XF 3 "=2"))]
16722   "TARGET_USE_FANCY_MATH_387
16723    && flag_unsafe_math_optimizations"
16724   "fyl2x"
16725   [(set_attr "type" "fpspc")
16726    (set_attr "mode" "XF")])
16727
16728 (define_insn "fyl2x_extend<mode>xf3_i387"
16729   [(set (match_operand:XF 0 "register_operand" "=f")
16730         (unspec:XF [(float_extend:XF
16731                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16732                     (match_operand:XF 2 "register_operand" "u")]
16733                    UNSPEC_FYL2X))
16734    (clobber (match_scratch:XF 3 "=2"))]
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"
16739   "fyl2x"
16740   [(set_attr "type" "fpspc")
16741    (set_attr "mode" "XF")])
16742
16743 (define_expand "logxf2"
16744   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16745                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16746                                (match_dup 2)] UNSPEC_FYL2X))
16747               (clobber (match_scratch:XF 3 ""))])]
16748   "TARGET_USE_FANCY_MATH_387
16749    && flag_unsafe_math_optimizations"
16750 {
16751   operands[2] = gen_reg_rtx (XFmode);
16752   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16753 })
16754
16755 (define_expand "log<mode>2"
16756   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16757    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16758   "TARGET_USE_FANCY_MATH_387
16759    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16760        || TARGET_MIX_SSE_I387)
16761    && flag_unsafe_math_optimizations"
16762 {
16763   rtx op0 = gen_reg_rtx (XFmode);
16764
16765   rtx op2 = gen_reg_rtx (XFmode);
16766   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16767
16768   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16769   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16770   DONE;
16771 })
16772
16773 (define_expand "log10xf2"
16774   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16775                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16776                                (match_dup 2)] UNSPEC_FYL2X))
16777               (clobber (match_scratch:XF 3 ""))])]
16778   "TARGET_USE_FANCY_MATH_387
16779    && flag_unsafe_math_optimizations"
16780 {
16781   operands[2] = gen_reg_rtx (XFmode);
16782   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16783 })
16784
16785 (define_expand "log10<mode>2"
16786   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16787    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16788   "TARGET_USE_FANCY_MATH_387
16789    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16790        || TARGET_MIX_SSE_I387)
16791    && flag_unsafe_math_optimizations"
16792 {
16793   rtx op0 = gen_reg_rtx (XFmode);
16794
16795   rtx op2 = gen_reg_rtx (XFmode);
16796   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16797
16798   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16799   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16800   DONE;
16801 })
16802
16803 (define_expand "log2xf2"
16804   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16805                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16806                                (match_dup 2)] UNSPEC_FYL2X))
16807               (clobber (match_scratch:XF 3 ""))])]
16808   "TARGET_USE_FANCY_MATH_387
16809    && flag_unsafe_math_optimizations"
16810 {
16811   operands[2] = gen_reg_rtx (XFmode);
16812   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16813 })
16814
16815 (define_expand "log2<mode>2"
16816   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16817    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16818   "TARGET_USE_FANCY_MATH_387
16819    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16820        || TARGET_MIX_SSE_I387)
16821    && flag_unsafe_math_optimizations"
16822 {
16823   rtx op0 = gen_reg_rtx (XFmode);
16824
16825   rtx op2 = gen_reg_rtx (XFmode);
16826   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16827
16828   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16829   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16830   DONE;
16831 })
16832
16833 (define_insn "fyl2xp1xf3_i387"
16834   [(set (match_operand:XF 0 "register_operand" "=f")
16835         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16836                     (match_operand:XF 2 "register_operand" "u")]
16837                    UNSPEC_FYL2XP1))
16838    (clobber (match_scratch:XF 3 "=2"))]
16839   "TARGET_USE_FANCY_MATH_387
16840    && flag_unsafe_math_optimizations"
16841   "fyl2xp1"
16842   [(set_attr "type" "fpspc")
16843    (set_attr "mode" "XF")])
16844
16845 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16846   [(set (match_operand:XF 0 "register_operand" "=f")
16847         (unspec:XF [(float_extend:XF
16848                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16849                     (match_operand:XF 2 "register_operand" "u")]
16850                    UNSPEC_FYL2XP1))
16851    (clobber (match_scratch:XF 3 "=2"))]
16852   "TARGET_USE_FANCY_MATH_387
16853    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16854        || TARGET_MIX_SSE_I387)
16855    && flag_unsafe_math_optimizations"
16856   "fyl2xp1"
16857   [(set_attr "type" "fpspc")
16858    (set_attr "mode" "XF")])
16859
16860 (define_expand "log1pxf2"
16861   [(use (match_operand:XF 0 "register_operand" ""))
16862    (use (match_operand:XF 1 "register_operand" ""))]
16863   "TARGET_USE_FANCY_MATH_387
16864    && flag_unsafe_math_optimizations && !optimize_size"
16865 {
16866   ix86_emit_i387_log1p (operands[0], operands[1]);
16867   DONE;
16868 })
16869
16870 (define_expand "log1p<mode>2"
16871   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16872    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16873   "TARGET_USE_FANCY_MATH_387
16874    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16875        || TARGET_MIX_SSE_I387)
16876    && flag_unsafe_math_optimizations && !optimize_size"
16877 {
16878   rtx op0 = gen_reg_rtx (XFmode);
16879
16880   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16881
16882   ix86_emit_i387_log1p (op0, operands[1]);
16883   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16884   DONE;
16885 })
16886
16887 (define_insn "fxtractxf3_i387"
16888   [(set (match_operand:XF 0 "register_operand" "=f")
16889         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16890                    UNSPEC_XTRACT_FRACT))
16891    (set (match_operand:XF 1 "register_operand" "=u")
16892         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16893   "TARGET_USE_FANCY_MATH_387
16894    && flag_unsafe_math_optimizations"
16895   "fxtract"
16896   [(set_attr "type" "fpspc")
16897    (set_attr "mode" "XF")])
16898
16899 (define_insn "fxtract_extend<mode>xf3_i387"
16900   [(set (match_operand:XF 0 "register_operand" "=f")
16901         (unspec:XF [(float_extend:XF
16902                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16903                    UNSPEC_XTRACT_FRACT))
16904    (set (match_operand:XF 1 "register_operand" "=u")
16905         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
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"
16910   "fxtract"
16911   [(set_attr "type" "fpspc")
16912    (set_attr "mode" "XF")])
16913
16914 (define_expand "logbxf2"
16915   [(parallel [(set (match_dup 2)
16916                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16917                               UNSPEC_XTRACT_FRACT))
16918               (set (match_operand:XF 0 "register_operand" "")
16919                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16920   "TARGET_USE_FANCY_MATH_387
16921    && flag_unsafe_math_optimizations"
16922 {
16923   operands[2] = gen_reg_rtx (XFmode);
16924 })
16925
16926 (define_expand "logb<mode>2"
16927   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16928    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16929   "TARGET_USE_FANCY_MATH_387
16930    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16931        || TARGET_MIX_SSE_I387)
16932    && flag_unsafe_math_optimizations"
16933 {
16934   rtx op0 = gen_reg_rtx (XFmode);
16935   rtx op1 = gen_reg_rtx (XFmode);
16936
16937   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16938   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16939   DONE;
16940 })
16941
16942 (define_expand "ilogbxf2"
16943   [(use (match_operand:SI 0 "register_operand" ""))
16944    (use (match_operand:XF 1 "register_operand" ""))]
16945   "TARGET_USE_FANCY_MATH_387
16946    && flag_unsafe_math_optimizations && !optimize_size"
16947 {
16948   rtx op0 = gen_reg_rtx (XFmode);
16949   rtx op1 = gen_reg_rtx (XFmode);
16950
16951   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16952   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16953   DONE;
16954 })
16955
16956 (define_expand "ilogb<mode>2"
16957   [(use (match_operand:SI 0 "register_operand" ""))
16958    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16959   "TARGET_USE_FANCY_MATH_387
16960    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16961        || TARGET_MIX_SSE_I387)
16962    && flag_unsafe_math_optimizations && !optimize_size"
16963 {
16964   rtx op0 = gen_reg_rtx (XFmode);
16965   rtx op1 = gen_reg_rtx (XFmode);
16966
16967   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16968   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16969   DONE;
16970 })
16971
16972 (define_insn "*f2xm1xf2_i387"
16973   [(set (match_operand:XF 0 "register_operand" "=f")
16974         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16975                    UNSPEC_F2XM1))]
16976   "TARGET_USE_FANCY_MATH_387
16977    && flag_unsafe_math_optimizations"
16978   "f2xm1"
16979   [(set_attr "type" "fpspc")
16980    (set_attr "mode" "XF")])
16981
16982 (define_insn "*fscalexf4_i387"
16983   [(set (match_operand:XF 0 "register_operand" "=f")
16984         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16985                     (match_operand:XF 3 "register_operand" "1")]
16986                    UNSPEC_FSCALE_FRACT))
16987    (set (match_operand:XF 1 "register_operand" "=u")
16988         (unspec:XF [(match_dup 2) (match_dup 3)]
16989                    UNSPEC_FSCALE_EXP))]
16990   "TARGET_USE_FANCY_MATH_387
16991    && flag_unsafe_math_optimizations"
16992   "fscale"
16993   [(set_attr "type" "fpspc")
16994    (set_attr "mode" "XF")])
16995
16996 (define_expand "expNcorexf3"
16997   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16998                                (match_operand:XF 2 "register_operand" "")))
16999    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17000    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17001    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17002    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17003    (parallel [(set (match_operand:XF 0 "register_operand" "")
17004                    (unspec:XF [(match_dup 8) (match_dup 4)]
17005                               UNSPEC_FSCALE_FRACT))
17006               (set (match_dup 9)
17007                    (unspec:XF [(match_dup 8) (match_dup 4)]
17008                               UNSPEC_FSCALE_EXP))])]
17009   "TARGET_USE_FANCY_MATH_387
17010    && flag_unsafe_math_optimizations && !optimize_size"
17011 {
17012   int i;
17013
17014   for (i = 3; i < 10; i++)
17015     operands[i] = gen_reg_rtx (XFmode);
17016
17017   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17018 })
17019
17020 (define_expand "expxf2"
17021   [(use (match_operand:XF 0 "register_operand" ""))
17022    (use (match_operand:XF 1 "register_operand" ""))]
17023   "TARGET_USE_FANCY_MATH_387
17024    && flag_unsafe_math_optimizations && !optimize_size"
17025 {
17026   rtx op2 = gen_reg_rtx (XFmode);
17027   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17028
17029   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17030   DONE;
17031 })
17032
17033 (define_expand "exp<mode>2"
17034   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17035    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17036  "TARGET_USE_FANCY_MATH_387
17037    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17038        || TARGET_MIX_SSE_I387)
17039    && flag_unsafe_math_optimizations && !optimize_size"
17040 {
17041   rtx op0 = gen_reg_rtx (XFmode);
17042   rtx op1 = gen_reg_rtx (XFmode);
17043
17044   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17045   emit_insn (gen_expxf2 (op0, op1));
17046   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17047   DONE;
17048 })
17049
17050 (define_expand "exp10xf2"
17051   [(use (match_operand:XF 0 "register_operand" ""))
17052    (use (match_operand:XF 1 "register_operand" ""))]
17053   "TARGET_USE_FANCY_MATH_387
17054    && flag_unsafe_math_optimizations && !optimize_size"
17055 {
17056   rtx op2 = gen_reg_rtx (XFmode);
17057   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17058
17059   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17060   DONE;
17061 })
17062
17063 (define_expand "exp10<mode>2"
17064   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17065    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17066  "TARGET_USE_FANCY_MATH_387
17067    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17068        || TARGET_MIX_SSE_I387)
17069    && flag_unsafe_math_optimizations && !optimize_size"
17070 {
17071   rtx op0 = gen_reg_rtx (XFmode);
17072   rtx op1 = gen_reg_rtx (XFmode);
17073
17074   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17075   emit_insn (gen_exp10xf2 (op0, op1));
17076   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17077   DONE;
17078 })
17079
17080 (define_expand "exp2xf2"
17081   [(use (match_operand:XF 0 "register_operand" ""))
17082    (use (match_operand:XF 1 "register_operand" ""))]
17083   "TARGET_USE_FANCY_MATH_387
17084    && flag_unsafe_math_optimizations && !optimize_size"
17085 {
17086   rtx op2 = gen_reg_rtx (XFmode);
17087   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17088
17089   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17090   DONE;
17091 })
17092
17093 (define_expand "exp2<mode>2"
17094   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17095    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17096  "TARGET_USE_FANCY_MATH_387
17097    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17098        || TARGET_MIX_SSE_I387)
17099    && flag_unsafe_math_optimizations && !optimize_size"
17100 {
17101   rtx op0 = gen_reg_rtx (XFmode);
17102   rtx op1 = gen_reg_rtx (XFmode);
17103
17104   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17105   emit_insn (gen_exp2xf2 (op0, op1));
17106   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17107   DONE;
17108 })
17109
17110 (define_expand "expm1xf2"
17111   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17112                                (match_dup 2)))
17113    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17114    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17115    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17116    (parallel [(set (match_dup 7)
17117                    (unspec:XF [(match_dup 6) (match_dup 4)]
17118                               UNSPEC_FSCALE_FRACT))
17119                    (set (match_dup 8)
17120                    (unspec:XF [(match_dup 6) (match_dup 4)]
17121                               UNSPEC_FSCALE_EXP))])
17122    (parallel [(set (match_dup 10)
17123                    (unspec:XF [(match_dup 9) (match_dup 8)]
17124                               UNSPEC_FSCALE_FRACT))
17125               (set (match_dup 11)
17126                    (unspec:XF [(match_dup 9) (match_dup 8)]
17127                               UNSPEC_FSCALE_EXP))])
17128    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17129    (set (match_operand:XF 0 "register_operand" "")
17130         (plus:XF (match_dup 12) (match_dup 7)))]
17131   "TARGET_USE_FANCY_MATH_387
17132    && flag_unsafe_math_optimizations && !optimize_size"
17133 {
17134   int i;
17135
17136   for (i = 2; i < 13; i++)
17137     operands[i] = gen_reg_rtx (XFmode);
17138  
17139   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17140   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
17141 })
17142
17143 (define_expand "expm1<mode>2"
17144   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17145    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17146  "TARGET_USE_FANCY_MATH_387
17147    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17148        || TARGET_MIX_SSE_I387)
17149    && flag_unsafe_math_optimizations && !optimize_size"
17150 {
17151   rtx op0 = gen_reg_rtx (XFmode);
17152   rtx op1 = gen_reg_rtx (XFmode);
17153
17154   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17155   emit_insn (gen_expm1xf2 (op0, op1));
17156   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17157   DONE;
17158 })
17159
17160 (define_expand "ldexpxf3"
17161   [(set (match_dup 3)
17162         (float:XF (match_operand:SI 2 "register_operand" "")))
17163    (parallel [(set (match_operand:XF 0 " register_operand" "")
17164                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17165                                (match_dup 3)]
17166                               UNSPEC_FSCALE_FRACT))
17167               (set (match_dup 4)
17168                    (unspec:XF [(match_dup 1) (match_dup 3)]
17169                               UNSPEC_FSCALE_EXP))])]
17170   "TARGET_USE_FANCY_MATH_387
17171    && flag_unsafe_math_optimizations && !optimize_size"
17172 {
17173   operands[3] = gen_reg_rtx (XFmode);
17174   operands[4] = gen_reg_rtx (XFmode);
17175 })
17176
17177 (define_expand "ldexp<mode>3"
17178   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17179    (use (match_operand:X87MODEF12 1 "general_operand" ""))
17180    (use (match_operand:SI 2 "register_operand" ""))]
17181  "TARGET_USE_FANCY_MATH_387
17182    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17183        || TARGET_MIX_SSE_I387)
17184    && flag_unsafe_math_optimizations && !optimize_size"
17185 {
17186   rtx op0 = gen_reg_rtx (XFmode);
17187   rtx op1 = gen_reg_rtx (XFmode);
17188
17189   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17190   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17191   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17192   DONE;
17193 })
17194 \f
17195
17196 (define_insn "frndintxf2"
17197   [(set (match_operand:XF 0 "register_operand" "=f")
17198         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17199          UNSPEC_FRNDINT))]
17200   "TARGET_USE_FANCY_MATH_387
17201    && flag_unsafe_math_optimizations"
17202   "frndint"
17203   [(set_attr "type" "fpspc")
17204    (set_attr "mode" "XF")])
17205
17206 (define_expand "rintdf2"
17207   [(use (match_operand:DF 0 "register_operand" ""))
17208    (use (match_operand:DF 1 "register_operand" ""))]
17209   "(TARGET_USE_FANCY_MATH_387
17210     && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17211     && flag_unsafe_math_optimizations)
17212    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17213        && !flag_trapping_math
17214        && !optimize_size)"
17215 {
17216   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17217       && !flag_trapping_math
17218       && !optimize_size)
17219     ix86_expand_rint (operand0, operand1);
17220   else
17221     {
17222       rtx op0 = gen_reg_rtx (XFmode);
17223       rtx op1 = gen_reg_rtx (XFmode);
17224
17225       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17226       emit_insn (gen_frndintxf2 (op0, op1));
17227
17228       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17229     }
17230   DONE;
17231 })
17232
17233 (define_expand "rintsf2"
17234   [(use (match_operand:SF 0 "register_operand" ""))
17235    (use (match_operand:SF 1 "register_operand" ""))]
17236   "(TARGET_USE_FANCY_MATH_387
17237     && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17238     && flag_unsafe_math_optimizations)
17239    || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17240        && !flag_trapping_math
17241        && !optimize_size)"
17242 {
17243   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17244       && !flag_trapping_math
17245       && !optimize_size)
17246     ix86_expand_rint (operand0, operand1);
17247   else
17248     {
17249       rtx op0 = gen_reg_rtx (XFmode);
17250       rtx op1 = gen_reg_rtx (XFmode);
17251
17252       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17253       emit_insn (gen_frndintxf2 (op0, op1));
17254
17255       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17256     }
17257   DONE;
17258 })
17259
17260 (define_expand "rintxf2"
17261   [(use (match_operand:XF 0 "register_operand" ""))
17262    (use (match_operand:XF 1 "register_operand" ""))]
17263   "TARGET_USE_FANCY_MATH_387
17264    && flag_unsafe_math_optimizations && !optimize_size"
17265 {
17266   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17267   DONE;
17268 })
17269
17270 (define_expand "roundsf2"
17271   [(match_operand:SF 0 "register_operand" "")
17272    (match_operand:SF 1 "nonimmediate_operand" "")]
17273   "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17274    && !flag_trapping_math && !flag_rounding_math
17275    && !optimize_size"
17276 {
17277   ix86_expand_round (operand0, operand1);
17278   DONE;
17279 })
17280
17281 (define_expand "rounddf2"
17282   [(match_operand:DF 0 "register_operand" "")
17283    (match_operand:DF 1 "nonimmediate_operand" "")]
17284   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17285    && !flag_trapping_math && !flag_rounding_math
17286    && !optimize_size"
17287 {
17288   if (TARGET_64BIT)
17289     ix86_expand_round (operand0, operand1);
17290   else
17291     ix86_expand_rounddf_32 (operand0, operand1);
17292   DONE;
17293 })
17294
17295 (define_insn_and_split "*fistdi2_1"
17296   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17297         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17298          UNSPEC_FIST))]
17299   "TARGET_USE_FANCY_MATH_387
17300    && !(reload_completed || reload_in_progress)"
17301   "#"
17302   "&& 1"
17303   [(const_int 0)]
17304 {
17305   if (memory_operand (operands[0], VOIDmode))
17306     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17307   else
17308     {
17309       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17310       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17311                                          operands[2]));
17312     }
17313   DONE;
17314 }
17315   [(set_attr "type" "fpspc")
17316    (set_attr "mode" "DI")])
17317
17318 (define_insn "fistdi2"
17319   [(set (match_operand:DI 0 "memory_operand" "=m")
17320         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17321          UNSPEC_FIST))
17322    (clobber (match_scratch:XF 2 "=&1f"))]
17323   "TARGET_USE_FANCY_MATH_387"
17324   "* return output_fix_trunc (insn, operands, 0);"
17325   [(set_attr "type" "fpspc")
17326    (set_attr "mode" "DI")])
17327
17328 (define_insn "fistdi2_with_temp"
17329   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17330         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17331          UNSPEC_FIST))
17332    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17333    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17334   "TARGET_USE_FANCY_MATH_387"
17335   "#"
17336   [(set_attr "type" "fpspc")
17337    (set_attr "mode" "DI")])
17338
17339 (define_split
17340   [(set (match_operand:DI 0 "register_operand" "")
17341         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17342          UNSPEC_FIST))
17343    (clobber (match_operand:DI 2 "memory_operand" ""))
17344    (clobber (match_scratch 3 ""))]
17345   "reload_completed"
17346   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17347               (clobber (match_dup 3))])
17348    (set (match_dup 0) (match_dup 2))]
17349   "")
17350
17351 (define_split
17352   [(set (match_operand:DI 0 "memory_operand" "")
17353         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17354          UNSPEC_FIST))
17355    (clobber (match_operand:DI 2 "memory_operand" ""))
17356    (clobber (match_scratch 3 ""))]
17357   "reload_completed"
17358   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17359               (clobber (match_dup 3))])]
17360   "")
17361
17362 (define_insn_and_split "*fist<mode>2_1"
17363   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17364         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17365          UNSPEC_FIST))]
17366   "TARGET_USE_FANCY_MATH_387
17367    && !(reload_completed || reload_in_progress)"
17368   "#"
17369   "&& 1"
17370   [(const_int 0)]
17371 {
17372   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17373   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17374                                         operands[2]));
17375   DONE;
17376 }
17377   [(set_attr "type" "fpspc")
17378    (set_attr "mode" "<MODE>")])
17379
17380 (define_insn "fist<mode>2"
17381   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17382         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17383          UNSPEC_FIST))]
17384   "TARGET_USE_FANCY_MATH_387"
17385   "* return output_fix_trunc (insn, operands, 0);"
17386   [(set_attr "type" "fpspc")
17387    (set_attr "mode" "<MODE>")])
17388
17389 (define_insn "fist<mode>2_with_temp"
17390   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17391         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17392          UNSPEC_FIST))
17393    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17394   "TARGET_USE_FANCY_MATH_387"
17395   "#"
17396   [(set_attr "type" "fpspc")
17397    (set_attr "mode" "<MODE>")])
17398
17399 (define_split
17400   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17401         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17402          UNSPEC_FIST))
17403    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17404   "reload_completed"
17405   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17406                        UNSPEC_FIST))
17407    (set (match_dup 0) (match_dup 2))]
17408   "")
17409
17410 (define_split
17411   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17412         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17413          UNSPEC_FIST))
17414    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17415   "reload_completed"
17416   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17417                        UNSPEC_FIST))]
17418   "")
17419
17420 (define_expand "lrintxf<mode>2"
17421   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17422      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17423       UNSPEC_FIST))]
17424   "TARGET_USE_FANCY_MATH_387"
17425   "")
17426
17427 (define_expand "lrint<mode>di2"
17428   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17429      (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
17430       UNSPEC_FIX_NOTRUNC))]
17431   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
17432   "")
17433
17434 (define_expand "lrint<mode>si2"
17435   [(set (match_operand:SI 0 "nonimmediate_operand" "")
17436      (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
17437       UNSPEC_FIX_NOTRUNC))]
17438   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17439   "")
17440
17441 (define_expand "lround<mode>di2"
17442   [(match_operand:DI 0 "nonimmediate_operand" "")
17443    (match_operand:SSEMODEF 1 "register_operand" "")]
17444   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17445    && !flag_trapping_math && !flag_rounding_math
17446    && !optimize_size"
17447 {
17448   ix86_expand_lround (operand0, operand1);
17449   DONE;
17450 })
17451
17452 (define_expand "lround<mode>si2"
17453   [(match_operand:SI 0 "nonimmediate_operand" "")
17454    (match_operand:SSEMODEF 1 "register_operand" "")]
17455   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17456    && !flag_trapping_math && !flag_rounding_math
17457    && !optimize_size"
17458 {
17459   ix86_expand_lround (operand0, operand1);
17460   DONE;
17461 })
17462
17463 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17464 (define_insn_and_split "frndintxf2_floor"
17465   [(set (match_operand:XF 0 "register_operand" "=f")
17466         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17467          UNSPEC_FRNDINT_FLOOR))
17468    (clobber (reg:CC FLAGS_REG))]
17469   "TARGET_USE_FANCY_MATH_387
17470    && flag_unsafe_math_optimizations
17471    && !(reload_completed || reload_in_progress)"
17472   "#"
17473   "&& 1"
17474   [(const_int 0)]
17475 {
17476   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17477
17478   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17479   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17480
17481   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17482                                         operands[2], operands[3]));
17483   DONE;
17484 }
17485   [(set_attr "type" "frndint")
17486    (set_attr "i387_cw" "floor")
17487    (set_attr "mode" "XF")])
17488
17489 (define_insn "frndintxf2_floor_i387"
17490   [(set (match_operand:XF 0 "register_operand" "=f")
17491         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17492          UNSPEC_FRNDINT_FLOOR))
17493    (use (match_operand:HI 2 "memory_operand" "m"))
17494    (use (match_operand:HI 3 "memory_operand" "m"))]
17495   "TARGET_USE_FANCY_MATH_387
17496    && flag_unsafe_math_optimizations"
17497   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17498   [(set_attr "type" "frndint")
17499    (set_attr "i387_cw" "floor")
17500    (set_attr "mode" "XF")])
17501
17502 (define_expand "floorxf2"
17503   [(use (match_operand:XF 0 "register_operand" ""))
17504    (use (match_operand:XF 1 "register_operand" ""))]
17505   "TARGET_USE_FANCY_MATH_387
17506    && flag_unsafe_math_optimizations && !optimize_size"
17507 {
17508   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17509   DONE;
17510 })
17511
17512 (define_expand "floordf2"
17513   [(use (match_operand:DF 0 "register_operand" ""))
17514    (use (match_operand:DF 1 "register_operand" ""))]
17515   "((TARGET_USE_FANCY_MATH_387
17516      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17517      && flag_unsafe_math_optimizations)
17518     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17519         && !flag_trapping_math))
17520    && !optimize_size"
17521 {
17522   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17523       && !flag_trapping_math)
17524     {
17525       if (TARGET_64BIT)
17526         ix86_expand_floorceil (operand0, operand1, true);
17527       else
17528         ix86_expand_floorceildf_32 (operand0, operand1, true);
17529     }
17530   else
17531     {
17532       rtx op0 = gen_reg_rtx (XFmode);
17533       rtx op1 = gen_reg_rtx (XFmode);
17534
17535       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17536       emit_insn (gen_frndintxf2_floor (op0, op1));
17537
17538       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17539     }
17540   DONE;
17541 })
17542
17543 (define_expand "floorsf2"
17544   [(use (match_operand:SF 0 "register_operand" ""))
17545    (use (match_operand:SF 1 "register_operand" ""))]
17546   "((TARGET_USE_FANCY_MATH_387
17547      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17548      && flag_unsafe_math_optimizations)
17549     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17550         && !flag_trapping_math))
17551    && !optimize_size"
17552 {
17553   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17554       && !flag_trapping_math)
17555     ix86_expand_floorceil (operand0, operand1, true);
17556   else
17557     {
17558       rtx op0 = gen_reg_rtx (XFmode);
17559       rtx op1 = gen_reg_rtx (XFmode);
17560
17561       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17562       emit_insn (gen_frndintxf2_floor (op0, op1));
17563
17564       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17565     }
17566   DONE;
17567 })
17568
17569 (define_insn_and_split "*fist<mode>2_floor_1"
17570   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17571         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17572          UNSPEC_FIST_FLOOR))
17573    (clobber (reg:CC FLAGS_REG))]
17574   "TARGET_USE_FANCY_MATH_387
17575    && flag_unsafe_math_optimizations
17576    && !(reload_completed || reload_in_progress)"
17577   "#"
17578   "&& 1"
17579   [(const_int 0)]
17580 {
17581   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17582
17583   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17584   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17585   if (memory_operand (operands[0], VOIDmode))
17586     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17587                                       operands[2], operands[3]));
17588   else
17589     {
17590       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17591       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17592                                                   operands[2], operands[3],
17593                                                   operands[4]));
17594     }
17595   DONE;
17596 }
17597   [(set_attr "type" "fistp")
17598    (set_attr "i387_cw" "floor")
17599    (set_attr "mode" "<MODE>")])
17600
17601 (define_insn "fistdi2_floor"
17602   [(set (match_operand:DI 0 "memory_operand" "=m")
17603         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17604          UNSPEC_FIST_FLOOR))
17605    (use (match_operand:HI 2 "memory_operand" "m"))
17606    (use (match_operand:HI 3 "memory_operand" "m"))
17607    (clobber (match_scratch:XF 4 "=&1f"))]
17608   "TARGET_USE_FANCY_MATH_387
17609    && flag_unsafe_math_optimizations"
17610   "* return output_fix_trunc (insn, operands, 0);"
17611   [(set_attr "type" "fistp")
17612    (set_attr "i387_cw" "floor")
17613    (set_attr "mode" "DI")])
17614
17615 (define_insn "fistdi2_floor_with_temp"
17616   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17617         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17618          UNSPEC_FIST_FLOOR))
17619    (use (match_operand:HI 2 "memory_operand" "m,m"))
17620    (use (match_operand:HI 3 "memory_operand" "m,m"))
17621    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17622    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17623   "TARGET_USE_FANCY_MATH_387
17624    && flag_unsafe_math_optimizations"
17625   "#"
17626   [(set_attr "type" "fistp")
17627    (set_attr "i387_cw" "floor")
17628    (set_attr "mode" "DI")])
17629
17630 (define_split
17631   [(set (match_operand:DI 0 "register_operand" "")
17632         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17633          UNSPEC_FIST_FLOOR))
17634    (use (match_operand:HI 2 "memory_operand" ""))
17635    (use (match_operand:HI 3 "memory_operand" ""))
17636    (clobber (match_operand:DI 4 "memory_operand" ""))
17637    (clobber (match_scratch 5 ""))]
17638   "reload_completed"
17639   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17640               (use (match_dup 2))
17641               (use (match_dup 3))
17642               (clobber (match_dup 5))])
17643    (set (match_dup 0) (match_dup 4))]
17644   "")
17645
17646 (define_split
17647   [(set (match_operand:DI 0 "memory_operand" "")
17648         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17649          UNSPEC_FIST_FLOOR))
17650    (use (match_operand:HI 2 "memory_operand" ""))
17651    (use (match_operand:HI 3 "memory_operand" ""))
17652    (clobber (match_operand:DI 4 "memory_operand" ""))
17653    (clobber (match_scratch 5 ""))]
17654   "reload_completed"
17655   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17656               (use (match_dup 2))
17657               (use (match_dup 3))
17658               (clobber (match_dup 5))])]
17659   "")
17660
17661 (define_insn "fist<mode>2_floor"
17662   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17663         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17664          UNSPEC_FIST_FLOOR))
17665    (use (match_operand:HI 2 "memory_operand" "m"))
17666    (use (match_operand:HI 3 "memory_operand" "m"))]
17667   "TARGET_USE_FANCY_MATH_387
17668    && flag_unsafe_math_optimizations"
17669   "* return output_fix_trunc (insn, operands, 0);"
17670   [(set_attr "type" "fistp")
17671    (set_attr "i387_cw" "floor")
17672    (set_attr "mode" "<MODE>")])
17673
17674 (define_insn "fist<mode>2_floor_with_temp"
17675   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17676         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17677          UNSPEC_FIST_FLOOR))
17678    (use (match_operand:HI 2 "memory_operand" "m,m"))
17679    (use (match_operand:HI 3 "memory_operand" "m,m"))
17680    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17681   "TARGET_USE_FANCY_MATH_387
17682    && flag_unsafe_math_optimizations"
17683   "#"
17684   [(set_attr "type" "fistp")
17685    (set_attr "i387_cw" "floor")
17686    (set_attr "mode" "<MODE>")])
17687
17688 (define_split
17689   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17690         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17691          UNSPEC_FIST_FLOOR))
17692    (use (match_operand:HI 2 "memory_operand" ""))
17693    (use (match_operand:HI 3 "memory_operand" ""))
17694    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17695   "reload_completed"
17696   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17697                                   UNSPEC_FIST_FLOOR))
17698               (use (match_dup 2))
17699               (use (match_dup 3))])
17700    (set (match_dup 0) (match_dup 4))]
17701   "")
17702
17703 (define_split
17704   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17705         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17706          UNSPEC_FIST_FLOOR))
17707    (use (match_operand:HI 2 "memory_operand" ""))
17708    (use (match_operand:HI 3 "memory_operand" ""))
17709    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17710   "reload_completed"
17711   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17712                                   UNSPEC_FIST_FLOOR))
17713               (use (match_dup 2))
17714               (use (match_dup 3))])]
17715   "")
17716
17717 (define_expand "lfloorxf<mode>2"
17718   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17719                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17720                     UNSPEC_FIST_FLOOR))
17721               (clobber (reg:CC FLAGS_REG))])]
17722   "TARGET_USE_FANCY_MATH_387
17723    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17724    && flag_unsafe_math_optimizations"
17725   "")
17726
17727 (define_expand "lfloor<mode>di2"
17728   [(match_operand:DI 0 "nonimmediate_operand" "")
17729    (match_operand:SSEMODEF 1 "register_operand" "")]
17730   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17731    && !flag_trapping_math
17732    && !optimize_size"
17733 {
17734   ix86_expand_lfloorceil (operand0, operand1, true);
17735   DONE;
17736 })
17737
17738 (define_expand "lfloor<mode>si2"
17739   [(match_operand:SI 0 "nonimmediate_operand" "")
17740    (match_operand:SSEMODEF 1 "register_operand" "")]
17741   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17742    && !flag_trapping_math
17743    && (!optimize_size || !TARGET_64BIT)"
17744 {
17745   ix86_expand_lfloorceil (operand0, operand1, true);
17746   DONE;
17747 })
17748
17749 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17750 (define_insn_and_split "frndintxf2_ceil"
17751   [(set (match_operand:XF 0 "register_operand" "=f")
17752         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17753          UNSPEC_FRNDINT_CEIL))
17754    (clobber (reg:CC FLAGS_REG))]
17755   "TARGET_USE_FANCY_MATH_387
17756    && flag_unsafe_math_optimizations
17757    && !(reload_completed || reload_in_progress)"
17758   "#"
17759   "&& 1"
17760   [(const_int 0)]
17761 {
17762   ix86_optimize_mode_switching[I387_CEIL] = 1;
17763
17764   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17765   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17766
17767   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17768                                        operands[2], operands[3]));
17769   DONE;
17770 }
17771   [(set_attr "type" "frndint")
17772    (set_attr "i387_cw" "ceil")
17773    (set_attr "mode" "XF")])
17774
17775 (define_insn "frndintxf2_ceil_i387"
17776   [(set (match_operand:XF 0 "register_operand" "=f")
17777         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17778          UNSPEC_FRNDINT_CEIL))
17779    (use (match_operand:HI 2 "memory_operand" "m"))
17780    (use (match_operand:HI 3 "memory_operand" "m"))]
17781   "TARGET_USE_FANCY_MATH_387
17782    && flag_unsafe_math_optimizations"
17783   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17784   [(set_attr "type" "frndint")
17785    (set_attr "i387_cw" "ceil")
17786    (set_attr "mode" "XF")])
17787
17788 (define_expand "ceilxf2"
17789   [(use (match_operand:XF 0 "register_operand" ""))
17790    (use (match_operand:XF 1 "register_operand" ""))]
17791   "TARGET_USE_FANCY_MATH_387
17792    && flag_unsafe_math_optimizations && !optimize_size"
17793 {
17794   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17795   DONE;
17796 })
17797
17798 (define_expand "ceildf2"
17799   [(use (match_operand:DF 0 "register_operand" ""))
17800    (use (match_operand:DF 1 "register_operand" ""))]
17801   "((TARGET_USE_FANCY_MATH_387
17802      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17803      && flag_unsafe_math_optimizations)
17804     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17805         && !flag_trapping_math))
17806    && !optimize_size"
17807 {
17808   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17809       && !flag_trapping_math)
17810     {
17811       if (TARGET_64BIT)
17812         ix86_expand_floorceil (operand0, operand1, false);
17813       else
17814         ix86_expand_floorceildf_32 (operand0, operand1, false);
17815     }
17816   else
17817     {
17818       rtx op0 = gen_reg_rtx (XFmode);
17819       rtx op1 = gen_reg_rtx (XFmode);
17820
17821       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17822       emit_insn (gen_frndintxf2_ceil (op0, op1));
17823
17824       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17825     }
17826   DONE;
17827 })
17828
17829 (define_expand "ceilsf2"
17830   [(use (match_operand:SF 0 "register_operand" ""))
17831    (use (match_operand:SF 1 "register_operand" ""))]
17832   "((TARGET_USE_FANCY_MATH_387
17833      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17834      && flag_unsafe_math_optimizations)
17835     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17836         && !flag_trapping_math))
17837    && !optimize_size"
17838 {
17839   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17840       && !flag_trapping_math)
17841     ix86_expand_floorceil (operand0, operand1, false);
17842   else
17843     {
17844       rtx op0 = gen_reg_rtx (XFmode);
17845       rtx op1 = gen_reg_rtx (XFmode);
17846
17847       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17848       emit_insn (gen_frndintxf2_ceil (op0, op1));
17849
17850       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17851     }
17852   DONE;
17853 })
17854
17855 (define_insn_and_split "*fist<mode>2_ceil_1"
17856   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17857         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17858          UNSPEC_FIST_CEIL))
17859    (clobber (reg:CC FLAGS_REG))]
17860   "TARGET_USE_FANCY_MATH_387
17861    && flag_unsafe_math_optimizations
17862    && !(reload_completed || reload_in_progress)"
17863   "#"
17864   "&& 1"
17865   [(const_int 0)]
17866 {
17867   ix86_optimize_mode_switching[I387_CEIL] = 1;
17868
17869   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17870   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17871   if (memory_operand (operands[0], VOIDmode))
17872     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17873                                      operands[2], operands[3]));
17874   else
17875     {
17876       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17877       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17878                                                  operands[2], operands[3],
17879                                                  operands[4]));
17880     }
17881   DONE;
17882 }
17883   [(set_attr "type" "fistp")
17884    (set_attr "i387_cw" "ceil")
17885    (set_attr "mode" "<MODE>")])
17886
17887 (define_insn "fistdi2_ceil"
17888   [(set (match_operand:DI 0 "memory_operand" "=m")
17889         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17890          UNSPEC_FIST_CEIL))
17891    (use (match_operand:HI 2 "memory_operand" "m"))
17892    (use (match_operand:HI 3 "memory_operand" "m"))
17893    (clobber (match_scratch:XF 4 "=&1f"))]
17894   "TARGET_USE_FANCY_MATH_387
17895    && flag_unsafe_math_optimizations"
17896   "* return output_fix_trunc (insn, operands, 0);"
17897   [(set_attr "type" "fistp")
17898    (set_attr "i387_cw" "ceil")
17899    (set_attr "mode" "DI")])
17900
17901 (define_insn "fistdi2_ceil_with_temp"
17902   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17903         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17904          UNSPEC_FIST_CEIL))
17905    (use (match_operand:HI 2 "memory_operand" "m,m"))
17906    (use (match_operand:HI 3 "memory_operand" "m,m"))
17907    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17908    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17909   "TARGET_USE_FANCY_MATH_387
17910    && flag_unsafe_math_optimizations"
17911   "#"
17912   [(set_attr "type" "fistp")
17913    (set_attr "i387_cw" "ceil")
17914    (set_attr "mode" "DI")])
17915
17916 (define_split
17917   [(set (match_operand:DI 0 "register_operand" "")
17918         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17919          UNSPEC_FIST_CEIL))
17920    (use (match_operand:HI 2 "memory_operand" ""))
17921    (use (match_operand:HI 3 "memory_operand" ""))
17922    (clobber (match_operand:DI 4 "memory_operand" ""))
17923    (clobber (match_scratch 5 ""))]
17924   "reload_completed"
17925   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17926               (use (match_dup 2))
17927               (use (match_dup 3))
17928               (clobber (match_dup 5))])
17929    (set (match_dup 0) (match_dup 4))]
17930   "")
17931
17932 (define_split
17933   [(set (match_operand:DI 0 "memory_operand" "")
17934         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17935          UNSPEC_FIST_CEIL))
17936    (use (match_operand:HI 2 "memory_operand" ""))
17937    (use (match_operand:HI 3 "memory_operand" ""))
17938    (clobber (match_operand:DI 4 "memory_operand" ""))
17939    (clobber (match_scratch 5 ""))]
17940   "reload_completed"
17941   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17942               (use (match_dup 2))
17943               (use (match_dup 3))
17944               (clobber (match_dup 5))])]
17945   "")
17946
17947 (define_insn "fist<mode>2_ceil"
17948   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17949         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17950          UNSPEC_FIST_CEIL))
17951    (use (match_operand:HI 2 "memory_operand" "m"))
17952    (use (match_operand:HI 3 "memory_operand" "m"))]
17953   "TARGET_USE_FANCY_MATH_387
17954    && flag_unsafe_math_optimizations"
17955   "* return output_fix_trunc (insn, operands, 0);"
17956   [(set_attr "type" "fistp")
17957    (set_attr "i387_cw" "ceil")
17958    (set_attr "mode" "<MODE>")])
17959
17960 (define_insn "fist<mode>2_ceil_with_temp"
17961   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17962         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17963          UNSPEC_FIST_CEIL))
17964    (use (match_operand:HI 2 "memory_operand" "m,m"))
17965    (use (match_operand:HI 3 "memory_operand" "m,m"))
17966    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17967   "TARGET_USE_FANCY_MATH_387
17968    && flag_unsafe_math_optimizations"
17969   "#"
17970   [(set_attr "type" "fistp")
17971    (set_attr "i387_cw" "ceil")
17972    (set_attr "mode" "<MODE>")])
17973
17974 (define_split
17975   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17976         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17977          UNSPEC_FIST_CEIL))
17978    (use (match_operand:HI 2 "memory_operand" ""))
17979    (use (match_operand:HI 3 "memory_operand" ""))
17980    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17981   "reload_completed"
17982   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17983                                   UNSPEC_FIST_CEIL))
17984               (use (match_dup 2))
17985               (use (match_dup 3))])
17986    (set (match_dup 0) (match_dup 4))]
17987   "")
17988
17989 (define_split
17990   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17991         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17992          UNSPEC_FIST_CEIL))
17993    (use (match_operand:HI 2 "memory_operand" ""))
17994    (use (match_operand:HI 3 "memory_operand" ""))
17995    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17996   "reload_completed"
17997   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17998                                   UNSPEC_FIST_CEIL))
17999               (use (match_dup 2))
18000               (use (match_dup 3))])]
18001   "")
18002
18003 (define_expand "lceilxf<mode>2"
18004   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18005                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18006                     UNSPEC_FIST_CEIL))
18007               (clobber (reg:CC FLAGS_REG))])]
18008   "TARGET_USE_FANCY_MATH_387
18009    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18010    && flag_unsafe_math_optimizations"
18011   "")
18012
18013 (define_expand "lceil<mode>di2"
18014   [(match_operand:DI 0 "nonimmediate_operand" "")
18015    (match_operand:SSEMODEF 1 "register_operand" "")]
18016   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18017    && !flag_trapping_math"
18018 {
18019   ix86_expand_lfloorceil (operand0, operand1, false);
18020   DONE;
18021 })
18022
18023 (define_expand "lceil<mode>si2"
18024   [(match_operand:SI 0 "nonimmediate_operand" "")
18025    (match_operand:SSEMODEF 1 "register_operand" "")]
18026   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18027    && !flag_trapping_math"
18028 {
18029   ix86_expand_lfloorceil (operand0, operand1, false);
18030   DONE;
18031 })
18032
18033 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18034 (define_insn_and_split "frndintxf2_trunc"
18035   [(set (match_operand:XF 0 "register_operand" "=f")
18036         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18037          UNSPEC_FRNDINT_TRUNC))
18038    (clobber (reg:CC FLAGS_REG))]
18039   "TARGET_USE_FANCY_MATH_387
18040    && flag_unsafe_math_optimizations
18041    && !(reload_completed || reload_in_progress)"
18042   "#"
18043   "&& 1"
18044   [(const_int 0)]
18045 {
18046   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18047
18048   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18049   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18050
18051   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18052                                         operands[2], operands[3]));
18053   DONE;
18054 }
18055   [(set_attr "type" "frndint")
18056    (set_attr "i387_cw" "trunc")
18057    (set_attr "mode" "XF")])
18058
18059 (define_insn "frndintxf2_trunc_i387"
18060   [(set (match_operand:XF 0 "register_operand" "=f")
18061         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18062          UNSPEC_FRNDINT_TRUNC))
18063    (use (match_operand:HI 2 "memory_operand" "m"))
18064    (use (match_operand:HI 3 "memory_operand" "m"))]
18065   "TARGET_USE_FANCY_MATH_387
18066    && flag_unsafe_math_optimizations"
18067   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18068   [(set_attr "type" "frndint")
18069    (set_attr "i387_cw" "trunc")
18070    (set_attr "mode" "XF")])
18071
18072 (define_expand "btruncxf2"
18073   [(use (match_operand:XF 0 "register_operand" ""))
18074    (use (match_operand:XF 1 "register_operand" ""))]
18075   "TARGET_USE_FANCY_MATH_387
18076    && flag_unsafe_math_optimizations && !optimize_size"
18077 {
18078   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18079   DONE;
18080 })
18081
18082 (define_expand "btruncdf2"
18083   [(use (match_operand:DF 0 "register_operand" ""))
18084    (use (match_operand:DF 1 "register_operand" ""))]
18085   "((TARGET_USE_FANCY_MATH_387
18086      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18087      && flag_unsafe_math_optimizations)
18088     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18089         && !flag_trapping_math))
18090    && !optimize_size"
18091 {
18092   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18093       && !flag_trapping_math)
18094     {
18095       if (TARGET_64BIT)
18096         ix86_expand_trunc (operand0, operand1);
18097       else
18098         ix86_expand_truncdf_32 (operand0, operand1);
18099     }
18100   else
18101     {
18102       rtx op0 = gen_reg_rtx (XFmode);
18103       rtx op1 = gen_reg_rtx (XFmode);
18104
18105       emit_insn (gen_extenddfxf2 (op1, operands[1]));
18106       emit_insn (gen_frndintxf2_trunc (op0, op1));
18107
18108       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18109     }
18110   DONE;
18111 })
18112
18113 (define_expand "btruncsf2"
18114   [(use (match_operand:SF 0 "register_operand" ""))
18115    (use (match_operand:SF 1 "register_operand" ""))]
18116   "((TARGET_USE_FANCY_MATH_387
18117      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18118      && flag_unsafe_math_optimizations)
18119     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18120         && !flag_trapping_math))
18121    && !optimize_size"
18122 {
18123   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18124       && !flag_trapping_math)
18125     ix86_expand_trunc (operand0, operand1);
18126   else
18127     {
18128       rtx op0 = gen_reg_rtx (XFmode);
18129       rtx op1 = gen_reg_rtx (XFmode);
18130
18131       emit_insn (gen_extendsfxf2 (op1, operands[1]));
18132       emit_insn (gen_frndintxf2_trunc (op0, op1));
18133
18134       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18135     }
18136   DONE;
18137 })
18138
18139 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18140 (define_insn_and_split "frndintxf2_mask_pm"
18141   [(set (match_operand:XF 0 "register_operand" "=f")
18142         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18143          UNSPEC_FRNDINT_MASK_PM))
18144    (clobber (reg:CC FLAGS_REG))]
18145   "TARGET_USE_FANCY_MATH_387
18146    && flag_unsafe_math_optimizations
18147    && !(reload_completed || reload_in_progress)"
18148   "#"
18149   "&& 1"
18150   [(const_int 0)]
18151 {
18152   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18153
18154   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18155   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18156
18157   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18158                                           operands[2], operands[3]));
18159   DONE;
18160 }
18161   [(set_attr "type" "frndint")
18162    (set_attr "i387_cw" "mask_pm")
18163    (set_attr "mode" "XF")])
18164
18165 (define_insn "frndintxf2_mask_pm_i387"
18166   [(set (match_operand:XF 0 "register_operand" "=f")
18167         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18168          UNSPEC_FRNDINT_MASK_PM))
18169    (use (match_operand:HI 2 "memory_operand" "m"))
18170    (use (match_operand:HI 3 "memory_operand" "m"))]
18171   "TARGET_USE_FANCY_MATH_387
18172    && flag_unsafe_math_optimizations"
18173   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18174   [(set_attr "type" "frndint")
18175    (set_attr "i387_cw" "mask_pm")
18176    (set_attr "mode" "XF")])
18177
18178 (define_expand "nearbyintxf2"
18179   [(use (match_operand:XF 0 "register_operand" ""))
18180    (use (match_operand:XF 1 "register_operand" ""))]
18181   "TARGET_USE_FANCY_MATH_387
18182    && flag_unsafe_math_optimizations"
18183 {
18184   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18185
18186   DONE;
18187 })
18188
18189 (define_expand "nearbyintdf2"
18190   [(use (match_operand:DF 0 "register_operand" ""))
18191    (use (match_operand:DF 1 "register_operand" ""))]
18192   "TARGET_USE_FANCY_MATH_387
18193    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18194    && flag_unsafe_math_optimizations"
18195 {
18196   rtx op0 = gen_reg_rtx (XFmode);
18197   rtx op1 = gen_reg_rtx (XFmode);
18198
18199   emit_insn (gen_extenddfxf2 (op1, operands[1]));
18200   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18201
18202   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18203   DONE;
18204 })
18205
18206 (define_expand "nearbyintsf2"
18207   [(use (match_operand:SF 0 "register_operand" ""))
18208    (use (match_operand:SF 1 "register_operand" ""))]
18209   "TARGET_USE_FANCY_MATH_387
18210    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18211    && flag_unsafe_math_optimizations"
18212 {
18213   rtx op0 = gen_reg_rtx (XFmode);
18214   rtx op1 = gen_reg_rtx (XFmode);
18215
18216   emit_insn (gen_extendsfxf2 (op1, operands[1]));
18217   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18218
18219   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18220   DONE;
18221 })
18222
18223 (define_insn "fxam<mode>2_i387"
18224   [(set (match_operand:HI 0 "register_operand" "=a")
18225         (unspec:HI
18226           [(match_operand:X87MODEF 1 "register_operand" "f")]
18227           UNSPEC_FXAM))]
18228   "TARGET_USE_FANCY_MATH_387"
18229   "fxam\n\tfnstsw\t%0"
18230   [(set_attr "type" "multi")
18231    (set_attr "unit" "i387")
18232    (set_attr "mode" "<MODE>")])
18233
18234 (define_expand "isinf<mode>2"
18235   [(use (match_operand:SI 0 "register_operand" ""))
18236    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18237   "TARGET_USE_FANCY_MATH_387
18238   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18239       || TARGET_MIX_SSE_I387)"
18240 {
18241   rtx mask = GEN_INT (0x45);
18242   rtx val = GEN_INT (0x05);
18243
18244   rtx cond;
18245
18246   rtx scratch = gen_reg_rtx (HImode);
18247   rtx res = gen_reg_rtx (QImode);
18248
18249   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18250   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18251   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18252   cond = gen_rtx_fmt_ee (EQ, QImode,
18253                          gen_rtx_REG (CCmode, FLAGS_REG),
18254                          const0_rtx);
18255   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18256   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18257   DONE;
18258 })
18259
18260 \f
18261 ;; Block operation instructions
18262
18263 (define_expand "movmemsi"
18264   [(use (match_operand:BLK 0 "memory_operand" ""))
18265    (use (match_operand:BLK 1 "memory_operand" ""))
18266    (use (match_operand:SI 2 "nonmemory_operand" ""))
18267    (use (match_operand:SI 3 "const_int_operand" ""))
18268    (use (match_operand:SI 4 "const_int_operand" ""))
18269    (use (match_operand:SI 5 "const_int_operand" ""))]
18270   ""
18271 {
18272  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18273                          operands[4], operands[5]))
18274    DONE;
18275  else
18276    FAIL;
18277 })
18278
18279 (define_expand "movmemdi"
18280   [(use (match_operand:BLK 0 "memory_operand" ""))
18281    (use (match_operand:BLK 1 "memory_operand" ""))
18282    (use (match_operand:DI 2 "nonmemory_operand" ""))
18283    (use (match_operand:DI 3 "const_int_operand" ""))
18284    (use (match_operand:SI 4 "const_int_operand" ""))
18285    (use (match_operand:SI 5 "const_int_operand" ""))]
18286   "TARGET_64BIT"
18287 {
18288  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18289                          operands[4], operands[5]))
18290    DONE;
18291  else
18292    FAIL;
18293 })
18294
18295 ;; Most CPUs don't like single string operations
18296 ;; Handle this case here to simplify previous expander.
18297
18298 (define_expand "strmov"
18299   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18300    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18301    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18302               (clobber (reg:CC FLAGS_REG))])
18303    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18304               (clobber (reg:CC FLAGS_REG))])]
18305   ""
18306 {
18307   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18308
18309   /* If .md ever supports :P for Pmode, these can be directly
18310      in the pattern above.  */
18311   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18312   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18313
18314   if (TARGET_SINGLE_STRINGOP || optimize_size)
18315     {
18316       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18317                                       operands[2], operands[3],
18318                                       operands[5], operands[6]));
18319       DONE;
18320     }
18321
18322   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18323 })
18324
18325 (define_expand "strmov_singleop"
18326   [(parallel [(set (match_operand 1 "memory_operand" "")
18327                    (match_operand 3 "memory_operand" ""))
18328               (set (match_operand 0 "register_operand" "")
18329                    (match_operand 4 "" ""))
18330               (set (match_operand 2 "register_operand" "")
18331                    (match_operand 5 "" ""))])]
18332   "TARGET_SINGLE_STRINGOP || optimize_size"
18333   "")
18334
18335 (define_insn "*strmovdi_rex_1"
18336   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18337         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18338    (set (match_operand:DI 0 "register_operand" "=D")
18339         (plus:DI (match_dup 2)
18340                  (const_int 8)))
18341    (set (match_operand:DI 1 "register_operand" "=S")
18342         (plus:DI (match_dup 3)
18343                  (const_int 8)))]
18344   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18345   "movsq"
18346   [(set_attr "type" "str")
18347    (set_attr "mode" "DI")
18348    (set_attr "memory" "both")])
18349
18350 (define_insn "*strmovsi_1"
18351   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18352         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18353    (set (match_operand:SI 0 "register_operand" "=D")
18354         (plus:SI (match_dup 2)
18355                  (const_int 4)))
18356    (set (match_operand:SI 1 "register_operand" "=S")
18357         (plus:SI (match_dup 3)
18358                  (const_int 4)))]
18359   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18360   "{movsl|movsd}"
18361   [(set_attr "type" "str")
18362    (set_attr "mode" "SI")
18363    (set_attr "memory" "both")])
18364
18365 (define_insn "*strmovsi_rex_1"
18366   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18367         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18368    (set (match_operand:DI 0 "register_operand" "=D")
18369         (plus:DI (match_dup 2)
18370                  (const_int 4)))
18371    (set (match_operand:DI 1 "register_operand" "=S")
18372         (plus:DI (match_dup 3)
18373                  (const_int 4)))]
18374   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18375   "{movsl|movsd}"
18376   [(set_attr "type" "str")
18377    (set_attr "mode" "SI")
18378    (set_attr "memory" "both")])
18379
18380 (define_insn "*strmovhi_1"
18381   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18382         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18383    (set (match_operand:SI 0 "register_operand" "=D")
18384         (plus:SI (match_dup 2)
18385                  (const_int 2)))
18386    (set (match_operand:SI 1 "register_operand" "=S")
18387         (plus:SI (match_dup 3)
18388                  (const_int 2)))]
18389   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18390   "movsw"
18391   [(set_attr "type" "str")
18392    (set_attr "memory" "both")
18393    (set_attr "mode" "HI")])
18394
18395 (define_insn "*strmovhi_rex_1"
18396   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18397         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18398    (set (match_operand:DI 0 "register_operand" "=D")
18399         (plus:DI (match_dup 2)
18400                  (const_int 2)))
18401    (set (match_operand:DI 1 "register_operand" "=S")
18402         (plus:DI (match_dup 3)
18403                  (const_int 2)))]
18404   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18405   "movsw"
18406   [(set_attr "type" "str")
18407    (set_attr "memory" "both")
18408    (set_attr "mode" "HI")])
18409
18410 (define_insn "*strmovqi_1"
18411   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18412         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18413    (set (match_operand:SI 0 "register_operand" "=D")
18414         (plus:SI (match_dup 2)
18415                  (const_int 1)))
18416    (set (match_operand:SI 1 "register_operand" "=S")
18417         (plus:SI (match_dup 3)
18418                  (const_int 1)))]
18419   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18420   "movsb"
18421   [(set_attr "type" "str")
18422    (set_attr "memory" "both")
18423    (set_attr "mode" "QI")])
18424
18425 (define_insn "*strmovqi_rex_1"
18426   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18427         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18428    (set (match_operand:DI 0 "register_operand" "=D")
18429         (plus:DI (match_dup 2)
18430                  (const_int 1)))
18431    (set (match_operand:DI 1 "register_operand" "=S")
18432         (plus:DI (match_dup 3)
18433                  (const_int 1)))]
18434   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18435   "movsb"
18436   [(set_attr "type" "str")
18437    (set_attr "memory" "both")
18438    (set_attr "mode" "QI")])
18439
18440 (define_expand "rep_mov"
18441   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18442               (set (match_operand 0 "register_operand" "")
18443                    (match_operand 5 "" ""))
18444               (set (match_operand 2 "register_operand" "")
18445                    (match_operand 6 "" ""))
18446               (set (match_operand 1 "memory_operand" "")
18447                    (match_operand 3 "memory_operand" ""))
18448               (use (match_dup 4))])]
18449   ""
18450   "")
18451
18452 (define_insn "*rep_movdi_rex64"
18453   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18454    (set (match_operand:DI 0 "register_operand" "=D")
18455         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18456                             (const_int 3))
18457                  (match_operand:DI 3 "register_operand" "0")))
18458    (set (match_operand:DI 1 "register_operand" "=S")
18459         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18460                  (match_operand:DI 4 "register_operand" "1")))
18461    (set (mem:BLK (match_dup 3))
18462         (mem:BLK (match_dup 4)))
18463    (use (match_dup 5))]
18464   "TARGET_64BIT"
18465   "{rep\;movsq|rep movsq}"
18466   [(set_attr "type" "str")
18467    (set_attr "prefix_rep" "1")
18468    (set_attr "memory" "both")
18469    (set_attr "mode" "DI")])
18470
18471 (define_insn "*rep_movsi"
18472   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18473    (set (match_operand:SI 0 "register_operand" "=D")
18474         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18475                             (const_int 2))
18476                  (match_operand:SI 3 "register_operand" "0")))
18477    (set (match_operand:SI 1 "register_operand" "=S")
18478         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18479                  (match_operand:SI 4 "register_operand" "1")))
18480    (set (mem:BLK (match_dup 3))
18481         (mem:BLK (match_dup 4)))
18482    (use (match_dup 5))]
18483   "!TARGET_64BIT"
18484   "{rep\;movsl|rep movsd}"
18485   [(set_attr "type" "str")
18486    (set_attr "prefix_rep" "1")
18487    (set_attr "memory" "both")
18488    (set_attr "mode" "SI")])
18489
18490 (define_insn "*rep_movsi_rex64"
18491   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18492    (set (match_operand:DI 0 "register_operand" "=D")
18493         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18494                             (const_int 2))
18495                  (match_operand:DI 3 "register_operand" "0")))
18496    (set (match_operand:DI 1 "register_operand" "=S")
18497         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18498                  (match_operand:DI 4 "register_operand" "1")))
18499    (set (mem:BLK (match_dup 3))
18500         (mem:BLK (match_dup 4)))
18501    (use (match_dup 5))]
18502   "TARGET_64BIT"
18503   "{rep\;movsl|rep movsd}"
18504   [(set_attr "type" "str")
18505    (set_attr "prefix_rep" "1")
18506    (set_attr "memory" "both")
18507    (set_attr "mode" "SI")])
18508
18509 (define_insn "*rep_movqi"
18510   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18511    (set (match_operand:SI 0 "register_operand" "=D")
18512         (plus:SI (match_operand:SI 3 "register_operand" "0")
18513                  (match_operand:SI 5 "register_operand" "2")))
18514    (set (match_operand:SI 1 "register_operand" "=S")
18515         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18516    (set (mem:BLK (match_dup 3))
18517         (mem:BLK (match_dup 4)))
18518    (use (match_dup 5))]
18519   "!TARGET_64BIT"
18520   "{rep\;movsb|rep movsb}"
18521   [(set_attr "type" "str")
18522    (set_attr "prefix_rep" "1")
18523    (set_attr "memory" "both")
18524    (set_attr "mode" "SI")])
18525
18526 (define_insn "*rep_movqi_rex64"
18527   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18528    (set (match_operand:DI 0 "register_operand" "=D")
18529         (plus:DI (match_operand:DI 3 "register_operand" "0")
18530                  (match_operand:DI 5 "register_operand" "2")))
18531    (set (match_operand:DI 1 "register_operand" "=S")
18532         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18533    (set (mem:BLK (match_dup 3))
18534         (mem:BLK (match_dup 4)))
18535    (use (match_dup 5))]
18536   "TARGET_64BIT"
18537   "{rep\;movsb|rep movsb}"
18538   [(set_attr "type" "str")
18539    (set_attr "prefix_rep" "1")
18540    (set_attr "memory" "both")
18541    (set_attr "mode" "SI")])
18542
18543 (define_expand "setmemsi"
18544    [(use (match_operand:BLK 0 "memory_operand" ""))
18545     (use (match_operand:SI 1 "nonmemory_operand" ""))
18546     (use (match_operand 2 "const_int_operand" ""))
18547     (use (match_operand 3 "const_int_operand" ""))
18548     (use (match_operand:SI 4 "const_int_operand" ""))
18549     (use (match_operand:SI 5 "const_int_operand" ""))]
18550   ""
18551 {
18552  if (ix86_expand_setmem (operands[0], operands[1],
18553                          operands[2], operands[3],
18554                          operands[4], operands[5]))
18555    DONE;
18556  else
18557    FAIL;
18558 })
18559
18560 (define_expand "setmemdi"
18561    [(use (match_operand:BLK 0 "memory_operand" ""))
18562     (use (match_operand:DI 1 "nonmemory_operand" ""))
18563     (use (match_operand 2 "const_int_operand" ""))
18564     (use (match_operand 3 "const_int_operand" ""))
18565     (use (match_operand 4 "const_int_operand" ""))
18566     (use (match_operand 5 "const_int_operand" ""))]
18567   "TARGET_64BIT"
18568 {
18569  if (ix86_expand_setmem (operands[0], operands[1],
18570                          operands[2], operands[3],
18571                          operands[4], operands[5]))
18572    DONE;
18573  else
18574    FAIL;
18575 })
18576
18577 ;; Most CPUs don't like single string operations
18578 ;; Handle this case here to simplify previous expander.
18579
18580 (define_expand "strset"
18581   [(set (match_operand 1 "memory_operand" "")
18582         (match_operand 2 "register_operand" ""))
18583    (parallel [(set (match_operand 0 "register_operand" "")
18584                    (match_dup 3))
18585               (clobber (reg:CC FLAGS_REG))])]
18586   ""
18587 {
18588   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18589     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18590
18591   /* If .md ever supports :P for Pmode, this can be directly
18592      in the pattern above.  */
18593   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18594                               GEN_INT (GET_MODE_SIZE (GET_MODE
18595                                                       (operands[2]))));
18596   if (TARGET_SINGLE_STRINGOP || optimize_size)
18597     {
18598       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18599                                       operands[3]));
18600       DONE;
18601     }
18602 })
18603
18604 (define_expand "strset_singleop"
18605   [(parallel [(set (match_operand 1 "memory_operand" "")
18606                    (match_operand 2 "register_operand" ""))
18607               (set (match_operand 0 "register_operand" "")
18608                    (match_operand 3 "" ""))])]
18609   "TARGET_SINGLE_STRINGOP || optimize_size"
18610   "")
18611
18612 (define_insn "*strsetdi_rex_1"
18613   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18614         (match_operand:DI 2 "register_operand" "a"))
18615    (set (match_operand:DI 0 "register_operand" "=D")
18616         (plus:DI (match_dup 1)
18617                  (const_int 8)))]
18618   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18619   "stosq"
18620   [(set_attr "type" "str")
18621    (set_attr "memory" "store")
18622    (set_attr "mode" "DI")])
18623
18624 (define_insn "*strsetsi_1"
18625   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18626         (match_operand:SI 2 "register_operand" "a"))
18627    (set (match_operand:SI 0 "register_operand" "=D")
18628         (plus:SI (match_dup 1)
18629                  (const_int 4)))]
18630   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18631   "{stosl|stosd}"
18632   [(set_attr "type" "str")
18633    (set_attr "memory" "store")
18634    (set_attr "mode" "SI")])
18635
18636 (define_insn "*strsetsi_rex_1"
18637   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18638         (match_operand:SI 2 "register_operand" "a"))
18639    (set (match_operand:DI 0 "register_operand" "=D")
18640         (plus:DI (match_dup 1)
18641                  (const_int 4)))]
18642   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18643   "{stosl|stosd}"
18644   [(set_attr "type" "str")
18645    (set_attr "memory" "store")
18646    (set_attr "mode" "SI")])
18647
18648 (define_insn "*strsethi_1"
18649   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18650         (match_operand:HI 2 "register_operand" "a"))
18651    (set (match_operand:SI 0 "register_operand" "=D")
18652         (plus:SI (match_dup 1)
18653                  (const_int 2)))]
18654   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18655   "stosw"
18656   [(set_attr "type" "str")
18657    (set_attr "memory" "store")
18658    (set_attr "mode" "HI")])
18659
18660 (define_insn "*strsethi_rex_1"
18661   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18662         (match_operand:HI 2 "register_operand" "a"))
18663    (set (match_operand:DI 0 "register_operand" "=D")
18664         (plus:DI (match_dup 1)
18665                  (const_int 2)))]
18666   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18667   "stosw"
18668   [(set_attr "type" "str")
18669    (set_attr "memory" "store")
18670    (set_attr "mode" "HI")])
18671
18672 (define_insn "*strsetqi_1"
18673   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18674         (match_operand:QI 2 "register_operand" "a"))
18675    (set (match_operand:SI 0 "register_operand" "=D")
18676         (plus:SI (match_dup 1)
18677                  (const_int 1)))]
18678   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18679   "stosb"
18680   [(set_attr "type" "str")
18681    (set_attr "memory" "store")
18682    (set_attr "mode" "QI")])
18683
18684 (define_insn "*strsetqi_rex_1"
18685   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18686         (match_operand:QI 2 "register_operand" "a"))
18687    (set (match_operand:DI 0 "register_operand" "=D")
18688         (plus:DI (match_dup 1)
18689                  (const_int 1)))]
18690   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18691   "stosb"
18692   [(set_attr "type" "str")
18693    (set_attr "memory" "store")
18694    (set_attr "mode" "QI")])
18695
18696 (define_expand "rep_stos"
18697   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18698               (set (match_operand 0 "register_operand" "")
18699                    (match_operand 4 "" ""))
18700               (set (match_operand 2 "memory_operand" "") (const_int 0))
18701               (use (match_operand 3 "register_operand" ""))
18702               (use (match_dup 1))])]
18703   ""
18704   "")
18705
18706 (define_insn "*rep_stosdi_rex64"
18707   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18708    (set (match_operand:DI 0 "register_operand" "=D")
18709         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18710                             (const_int 3))
18711                  (match_operand:DI 3 "register_operand" "0")))
18712    (set (mem:BLK (match_dup 3))
18713         (const_int 0))
18714    (use (match_operand:DI 2 "register_operand" "a"))
18715    (use (match_dup 4))]
18716   "TARGET_64BIT"
18717   "{rep\;stosq|rep stosq}"
18718   [(set_attr "type" "str")
18719    (set_attr "prefix_rep" "1")
18720    (set_attr "memory" "store")
18721    (set_attr "mode" "DI")])
18722
18723 (define_insn "*rep_stossi"
18724   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18725    (set (match_operand:SI 0 "register_operand" "=D")
18726         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18727                             (const_int 2))
18728                  (match_operand:SI 3 "register_operand" "0")))
18729    (set (mem:BLK (match_dup 3))
18730         (const_int 0))
18731    (use (match_operand:SI 2 "register_operand" "a"))
18732    (use (match_dup 4))]
18733   "!TARGET_64BIT"
18734   "{rep\;stosl|rep stosd}"
18735   [(set_attr "type" "str")
18736    (set_attr "prefix_rep" "1")
18737    (set_attr "memory" "store")
18738    (set_attr "mode" "SI")])
18739
18740 (define_insn "*rep_stossi_rex64"
18741   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18742    (set (match_operand:DI 0 "register_operand" "=D")
18743         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18744                             (const_int 2))
18745                  (match_operand:DI 3 "register_operand" "0")))
18746    (set (mem:BLK (match_dup 3))
18747         (const_int 0))
18748    (use (match_operand:SI 2 "register_operand" "a"))
18749    (use (match_dup 4))]
18750   "TARGET_64BIT"
18751   "{rep\;stosl|rep stosd}"
18752   [(set_attr "type" "str")
18753    (set_attr "prefix_rep" "1")
18754    (set_attr "memory" "store")
18755    (set_attr "mode" "SI")])
18756
18757 (define_insn "*rep_stosqi"
18758   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18759    (set (match_operand:SI 0 "register_operand" "=D")
18760         (plus:SI (match_operand:SI 3 "register_operand" "0")
18761                  (match_operand:SI 4 "register_operand" "1")))
18762    (set (mem:BLK (match_dup 3))
18763         (const_int 0))
18764    (use (match_operand:QI 2 "register_operand" "a"))
18765    (use (match_dup 4))]
18766   "!TARGET_64BIT"
18767   "{rep\;stosb|rep stosb}"
18768   [(set_attr "type" "str")
18769    (set_attr "prefix_rep" "1")
18770    (set_attr "memory" "store")
18771    (set_attr "mode" "QI")])
18772
18773 (define_insn "*rep_stosqi_rex64"
18774   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18775    (set (match_operand:DI 0 "register_operand" "=D")
18776         (plus:DI (match_operand:DI 3 "register_operand" "0")
18777                  (match_operand:DI 4 "register_operand" "1")))
18778    (set (mem:BLK (match_dup 3))
18779         (const_int 0))
18780    (use (match_operand:QI 2 "register_operand" "a"))
18781    (use (match_dup 4))]
18782   "TARGET_64BIT"
18783   "{rep\;stosb|rep stosb}"
18784   [(set_attr "type" "str")
18785    (set_attr "prefix_rep" "1")
18786    (set_attr "memory" "store")
18787    (set_attr "mode" "QI")])
18788
18789 (define_expand "cmpstrnsi"
18790   [(set (match_operand:SI 0 "register_operand" "")
18791         (compare:SI (match_operand:BLK 1 "general_operand" "")
18792                     (match_operand:BLK 2 "general_operand" "")))
18793    (use (match_operand 3 "general_operand" ""))
18794    (use (match_operand 4 "immediate_operand" ""))]
18795   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18796 {
18797   rtx addr1, addr2, out, outlow, count, countreg, align;
18798
18799   /* Can't use this if the user has appropriated esi or edi.  */
18800   if (global_regs[4] || global_regs[5])
18801     FAIL;
18802
18803   out = operands[0];
18804   if (!REG_P (out))
18805     out = gen_reg_rtx (SImode);
18806
18807   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18808   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18809   if (addr1 != XEXP (operands[1], 0))
18810     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18811   if (addr2 != XEXP (operands[2], 0))
18812     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18813
18814   count = operands[3];
18815   countreg = ix86_zero_extend_to_Pmode (count);
18816
18817   /* %%% Iff we are testing strict equality, we can use known alignment
18818      to good advantage.  This may be possible with combine, particularly
18819      once cc0 is dead.  */
18820   align = operands[4];
18821
18822   if (CONST_INT_P (count))
18823     {
18824       if (INTVAL (count) == 0)
18825         {
18826           emit_move_insn (operands[0], const0_rtx);
18827           DONE;
18828         }
18829       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18830                                      operands[1], operands[2]));
18831     }
18832   else
18833     {
18834       if (TARGET_64BIT)
18835         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18836       else
18837         emit_insn (gen_cmpsi_1 (countreg, countreg));
18838       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18839                                   operands[1], operands[2]));
18840     }
18841
18842   outlow = gen_lowpart (QImode, out);
18843   emit_insn (gen_cmpintqi (outlow));
18844   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18845
18846   if (operands[0] != out)
18847     emit_move_insn (operands[0], out);
18848
18849   DONE;
18850 })
18851
18852 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18853
18854 (define_expand "cmpintqi"
18855   [(set (match_dup 1)
18856         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18857    (set (match_dup 2)
18858         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18859    (parallel [(set (match_operand:QI 0 "register_operand" "")
18860                    (minus:QI (match_dup 1)
18861                              (match_dup 2)))
18862               (clobber (reg:CC FLAGS_REG))])]
18863   ""
18864   "operands[1] = gen_reg_rtx (QImode);
18865    operands[2] = gen_reg_rtx (QImode);")
18866
18867 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18868 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18869
18870 (define_expand "cmpstrnqi_nz_1"
18871   [(parallel [(set (reg:CC FLAGS_REG)
18872                    (compare:CC (match_operand 4 "memory_operand" "")
18873                                (match_operand 5 "memory_operand" "")))
18874               (use (match_operand 2 "register_operand" ""))
18875               (use (match_operand:SI 3 "immediate_operand" ""))
18876               (clobber (match_operand 0 "register_operand" ""))
18877               (clobber (match_operand 1 "register_operand" ""))
18878               (clobber (match_dup 2))])]
18879   ""
18880   "")
18881
18882 (define_insn "*cmpstrnqi_nz_1"
18883   [(set (reg:CC FLAGS_REG)
18884         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18885                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18886    (use (match_operand:SI 6 "register_operand" "2"))
18887    (use (match_operand:SI 3 "immediate_operand" "i"))
18888    (clobber (match_operand:SI 0 "register_operand" "=S"))
18889    (clobber (match_operand:SI 1 "register_operand" "=D"))
18890    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18891   "!TARGET_64BIT"
18892   "repz{\;| }cmpsb"
18893   [(set_attr "type" "str")
18894    (set_attr "mode" "QI")
18895    (set_attr "prefix_rep" "1")])
18896
18897 (define_insn "*cmpstrnqi_nz_rex_1"
18898   [(set (reg:CC FLAGS_REG)
18899         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18900                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18901    (use (match_operand:DI 6 "register_operand" "2"))
18902    (use (match_operand:SI 3 "immediate_operand" "i"))
18903    (clobber (match_operand:DI 0 "register_operand" "=S"))
18904    (clobber (match_operand:DI 1 "register_operand" "=D"))
18905    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18906   "TARGET_64BIT"
18907   "repz{\;| }cmpsb"
18908   [(set_attr "type" "str")
18909    (set_attr "mode" "QI")
18910    (set_attr "prefix_rep" "1")])
18911
18912 ;; The same, but the count is not known to not be zero.
18913
18914 (define_expand "cmpstrnqi_1"
18915   [(parallel [(set (reg:CC FLAGS_REG)
18916                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18917                                      (const_int 0))
18918                   (compare:CC (match_operand 4 "memory_operand" "")
18919                               (match_operand 5 "memory_operand" ""))
18920                   (const_int 0)))
18921               (use (match_operand:SI 3 "immediate_operand" ""))
18922               (use (reg:CC FLAGS_REG))
18923               (clobber (match_operand 0 "register_operand" ""))
18924               (clobber (match_operand 1 "register_operand" ""))
18925               (clobber (match_dup 2))])]
18926   ""
18927   "")
18928
18929 (define_insn "*cmpstrnqi_1"
18930   [(set (reg:CC FLAGS_REG)
18931         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18932                              (const_int 0))
18933           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18934                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18935           (const_int 0)))
18936    (use (match_operand:SI 3 "immediate_operand" "i"))
18937    (use (reg:CC FLAGS_REG))
18938    (clobber (match_operand:SI 0 "register_operand" "=S"))
18939    (clobber (match_operand:SI 1 "register_operand" "=D"))
18940    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18941   "!TARGET_64BIT"
18942   "repz{\;| }cmpsb"
18943   [(set_attr "type" "str")
18944    (set_attr "mode" "QI")
18945    (set_attr "prefix_rep" "1")])
18946
18947 (define_insn "*cmpstrnqi_rex_1"
18948   [(set (reg:CC FLAGS_REG)
18949         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18950                              (const_int 0))
18951           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18952                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18953           (const_int 0)))
18954    (use (match_operand:SI 3 "immediate_operand" "i"))
18955    (use (reg:CC FLAGS_REG))
18956    (clobber (match_operand:DI 0 "register_operand" "=S"))
18957    (clobber (match_operand:DI 1 "register_operand" "=D"))
18958    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18959   "TARGET_64BIT"
18960   "repz{\;| }cmpsb"
18961   [(set_attr "type" "str")
18962    (set_attr "mode" "QI")
18963    (set_attr "prefix_rep" "1")])
18964
18965 (define_expand "strlensi"
18966   [(set (match_operand:SI 0 "register_operand" "")
18967         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18968                     (match_operand:QI 2 "immediate_operand" "")
18969                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18970   ""
18971 {
18972  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18973    DONE;
18974  else
18975    FAIL;
18976 })
18977
18978 (define_expand "strlendi"
18979   [(set (match_operand:DI 0 "register_operand" "")
18980         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18981                     (match_operand:QI 2 "immediate_operand" "")
18982                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18983   ""
18984 {
18985  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18986    DONE;
18987  else
18988    FAIL;
18989 })
18990
18991 (define_expand "strlenqi_1"
18992   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18993               (clobber (match_operand 1 "register_operand" ""))
18994               (clobber (reg:CC FLAGS_REG))])]
18995   ""
18996   "")
18997
18998 (define_insn "*strlenqi_1"
18999   [(set (match_operand:SI 0 "register_operand" "=&c")
19000         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19001                     (match_operand:QI 2 "register_operand" "a")
19002                     (match_operand:SI 3 "immediate_operand" "i")
19003                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19004    (clobber (match_operand:SI 1 "register_operand" "=D"))
19005    (clobber (reg:CC FLAGS_REG))]
19006   "!TARGET_64BIT"
19007   "repnz{\;| }scasb"
19008   [(set_attr "type" "str")
19009    (set_attr "mode" "QI")
19010    (set_attr "prefix_rep" "1")])
19011
19012 (define_insn "*strlenqi_rex_1"
19013   [(set (match_operand:DI 0 "register_operand" "=&c")
19014         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19015                     (match_operand:QI 2 "register_operand" "a")
19016                     (match_operand:DI 3 "immediate_operand" "i")
19017                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19018    (clobber (match_operand:DI 1 "register_operand" "=D"))
19019    (clobber (reg:CC FLAGS_REG))]
19020   "TARGET_64BIT"
19021   "repnz{\;| }scasb"
19022   [(set_attr "type" "str")
19023    (set_attr "mode" "QI")
19024    (set_attr "prefix_rep" "1")])
19025
19026 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19027 ;; handled in combine, but it is not currently up to the task.
19028 ;; When used for their truth value, the cmpstrn* expanders generate
19029 ;; code like this:
19030 ;;
19031 ;;   repz cmpsb
19032 ;;   seta       %al
19033 ;;   setb       %dl
19034 ;;   cmpb       %al, %dl
19035 ;;   jcc        label
19036 ;;
19037 ;; The intermediate three instructions are unnecessary.
19038
19039 ;; This one handles cmpstrn*_nz_1...
19040 (define_peephole2
19041   [(parallel[
19042      (set (reg:CC FLAGS_REG)
19043           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19044                       (mem:BLK (match_operand 5 "register_operand" ""))))
19045      (use (match_operand 6 "register_operand" ""))
19046      (use (match_operand:SI 3 "immediate_operand" ""))
19047      (clobber (match_operand 0 "register_operand" ""))
19048      (clobber (match_operand 1 "register_operand" ""))
19049      (clobber (match_operand 2 "register_operand" ""))])
19050    (set (match_operand:QI 7 "register_operand" "")
19051         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19052    (set (match_operand:QI 8 "register_operand" "")
19053         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19054    (set (reg FLAGS_REG)
19055         (compare (match_dup 7) (match_dup 8)))
19056   ]
19057   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19058   [(parallel[
19059      (set (reg:CC FLAGS_REG)
19060           (compare:CC (mem:BLK (match_dup 4))
19061                       (mem:BLK (match_dup 5))))
19062      (use (match_dup 6))
19063      (use (match_dup 3))
19064      (clobber (match_dup 0))
19065      (clobber (match_dup 1))
19066      (clobber (match_dup 2))])]
19067   "")
19068
19069 ;; ...and this one handles cmpstrn*_1.
19070 (define_peephole2
19071   [(parallel[
19072      (set (reg:CC FLAGS_REG)
19073           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19074                                (const_int 0))
19075             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19076                         (mem:BLK (match_operand 5 "register_operand" "")))
19077             (const_int 0)))
19078      (use (match_operand:SI 3 "immediate_operand" ""))
19079      (use (reg:CC FLAGS_REG))
19080      (clobber (match_operand 0 "register_operand" ""))
19081      (clobber (match_operand 1 "register_operand" ""))
19082      (clobber (match_operand 2 "register_operand" ""))])
19083    (set (match_operand:QI 7 "register_operand" "")
19084         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19085    (set (match_operand:QI 8 "register_operand" "")
19086         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19087    (set (reg FLAGS_REG)
19088         (compare (match_dup 7) (match_dup 8)))
19089   ]
19090   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19091   [(parallel[
19092      (set (reg:CC FLAGS_REG)
19093           (if_then_else:CC (ne (match_dup 6)
19094                                (const_int 0))
19095             (compare:CC (mem:BLK (match_dup 4))
19096                         (mem:BLK (match_dup 5)))
19097             (const_int 0)))
19098      (use (match_dup 3))
19099      (use (reg:CC FLAGS_REG))
19100      (clobber (match_dup 0))
19101      (clobber (match_dup 1))
19102      (clobber (match_dup 2))])]
19103   "")
19104
19105
19106 \f
19107 ;; Conditional move instructions.
19108
19109 (define_expand "movdicc"
19110   [(set (match_operand:DI 0 "register_operand" "")
19111         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19112                          (match_operand:DI 2 "general_operand" "")
19113                          (match_operand:DI 3 "general_operand" "")))]
19114   "TARGET_64BIT"
19115   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19116
19117 (define_insn "x86_movdicc_0_m1_rex64"
19118   [(set (match_operand:DI 0 "register_operand" "=r")
19119         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19120           (const_int -1)
19121           (const_int 0)))
19122    (clobber (reg:CC FLAGS_REG))]
19123   "TARGET_64BIT"
19124   "sbb{q}\t%0, %0"
19125   ; Since we don't have the proper number of operands for an alu insn,
19126   ; fill in all the blanks.
19127   [(set_attr "type" "alu")
19128    (set_attr "pent_pair" "pu")
19129    (set_attr "memory" "none")
19130    (set_attr "imm_disp" "false")
19131    (set_attr "mode" "DI")
19132    (set_attr "length_immediate" "0")])
19133
19134 (define_insn "*movdicc_c_rex64"
19135   [(set (match_operand:DI 0 "register_operand" "=r,r")
19136         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19137                                 [(reg FLAGS_REG) (const_int 0)])
19138                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19139                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19140   "TARGET_64BIT && TARGET_CMOVE
19141    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19142   "@
19143    cmov%O2%C1\t{%2, %0|%0, %2}
19144    cmov%O2%c1\t{%3, %0|%0, %3}"
19145   [(set_attr "type" "icmov")
19146    (set_attr "mode" "DI")])
19147
19148 (define_expand "movsicc"
19149   [(set (match_operand:SI 0 "register_operand" "")
19150         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19151                          (match_operand:SI 2 "general_operand" "")
19152                          (match_operand:SI 3 "general_operand" "")))]
19153   ""
19154   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19155
19156 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19157 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19158 ;; So just document what we're doing explicitly.
19159
19160 (define_insn "x86_movsicc_0_m1"
19161   [(set (match_operand:SI 0 "register_operand" "=r")
19162         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19163           (const_int -1)
19164           (const_int 0)))
19165    (clobber (reg:CC FLAGS_REG))]
19166   ""
19167   "sbb{l}\t%0, %0"
19168   ; Since we don't have the proper number of operands for an alu insn,
19169   ; fill in all the blanks.
19170   [(set_attr "type" "alu")
19171    (set_attr "pent_pair" "pu")
19172    (set_attr "memory" "none")
19173    (set_attr "imm_disp" "false")
19174    (set_attr "mode" "SI")
19175    (set_attr "length_immediate" "0")])
19176
19177 (define_insn "*movsicc_noc"
19178   [(set (match_operand:SI 0 "register_operand" "=r,r")
19179         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19180                                 [(reg FLAGS_REG) (const_int 0)])
19181                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19182                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19183   "TARGET_CMOVE
19184    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19185   "@
19186    cmov%O2%C1\t{%2, %0|%0, %2}
19187    cmov%O2%c1\t{%3, %0|%0, %3}"
19188   [(set_attr "type" "icmov")
19189    (set_attr "mode" "SI")])
19190
19191 (define_expand "movhicc"
19192   [(set (match_operand:HI 0 "register_operand" "")
19193         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19194                          (match_operand:HI 2 "general_operand" "")
19195                          (match_operand:HI 3 "general_operand" "")))]
19196   "TARGET_HIMODE_MATH"
19197   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19198
19199 (define_insn "*movhicc_noc"
19200   [(set (match_operand:HI 0 "register_operand" "=r,r")
19201         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19202                                 [(reg FLAGS_REG) (const_int 0)])
19203                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19204                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19205   "TARGET_CMOVE
19206    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19207   "@
19208    cmov%O2%C1\t{%2, %0|%0, %2}
19209    cmov%O2%c1\t{%3, %0|%0, %3}"
19210   [(set_attr "type" "icmov")
19211    (set_attr "mode" "HI")])
19212
19213 (define_expand "movqicc"
19214   [(set (match_operand:QI 0 "register_operand" "")
19215         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19216                          (match_operand:QI 2 "general_operand" "")
19217                          (match_operand:QI 3 "general_operand" "")))]
19218   "TARGET_QIMODE_MATH"
19219   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19220
19221 (define_insn_and_split "*movqicc_noc"
19222   [(set (match_operand:QI 0 "register_operand" "=r,r")
19223         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19224                                 [(match_operand 4 "flags_reg_operand" "")
19225                                  (const_int 0)])
19226                       (match_operand:QI 2 "register_operand" "r,0")
19227                       (match_operand:QI 3 "register_operand" "0,r")))]
19228   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19229   "#"
19230   "&& reload_completed"
19231   [(set (match_dup 0)
19232         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19233                       (match_dup 2)
19234                       (match_dup 3)))]
19235   "operands[0] = gen_lowpart (SImode, operands[0]);
19236    operands[2] = gen_lowpart (SImode, operands[2]);
19237    operands[3] = gen_lowpart (SImode, operands[3]);"
19238   [(set_attr "type" "icmov")
19239    (set_attr "mode" "SI")])
19240
19241 (define_expand "movsfcc"
19242   [(set (match_operand:SF 0 "register_operand" "")
19243         (if_then_else:SF (match_operand 1 "comparison_operator" "")
19244                          (match_operand:SF 2 "register_operand" "")
19245                          (match_operand:SF 3 "register_operand" "")))]
19246   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19247   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19248
19249 (define_insn "*movsfcc_1_387"
19250   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19251         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19252                                 [(reg FLAGS_REG) (const_int 0)])
19253                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19254                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19255   "TARGET_80387 && TARGET_CMOVE
19256    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19257   "@
19258    fcmov%F1\t{%2, %0|%0, %2}
19259    fcmov%f1\t{%3, %0|%0, %3}
19260    cmov%O2%C1\t{%2, %0|%0, %2}
19261    cmov%O2%c1\t{%3, %0|%0, %3}"
19262   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19263    (set_attr "mode" "SF,SF,SI,SI")])
19264
19265 (define_expand "movdfcc"
19266   [(set (match_operand:DF 0 "register_operand" "")
19267         (if_then_else:DF (match_operand 1 "comparison_operator" "")
19268                          (match_operand:DF 2 "register_operand" "")
19269                          (match_operand:DF 3 "register_operand" "")))]
19270   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19271   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19272
19273 (define_insn "*movdfcc_1"
19274   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19275         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19276                                 [(reg FLAGS_REG) (const_int 0)])
19277                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19278                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19279   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19280    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19281   "@
19282    fcmov%F1\t{%2, %0|%0, %2}
19283    fcmov%f1\t{%3, %0|%0, %3}
19284    #
19285    #"
19286   [(set_attr "type" "fcmov,fcmov,multi,multi")
19287    (set_attr "mode" "DF")])
19288
19289 (define_insn "*movdfcc_1_rex64"
19290   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19291         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19292                                 [(reg FLAGS_REG) (const_int 0)])
19293                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19294                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19295   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19296    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19297   "@
19298    fcmov%F1\t{%2, %0|%0, %2}
19299    fcmov%f1\t{%3, %0|%0, %3}
19300    cmov%O2%C1\t{%2, %0|%0, %2}
19301    cmov%O2%c1\t{%3, %0|%0, %3}"
19302   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19303    (set_attr "mode" "DF")])
19304
19305 (define_split
19306   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19307         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19308                                 [(match_operand 4 "flags_reg_operand" "")
19309                                  (const_int 0)])
19310                       (match_operand:DF 2 "nonimmediate_operand" "")
19311                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19312   "!TARGET_64BIT && reload_completed"
19313   [(set (match_dup 2)
19314         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19315                       (match_dup 5)
19316                       (match_dup 7)))
19317    (set (match_dup 3)
19318         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19319                       (match_dup 6)
19320                       (match_dup 8)))]
19321   "split_di (operands+2, 1, operands+5, operands+6);
19322    split_di (operands+3, 1, operands+7, operands+8);
19323    split_di (operands, 1, operands+2, operands+3);")
19324
19325 (define_expand "movxfcc"
19326   [(set (match_operand:XF 0 "register_operand" "")
19327         (if_then_else:XF (match_operand 1 "comparison_operator" "")
19328                          (match_operand:XF 2 "register_operand" "")
19329                          (match_operand:XF 3 "register_operand" "")))]
19330   "TARGET_80387 && TARGET_CMOVE"
19331   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19332
19333 (define_insn "*movxfcc_1"
19334   [(set (match_operand:XF 0 "register_operand" "=f,f")
19335         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19336                                 [(reg FLAGS_REG) (const_int 0)])
19337                       (match_operand:XF 2 "register_operand" "f,0")
19338                       (match_operand:XF 3 "register_operand" "0,f")))]
19339   "TARGET_80387 && TARGET_CMOVE"
19340   "@
19341    fcmov%F1\t{%2, %0|%0, %2}
19342    fcmov%f1\t{%3, %0|%0, %3}"
19343   [(set_attr "type" "fcmov")
19344    (set_attr "mode" "XF")])
19345
19346 ;; These versions of the min/max patterns are intentionally ignorant of
19347 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19348 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19349 ;; are undefined in this condition, we're certain this is correct.
19350
19351 (define_insn "sminsf3"
19352   [(set (match_operand:SF 0 "register_operand" "=x")
19353         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19354                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19355   "TARGET_SSE_MATH"
19356   "minss\t{%2, %0|%0, %2}"
19357   [(set_attr "type" "sseadd")
19358    (set_attr "mode" "SF")])
19359
19360 (define_insn "smaxsf3"
19361   [(set (match_operand:SF 0 "register_operand" "=x")
19362         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19363                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19364   "TARGET_SSE_MATH"
19365   "maxss\t{%2, %0|%0, %2}"
19366   [(set_attr "type" "sseadd")
19367    (set_attr "mode" "SF")])
19368
19369 (define_insn "smindf3"
19370   [(set (match_operand:DF 0 "register_operand" "=x")
19371         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19372                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19373   "TARGET_SSE2 && TARGET_SSE_MATH"
19374   "minsd\t{%2, %0|%0, %2}"
19375   [(set_attr "type" "sseadd")
19376    (set_attr "mode" "DF")])
19377
19378 (define_insn "smaxdf3"
19379   [(set (match_operand:DF 0 "register_operand" "=x")
19380         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19381                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19382   "TARGET_SSE2 && TARGET_SSE_MATH"
19383   "maxsd\t{%2, %0|%0, %2}"
19384   [(set_attr "type" "sseadd")
19385    (set_attr "mode" "DF")])
19386
19387 ;; These versions of the min/max patterns implement exactly the operations
19388 ;;   min = (op1 < op2 ? op1 : op2)
19389 ;;   max = (!(op1 < op2) ? op1 : op2)
19390 ;; Their operands are not commutative, and thus they may be used in the
19391 ;; presence of -0.0 and NaN.
19392
19393 (define_insn "*ieee_sminsf3"
19394   [(set (match_operand:SF 0 "register_operand" "=x")
19395         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19396                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19397                    UNSPEC_IEEE_MIN))]
19398   "TARGET_SSE_MATH"
19399   "minss\t{%2, %0|%0, %2}"
19400   [(set_attr "type" "sseadd")
19401    (set_attr "mode" "SF")])
19402
19403 (define_insn "*ieee_smaxsf3"
19404   [(set (match_operand:SF 0 "register_operand" "=x")
19405         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19406                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19407                    UNSPEC_IEEE_MAX))]
19408   "TARGET_SSE_MATH"
19409   "maxss\t{%2, %0|%0, %2}"
19410   [(set_attr "type" "sseadd")
19411    (set_attr "mode" "SF")])
19412
19413 (define_insn "*ieee_smindf3"
19414   [(set (match_operand:DF 0 "register_operand" "=x")
19415         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19416                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19417                    UNSPEC_IEEE_MIN))]
19418   "TARGET_SSE2 && TARGET_SSE_MATH"
19419   "minsd\t{%2, %0|%0, %2}"
19420   [(set_attr "type" "sseadd")
19421    (set_attr "mode" "DF")])
19422
19423 (define_insn "*ieee_smaxdf3"
19424   [(set (match_operand:DF 0 "register_operand" "=x")
19425         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19426                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19427                    UNSPEC_IEEE_MAX))]
19428   "TARGET_SSE2 && TARGET_SSE_MATH"
19429   "maxsd\t{%2, %0|%0, %2}"
19430   [(set_attr "type" "sseadd")
19431    (set_attr "mode" "DF")])
19432
19433 ;; Make two stack loads independent:
19434 ;;   fld aa              fld aa
19435 ;;   fld %st(0)     ->   fld bb
19436 ;;   fmul bb             fmul %st(1), %st
19437 ;;
19438 ;; Actually we only match the last two instructions for simplicity.
19439 (define_peephole2
19440   [(set (match_operand 0 "fp_register_operand" "")
19441         (match_operand 1 "fp_register_operand" ""))
19442    (set (match_dup 0)
19443         (match_operator 2 "binary_fp_operator"
19444            [(match_dup 0)
19445             (match_operand 3 "memory_operand" "")]))]
19446   "REGNO (operands[0]) != REGNO (operands[1])"
19447   [(set (match_dup 0) (match_dup 3))
19448    (set (match_dup 0) (match_dup 4))]
19449
19450   ;; The % modifier is not operational anymore in peephole2's, so we have to
19451   ;; swap the operands manually in the case of addition and multiplication.
19452   "if (COMMUTATIVE_ARITH_P (operands[2]))
19453      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19454                                  operands[0], operands[1]);
19455    else
19456      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19457                                  operands[1], operands[0]);")
19458
19459 ;; Conditional addition patterns
19460 (define_expand "addqicc"
19461   [(match_operand:QI 0 "register_operand" "")
19462    (match_operand 1 "comparison_operator" "")
19463    (match_operand:QI 2 "register_operand" "")
19464    (match_operand:QI 3 "const_int_operand" "")]
19465   ""
19466   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19467
19468 (define_expand "addhicc"
19469   [(match_operand:HI 0 "register_operand" "")
19470    (match_operand 1 "comparison_operator" "")
19471    (match_operand:HI 2 "register_operand" "")
19472    (match_operand:HI 3 "const_int_operand" "")]
19473   ""
19474   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19475
19476 (define_expand "addsicc"
19477   [(match_operand:SI 0 "register_operand" "")
19478    (match_operand 1 "comparison_operator" "")
19479    (match_operand:SI 2 "register_operand" "")
19480    (match_operand:SI 3 "const_int_operand" "")]
19481   ""
19482   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19483
19484 (define_expand "adddicc"
19485   [(match_operand:DI 0 "register_operand" "")
19486    (match_operand 1 "comparison_operator" "")
19487    (match_operand:DI 2 "register_operand" "")
19488    (match_operand:DI 3 "const_int_operand" "")]
19489   "TARGET_64BIT"
19490   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19491
19492 \f
19493 ;; Misc patterns (?)
19494
19495 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19496 ;; Otherwise there will be nothing to keep
19497 ;;
19498 ;; [(set (reg ebp) (reg esp))]
19499 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19500 ;;  (clobber (eflags)]
19501 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19502 ;;
19503 ;; in proper program order.
19504 (define_insn "pro_epilogue_adjust_stack_1"
19505   [(set (match_operand:SI 0 "register_operand" "=r,r")
19506         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19507                  (match_operand:SI 2 "immediate_operand" "i,i")))
19508    (clobber (reg:CC FLAGS_REG))
19509    (clobber (mem:BLK (scratch)))]
19510   "!TARGET_64BIT"
19511 {
19512   switch (get_attr_type (insn))
19513     {
19514     case TYPE_IMOV:
19515       return "mov{l}\t{%1, %0|%0, %1}";
19516
19517     case TYPE_ALU:
19518       if (CONST_INT_P (operands[2])
19519           && (INTVAL (operands[2]) == 128
19520               || (INTVAL (operands[2]) < 0
19521                   && INTVAL (operands[2]) != -128)))
19522         {
19523           operands[2] = GEN_INT (-INTVAL (operands[2]));
19524           return "sub{l}\t{%2, %0|%0, %2}";
19525         }
19526       return "add{l}\t{%2, %0|%0, %2}";
19527
19528     case TYPE_LEA:
19529       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19530       return "lea{l}\t{%a2, %0|%0, %a2}";
19531
19532     default:
19533       gcc_unreachable ();
19534     }
19535 }
19536   [(set (attr "type")
19537         (cond [(eq_attr "alternative" "0")
19538                  (const_string "alu")
19539                (match_operand:SI 2 "const0_operand" "")
19540                  (const_string "imov")
19541               ]
19542               (const_string "lea")))
19543    (set_attr "mode" "SI")])
19544
19545 (define_insn "pro_epilogue_adjust_stack_rex64"
19546   [(set (match_operand:DI 0 "register_operand" "=r,r")
19547         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19548                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19549    (clobber (reg:CC FLAGS_REG))
19550    (clobber (mem:BLK (scratch)))]
19551   "TARGET_64BIT"
19552 {
19553   switch (get_attr_type (insn))
19554     {
19555     case TYPE_IMOV:
19556       return "mov{q}\t{%1, %0|%0, %1}";
19557
19558     case TYPE_ALU:
19559       if (CONST_INT_P (operands[2])
19560           /* Avoid overflows.  */
19561           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19562           && (INTVAL (operands[2]) == 128
19563               || (INTVAL (operands[2]) < 0
19564                   && INTVAL (operands[2]) != -128)))
19565         {
19566           operands[2] = GEN_INT (-INTVAL (operands[2]));
19567           return "sub{q}\t{%2, %0|%0, %2}";
19568         }
19569       return "add{q}\t{%2, %0|%0, %2}";
19570
19571     case TYPE_LEA:
19572       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19573       return "lea{q}\t{%a2, %0|%0, %a2}";
19574
19575     default:
19576       gcc_unreachable ();
19577     }
19578 }
19579   [(set (attr "type")
19580         (cond [(eq_attr "alternative" "0")
19581                  (const_string "alu")
19582                (match_operand:DI 2 "const0_operand" "")
19583                  (const_string "imov")
19584               ]
19585               (const_string "lea")))
19586    (set_attr "mode" "DI")])
19587
19588 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19589   [(set (match_operand:DI 0 "register_operand" "=r,r")
19590         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19591                  (match_operand:DI 3 "immediate_operand" "i,i")))
19592    (use (match_operand:DI 2 "register_operand" "r,r"))
19593    (clobber (reg:CC FLAGS_REG))
19594    (clobber (mem:BLK (scratch)))]
19595   "TARGET_64BIT"
19596 {
19597   switch (get_attr_type (insn))
19598     {
19599     case TYPE_ALU:
19600       return "add{q}\t{%2, %0|%0, %2}";
19601
19602     case TYPE_LEA:
19603       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19604       return "lea{q}\t{%a2, %0|%0, %a2}";
19605
19606     default:
19607       gcc_unreachable ();
19608     }
19609 }
19610   [(set_attr "type" "alu,lea")
19611    (set_attr "mode" "DI")])
19612
19613 (define_expand "allocate_stack_worker"
19614   [(match_operand:SI 0 "register_operand" "")]
19615   "TARGET_STACK_PROBE"
19616 {
19617   if (reload_completed)
19618     {
19619       if (TARGET_64BIT)
19620         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19621       else
19622         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19623     }
19624   else
19625     {
19626       if (TARGET_64BIT)
19627         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19628       else
19629         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19630     }
19631   DONE;
19632 })
19633
19634 (define_insn "allocate_stack_worker_1"
19635   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19636     UNSPECV_STACK_PROBE)
19637    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19638    (clobber (match_scratch:SI 1 "=0"))
19639    (clobber (reg:CC FLAGS_REG))]
19640   "!TARGET_64BIT && TARGET_STACK_PROBE"
19641   "call\t__alloca"
19642   [(set_attr "type" "multi")
19643    (set_attr "length" "5")])
19644
19645 (define_expand "allocate_stack_worker_postreload"
19646   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19647                                     UNSPECV_STACK_PROBE)
19648               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19649               (clobber (match_dup 0))
19650               (clobber (reg:CC FLAGS_REG))])]
19651   ""
19652   "")
19653
19654 (define_insn "allocate_stack_worker_rex64"
19655   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19656     UNSPECV_STACK_PROBE)
19657    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19658    (clobber (match_scratch:DI 1 "=0"))
19659    (clobber (reg:CC FLAGS_REG))]
19660   "TARGET_64BIT && TARGET_STACK_PROBE"
19661   "call\t__alloca"
19662   [(set_attr "type" "multi")
19663    (set_attr "length" "5")])
19664
19665 (define_expand "allocate_stack_worker_rex64_postreload"
19666   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19667                                     UNSPECV_STACK_PROBE)
19668               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19669               (clobber (match_dup 0))
19670               (clobber (reg:CC FLAGS_REG))])]
19671   ""
19672   "")
19673
19674 (define_expand "allocate_stack"
19675   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19676                    (minus:SI (reg:SI SP_REG)
19677                              (match_operand:SI 1 "general_operand" "")))
19678               (clobber (reg:CC FLAGS_REG))])
19679    (parallel [(set (reg:SI SP_REG)
19680                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
19681               (clobber (reg:CC FLAGS_REG))])]
19682   "TARGET_STACK_PROBE"
19683 {
19684 #ifdef CHECK_STACK_LIMIT
19685   if (CONST_INT_P (operands[1])
19686       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19687     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19688                            operands[1]));
19689   else
19690 #endif
19691     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19692                                                             operands[1])));
19693
19694   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19695   DONE;
19696 })
19697
19698 (define_expand "builtin_setjmp_receiver"
19699   [(label_ref (match_operand 0 "" ""))]
19700   "!TARGET_64BIT && flag_pic"
19701 {
19702   if (TARGET_MACHO)
19703     {
19704       rtx xops[3];
19705       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19706       rtx label_rtx = gen_label_rtx ();
19707       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19708       xops[0] = xops[1] = picreg;
19709       xops[2] = gen_rtx_CONST (SImode,
19710                   gen_rtx_MINUS (SImode,
19711                     gen_rtx_LABEL_REF (SImode, label_rtx),
19712                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19713       ix86_expand_binary_operator (MINUS, SImode, xops);
19714     }
19715   else
19716     emit_insn (gen_set_got (pic_offset_table_rtx));
19717   DONE;
19718 })
19719 \f
19720 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19721
19722 (define_split
19723   [(set (match_operand 0 "register_operand" "")
19724         (match_operator 3 "promotable_binary_operator"
19725            [(match_operand 1 "register_operand" "")
19726             (match_operand 2 "aligned_operand" "")]))
19727    (clobber (reg:CC FLAGS_REG))]
19728   "! TARGET_PARTIAL_REG_STALL && reload_completed
19729    && ((GET_MODE (operands[0]) == HImode
19730         && ((!optimize_size && !TARGET_FAST_PREFIX)
19731             /* ??? next two lines just !satisfies_constraint_K (...) */
19732             || !CONST_INT_P (operands[2])
19733             || satisfies_constraint_K (operands[2])))
19734        || (GET_MODE (operands[0]) == QImode
19735            && (TARGET_PROMOTE_QImode || optimize_size)))"
19736   [(parallel [(set (match_dup 0)
19737                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19738               (clobber (reg:CC FLAGS_REG))])]
19739   "operands[0] = gen_lowpart (SImode, operands[0]);
19740    operands[1] = gen_lowpart (SImode, operands[1]);
19741    if (GET_CODE (operands[3]) != ASHIFT)
19742      operands[2] = gen_lowpart (SImode, operands[2]);
19743    PUT_MODE (operands[3], SImode);")
19744
19745 ; Promote the QImode tests, as i386 has encoding of the AND
19746 ; instruction with 32-bit sign-extended immediate and thus the
19747 ; instruction size is unchanged, except in the %eax case for
19748 ; which it is increased by one byte, hence the ! optimize_size.
19749 (define_split
19750   [(set (match_operand 0 "flags_reg_operand" "")
19751         (match_operator 2 "compare_operator"
19752           [(and (match_operand 3 "aligned_operand" "")
19753                 (match_operand 4 "const_int_operand" ""))
19754            (const_int 0)]))
19755    (set (match_operand 1 "register_operand" "")
19756         (and (match_dup 3) (match_dup 4)))]
19757   "! TARGET_PARTIAL_REG_STALL && reload_completed
19758    /* Ensure that the operand will remain sign-extended immediate.  */
19759    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19760    && ! optimize_size
19761    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19762        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19763   [(parallel [(set (match_dup 0)
19764                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19765                                     (const_int 0)]))
19766               (set (match_dup 1)
19767                    (and:SI (match_dup 3) (match_dup 4)))])]
19768 {
19769   operands[4]
19770     = gen_int_mode (INTVAL (operands[4])
19771                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19772   operands[1] = gen_lowpart (SImode, operands[1]);
19773   operands[3] = gen_lowpart (SImode, operands[3]);
19774 })
19775
19776 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19777 ; the TEST instruction with 32-bit sign-extended immediate and thus
19778 ; the instruction size would at least double, which is not what we
19779 ; want even with ! optimize_size.
19780 (define_split
19781   [(set (match_operand 0 "flags_reg_operand" "")
19782         (match_operator 1 "compare_operator"
19783           [(and (match_operand:HI 2 "aligned_operand" "")
19784                 (match_operand:HI 3 "const_int_operand" ""))
19785            (const_int 0)]))]
19786   "! TARGET_PARTIAL_REG_STALL && reload_completed
19787    /* Ensure that the operand will remain sign-extended immediate.  */
19788    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19789    && ! TARGET_FAST_PREFIX
19790    && ! optimize_size"
19791   [(set (match_dup 0)
19792         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19793                          (const_int 0)]))]
19794 {
19795   operands[3]
19796     = gen_int_mode (INTVAL (operands[3])
19797                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19798   operands[2] = gen_lowpart (SImode, operands[2]);
19799 })
19800
19801 (define_split
19802   [(set (match_operand 0 "register_operand" "")
19803         (neg (match_operand 1 "register_operand" "")))
19804    (clobber (reg:CC FLAGS_REG))]
19805   "! TARGET_PARTIAL_REG_STALL && reload_completed
19806    && (GET_MODE (operands[0]) == HImode
19807        || (GET_MODE (operands[0]) == QImode
19808            && (TARGET_PROMOTE_QImode || optimize_size)))"
19809   [(parallel [(set (match_dup 0)
19810                    (neg:SI (match_dup 1)))
19811               (clobber (reg:CC FLAGS_REG))])]
19812   "operands[0] = gen_lowpart (SImode, operands[0]);
19813    operands[1] = gen_lowpart (SImode, operands[1]);")
19814
19815 (define_split
19816   [(set (match_operand 0 "register_operand" "")
19817         (not (match_operand 1 "register_operand" "")))]
19818   "! TARGET_PARTIAL_REG_STALL && reload_completed
19819    && (GET_MODE (operands[0]) == HImode
19820        || (GET_MODE (operands[0]) == QImode
19821            && (TARGET_PROMOTE_QImode || optimize_size)))"
19822   [(set (match_dup 0)
19823         (not:SI (match_dup 1)))]
19824   "operands[0] = gen_lowpart (SImode, operands[0]);
19825    operands[1] = gen_lowpart (SImode, operands[1]);")
19826
19827 (define_split
19828   [(set (match_operand 0 "register_operand" "")
19829         (if_then_else (match_operator 1 "comparison_operator"
19830                                 [(reg FLAGS_REG) (const_int 0)])
19831                       (match_operand 2 "register_operand" "")
19832                       (match_operand 3 "register_operand" "")))]
19833   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19834    && (GET_MODE (operands[0]) == HImode
19835        || (GET_MODE (operands[0]) == QImode
19836            && (TARGET_PROMOTE_QImode || optimize_size)))"
19837   [(set (match_dup 0)
19838         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19839   "operands[0] = gen_lowpart (SImode, operands[0]);
19840    operands[2] = gen_lowpart (SImode, operands[2]);
19841    operands[3] = gen_lowpart (SImode, operands[3]);")
19842
19843 \f
19844 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19845 ;; transform a complex memory operation into two memory to register operations.
19846
19847 ;; Don't push memory operands
19848 (define_peephole2
19849   [(set (match_operand:SI 0 "push_operand" "")
19850         (match_operand:SI 1 "memory_operand" ""))
19851    (match_scratch:SI 2 "r")]
19852   "!optimize_size && !TARGET_PUSH_MEMORY
19853    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19854   [(set (match_dup 2) (match_dup 1))
19855    (set (match_dup 0) (match_dup 2))]
19856   "")
19857
19858 (define_peephole2
19859   [(set (match_operand:DI 0 "push_operand" "")
19860         (match_operand:DI 1 "memory_operand" ""))
19861    (match_scratch:DI 2 "r")]
19862   "!optimize_size && !TARGET_PUSH_MEMORY
19863    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19864   [(set (match_dup 2) (match_dup 1))
19865    (set (match_dup 0) (match_dup 2))]
19866   "")
19867
19868 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19869 ;; SImode pushes.
19870 (define_peephole2
19871   [(set (match_operand:SF 0 "push_operand" "")
19872         (match_operand:SF 1 "memory_operand" ""))
19873    (match_scratch:SF 2 "r")]
19874   "!optimize_size && !TARGET_PUSH_MEMORY
19875    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19876   [(set (match_dup 2) (match_dup 1))
19877    (set (match_dup 0) (match_dup 2))]
19878   "")
19879
19880 (define_peephole2
19881   [(set (match_operand:HI 0 "push_operand" "")
19882         (match_operand:HI 1 "memory_operand" ""))
19883    (match_scratch:HI 2 "r")]
19884   "!optimize_size && !TARGET_PUSH_MEMORY
19885    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19886   [(set (match_dup 2) (match_dup 1))
19887    (set (match_dup 0) (match_dup 2))]
19888   "")
19889
19890 (define_peephole2
19891   [(set (match_operand:QI 0 "push_operand" "")
19892         (match_operand:QI 1 "memory_operand" ""))
19893    (match_scratch:QI 2 "q")]
19894   "!optimize_size && !TARGET_PUSH_MEMORY
19895    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19896   [(set (match_dup 2) (match_dup 1))
19897    (set (match_dup 0) (match_dup 2))]
19898   "")
19899
19900 ;; Don't move an immediate directly to memory when the instruction
19901 ;; gets too big.
19902 (define_peephole2
19903   [(match_scratch:SI 1 "r")
19904    (set (match_operand:SI 0 "memory_operand" "")
19905         (const_int 0))]
19906   "! optimize_size
19907    && ! TARGET_USE_MOV0
19908    && TARGET_SPLIT_LONG_MOVES
19909    && get_attr_length (insn) >= ix86_cost->large_insn
19910    && peep2_regno_dead_p (0, FLAGS_REG)"
19911   [(parallel [(set (match_dup 1) (const_int 0))
19912               (clobber (reg:CC FLAGS_REG))])
19913    (set (match_dup 0) (match_dup 1))]
19914   "")
19915
19916 (define_peephole2
19917   [(match_scratch:HI 1 "r")
19918    (set (match_operand:HI 0 "memory_operand" "")
19919         (const_int 0))]
19920   "! optimize_size
19921    && ! TARGET_USE_MOV0
19922    && TARGET_SPLIT_LONG_MOVES
19923    && get_attr_length (insn) >= ix86_cost->large_insn
19924    && peep2_regno_dead_p (0, FLAGS_REG)"
19925   [(parallel [(set (match_dup 2) (const_int 0))
19926               (clobber (reg:CC FLAGS_REG))])
19927    (set (match_dup 0) (match_dup 1))]
19928   "operands[2] = gen_lowpart (SImode, operands[1]);")
19929
19930 (define_peephole2
19931   [(match_scratch:QI 1 "q")
19932    (set (match_operand:QI 0 "memory_operand" "")
19933         (const_int 0))]
19934   "! optimize_size
19935    && ! TARGET_USE_MOV0
19936    && TARGET_SPLIT_LONG_MOVES
19937    && get_attr_length (insn) >= ix86_cost->large_insn
19938    && peep2_regno_dead_p (0, FLAGS_REG)"
19939   [(parallel [(set (match_dup 2) (const_int 0))
19940               (clobber (reg:CC FLAGS_REG))])
19941    (set (match_dup 0) (match_dup 1))]
19942   "operands[2] = gen_lowpart (SImode, operands[1]);")
19943
19944 (define_peephole2
19945   [(match_scratch:SI 2 "r")
19946    (set (match_operand:SI 0 "memory_operand" "")
19947         (match_operand:SI 1 "immediate_operand" ""))]
19948   "! optimize_size
19949    && get_attr_length (insn) >= ix86_cost->large_insn
19950    && TARGET_SPLIT_LONG_MOVES"
19951   [(set (match_dup 2) (match_dup 1))
19952    (set (match_dup 0) (match_dup 2))]
19953   "")
19954
19955 (define_peephole2
19956   [(match_scratch:HI 2 "r")
19957    (set (match_operand:HI 0 "memory_operand" "")
19958         (match_operand:HI 1 "immediate_operand" ""))]
19959   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19960   && TARGET_SPLIT_LONG_MOVES"
19961   [(set (match_dup 2) (match_dup 1))
19962    (set (match_dup 0) (match_dup 2))]
19963   "")
19964
19965 (define_peephole2
19966   [(match_scratch:QI 2 "q")
19967    (set (match_operand:QI 0 "memory_operand" "")
19968         (match_operand:QI 1 "immediate_operand" ""))]
19969   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19970   && TARGET_SPLIT_LONG_MOVES"
19971   [(set (match_dup 2) (match_dup 1))
19972    (set (match_dup 0) (match_dup 2))]
19973   "")
19974
19975 ;; Don't compare memory with zero, load and use a test instead.
19976 (define_peephole2
19977   [(set (match_operand 0 "flags_reg_operand" "")
19978         (match_operator 1 "compare_operator"
19979           [(match_operand:SI 2 "memory_operand" "")
19980            (const_int 0)]))
19981    (match_scratch:SI 3 "r")]
19982   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19983   [(set (match_dup 3) (match_dup 2))
19984    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19985   "")
19986
19987 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19988 ;; Don't split NOTs with a displacement operand, because resulting XOR
19989 ;; will not be pairable anyway.
19990 ;;
19991 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19992 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19993 ;; so this split helps here as well.
19994 ;;
19995 ;; Note: Can't do this as a regular split because we can't get proper
19996 ;; lifetime information then.
19997
19998 (define_peephole2
19999   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20000         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20001   "!optimize_size
20002    && peep2_regno_dead_p (0, FLAGS_REG)
20003    && ((TARGET_PENTIUM
20004         && (!MEM_P (operands[0])
20005             || !memory_displacement_operand (operands[0], SImode)))
20006        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
20007   [(parallel [(set (match_dup 0)
20008                    (xor:SI (match_dup 1) (const_int -1)))
20009               (clobber (reg:CC FLAGS_REG))])]
20010   "")
20011
20012 (define_peephole2
20013   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20014         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20015   "!optimize_size
20016    && peep2_regno_dead_p (0, FLAGS_REG)
20017    && ((TARGET_PENTIUM
20018         && (!MEM_P (operands[0])
20019             || !memory_displacement_operand (operands[0], HImode)))
20020        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
20021   [(parallel [(set (match_dup 0)
20022                    (xor:HI (match_dup 1) (const_int -1)))
20023               (clobber (reg:CC FLAGS_REG))])]
20024   "")
20025
20026 (define_peephole2
20027   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20028         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20029   "!optimize_size
20030    && peep2_regno_dead_p (0, FLAGS_REG)
20031    && ((TARGET_PENTIUM
20032         && (!MEM_P (operands[0])
20033             || !memory_displacement_operand (operands[0], QImode)))
20034        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
20035   [(parallel [(set (match_dup 0)
20036                    (xor:QI (match_dup 1) (const_int -1)))
20037               (clobber (reg:CC FLAGS_REG))])]
20038   "")
20039
20040 ;; Non pairable "test imm, reg" instructions can be translated to
20041 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20042 ;; byte opcode instead of two, have a short form for byte operands),
20043 ;; so do it for other CPUs as well.  Given that the value was dead,
20044 ;; this should not create any new dependencies.  Pass on the sub-word
20045 ;; versions if we're concerned about partial register stalls.
20046
20047 (define_peephole2
20048   [(set (match_operand 0 "flags_reg_operand" "")
20049         (match_operator 1 "compare_operator"
20050           [(and:SI (match_operand:SI 2 "register_operand" "")
20051                    (match_operand:SI 3 "immediate_operand" ""))
20052            (const_int 0)]))]
20053   "ix86_match_ccmode (insn, CCNOmode)
20054    && (true_regnum (operands[2]) != 0
20055        || satisfies_constraint_K (operands[3]))
20056    && peep2_reg_dead_p (1, operands[2])"
20057   [(parallel
20058      [(set (match_dup 0)
20059            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20060                             (const_int 0)]))
20061       (set (match_dup 2)
20062            (and:SI (match_dup 2) (match_dup 3)))])]
20063   "")
20064
20065 ;; We don't need to handle HImode case, because it will be promoted to SImode
20066 ;; on ! TARGET_PARTIAL_REG_STALL
20067
20068 (define_peephole2
20069   [(set (match_operand 0 "flags_reg_operand" "")
20070         (match_operator 1 "compare_operator"
20071           [(and:QI (match_operand:QI 2 "register_operand" "")
20072                    (match_operand:QI 3 "immediate_operand" ""))
20073            (const_int 0)]))]
20074   "! TARGET_PARTIAL_REG_STALL
20075    && ix86_match_ccmode (insn, CCNOmode)
20076    && true_regnum (operands[2]) != 0
20077    && peep2_reg_dead_p (1, operands[2])"
20078   [(parallel
20079      [(set (match_dup 0)
20080            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20081                             (const_int 0)]))
20082       (set (match_dup 2)
20083            (and:QI (match_dup 2) (match_dup 3)))])]
20084   "")
20085
20086 (define_peephole2
20087   [(set (match_operand 0 "flags_reg_operand" "")
20088         (match_operator 1 "compare_operator"
20089           [(and:SI
20090              (zero_extract:SI
20091                (match_operand 2 "ext_register_operand" "")
20092                (const_int 8)
20093                (const_int 8))
20094              (match_operand 3 "const_int_operand" ""))
20095            (const_int 0)]))]
20096   "! TARGET_PARTIAL_REG_STALL
20097    && ix86_match_ccmode (insn, CCNOmode)
20098    && true_regnum (operands[2]) != 0
20099    && peep2_reg_dead_p (1, operands[2])"
20100   [(parallel [(set (match_dup 0)
20101                    (match_op_dup 1
20102                      [(and:SI
20103                         (zero_extract:SI
20104                           (match_dup 2)
20105                           (const_int 8)
20106                           (const_int 8))
20107                         (match_dup 3))
20108                       (const_int 0)]))
20109               (set (zero_extract:SI (match_dup 2)
20110                                     (const_int 8)
20111                                     (const_int 8))
20112                    (and:SI
20113                      (zero_extract:SI
20114                        (match_dup 2)
20115                        (const_int 8)
20116                        (const_int 8))
20117                      (match_dup 3)))])]
20118   "")
20119
20120 ;; Don't do logical operations with memory inputs.
20121 (define_peephole2
20122   [(match_scratch:SI 2 "r")
20123    (parallel [(set (match_operand:SI 0 "register_operand" "")
20124                    (match_operator:SI 3 "arith_or_logical_operator"
20125                      [(match_dup 0)
20126                       (match_operand:SI 1 "memory_operand" "")]))
20127               (clobber (reg:CC FLAGS_REG))])]
20128   "! optimize_size && ! TARGET_READ_MODIFY"
20129   [(set (match_dup 2) (match_dup 1))
20130    (parallel [(set (match_dup 0)
20131                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20132               (clobber (reg:CC FLAGS_REG))])]
20133   "")
20134
20135 (define_peephole2
20136   [(match_scratch:SI 2 "r")
20137    (parallel [(set (match_operand:SI 0 "register_operand" "")
20138                    (match_operator:SI 3 "arith_or_logical_operator"
20139                      [(match_operand:SI 1 "memory_operand" "")
20140                       (match_dup 0)]))
20141               (clobber (reg:CC FLAGS_REG))])]
20142   "! optimize_size && ! TARGET_READ_MODIFY"
20143   [(set (match_dup 2) (match_dup 1))
20144    (parallel [(set (match_dup 0)
20145                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20146               (clobber (reg:CC FLAGS_REG))])]
20147   "")
20148
20149 ; Don't do logical operations with memory outputs
20150 ;
20151 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20152 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20153 ; the same decoder scheduling characteristics as the original.
20154
20155 (define_peephole2
20156   [(match_scratch:SI 2 "r")
20157    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20158                    (match_operator:SI 3 "arith_or_logical_operator"
20159                      [(match_dup 0)
20160                       (match_operand:SI 1 "nonmemory_operand" "")]))
20161               (clobber (reg:CC FLAGS_REG))])]
20162   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20163   [(set (match_dup 2) (match_dup 0))
20164    (parallel [(set (match_dup 2)
20165                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20166               (clobber (reg:CC FLAGS_REG))])
20167    (set (match_dup 0) (match_dup 2))]
20168   "")
20169
20170 (define_peephole2
20171   [(match_scratch:SI 2 "r")
20172    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20173                    (match_operator:SI 3 "arith_or_logical_operator"
20174                      [(match_operand:SI 1 "nonmemory_operand" "")
20175                       (match_dup 0)]))
20176               (clobber (reg:CC FLAGS_REG))])]
20177   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20178   [(set (match_dup 2) (match_dup 0))
20179    (parallel [(set (match_dup 2)
20180                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20181               (clobber (reg:CC FLAGS_REG))])
20182    (set (match_dup 0) (match_dup 2))]
20183   "")
20184
20185 ;; Attempt to always use XOR for zeroing registers.
20186 (define_peephole2
20187   [(set (match_operand 0 "register_operand" "")
20188         (match_operand 1 "const0_operand" ""))]
20189   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20190    && (! TARGET_USE_MOV0 || optimize_size)
20191    && GENERAL_REG_P (operands[0])
20192    && peep2_regno_dead_p (0, FLAGS_REG)"
20193   [(parallel [(set (match_dup 0) (const_int 0))
20194               (clobber (reg:CC FLAGS_REG))])]
20195 {
20196   operands[0] = gen_lowpart (word_mode, operands[0]);
20197 })
20198
20199 (define_peephole2
20200   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20201         (const_int 0))]
20202   "(GET_MODE (operands[0]) == QImode
20203     || GET_MODE (operands[0]) == HImode)
20204    && (! TARGET_USE_MOV0 || optimize_size)
20205    && peep2_regno_dead_p (0, FLAGS_REG)"
20206   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20207               (clobber (reg:CC FLAGS_REG))])])
20208
20209 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20210 (define_peephole2
20211   [(set (match_operand 0 "register_operand" "")
20212         (const_int -1))]
20213   "(GET_MODE (operands[0]) == HImode
20214     || GET_MODE (operands[0]) == SImode
20215     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20216    && (optimize_size || TARGET_PENTIUM)
20217    && peep2_regno_dead_p (0, FLAGS_REG)"
20218   [(parallel [(set (match_dup 0) (const_int -1))
20219               (clobber (reg:CC FLAGS_REG))])]
20220   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20221                               operands[0]);")
20222
20223 ;; Attempt to convert simple leas to adds. These can be created by
20224 ;; move expanders.
20225 (define_peephole2
20226   [(set (match_operand:SI 0 "register_operand" "")
20227         (plus:SI (match_dup 0)
20228                  (match_operand:SI 1 "nonmemory_operand" "")))]
20229   "peep2_regno_dead_p (0, FLAGS_REG)"
20230   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20231               (clobber (reg:CC FLAGS_REG))])]
20232   "")
20233
20234 (define_peephole2
20235   [(set (match_operand:SI 0 "register_operand" "")
20236         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20237                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20238   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20239   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20240               (clobber (reg:CC FLAGS_REG))])]
20241   "operands[2] = gen_lowpart (SImode, operands[2]);")
20242
20243 (define_peephole2
20244   [(set (match_operand:DI 0 "register_operand" "")
20245         (plus:DI (match_dup 0)
20246                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20247   "peep2_regno_dead_p (0, FLAGS_REG)"
20248   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20249               (clobber (reg:CC FLAGS_REG))])]
20250   "")
20251
20252 (define_peephole2
20253   [(set (match_operand:SI 0 "register_operand" "")
20254         (mult:SI (match_dup 0)
20255                  (match_operand:SI 1 "const_int_operand" "")))]
20256   "exact_log2 (INTVAL (operands[1])) >= 0
20257    && peep2_regno_dead_p (0, FLAGS_REG)"
20258   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20259               (clobber (reg:CC FLAGS_REG))])]
20260   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20261
20262 (define_peephole2
20263   [(set (match_operand:DI 0 "register_operand" "")
20264         (mult:DI (match_dup 0)
20265                  (match_operand:DI 1 "const_int_operand" "")))]
20266   "exact_log2 (INTVAL (operands[1])) >= 0
20267    && peep2_regno_dead_p (0, FLAGS_REG)"
20268   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20269               (clobber (reg:CC FLAGS_REG))])]
20270   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20271
20272 (define_peephole2
20273   [(set (match_operand:SI 0 "register_operand" "")
20274         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20275                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20276   "exact_log2 (INTVAL (operands[2])) >= 0
20277    && REGNO (operands[0]) == REGNO (operands[1])
20278    && peep2_regno_dead_p (0, FLAGS_REG)"
20279   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20280               (clobber (reg:CC FLAGS_REG))])]
20281   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20282
20283 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20284 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20285 ;; many CPUs it is also faster, since special hardware to avoid esp
20286 ;; dependencies is present.
20287
20288 ;; While some of these conversions may be done using splitters, we use peepholes
20289 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20290
20291 ;; Convert prologue esp subtractions to push.
20292 ;; We need register to push.  In order to keep verify_flow_info happy we have
20293 ;; two choices
20294 ;; - use scratch and clobber it in order to avoid dependencies
20295 ;; - use already live register
20296 ;; We can't use the second way right now, since there is no reliable way how to
20297 ;; verify that given register is live.  First choice will also most likely in
20298 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20299 ;; call clobbered registers are dead.  We may want to use base pointer as an
20300 ;; alternative when no register is available later.
20301
20302 (define_peephole2
20303   [(match_scratch:SI 0 "r")
20304    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20305               (clobber (reg:CC FLAGS_REG))
20306               (clobber (mem:BLK (scratch)))])]
20307   "optimize_size || !TARGET_SUB_ESP_4"
20308   [(clobber (match_dup 0))
20309    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20310               (clobber (mem:BLK (scratch)))])])
20311
20312 (define_peephole2
20313   [(match_scratch:SI 0 "r")
20314    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20315               (clobber (reg:CC FLAGS_REG))
20316               (clobber (mem:BLK (scratch)))])]
20317   "optimize_size || !TARGET_SUB_ESP_8"
20318   [(clobber (match_dup 0))
20319    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20320    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20321               (clobber (mem:BLK (scratch)))])])
20322
20323 ;; Convert esp subtractions to push.
20324 (define_peephole2
20325   [(match_scratch:SI 0 "r")
20326    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20327               (clobber (reg:CC FLAGS_REG))])]
20328   "optimize_size || !TARGET_SUB_ESP_4"
20329   [(clobber (match_dup 0))
20330    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20331
20332 (define_peephole2
20333   [(match_scratch:SI 0 "r")
20334    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20335               (clobber (reg:CC FLAGS_REG))])]
20336   "optimize_size || !TARGET_SUB_ESP_8"
20337   [(clobber (match_dup 0))
20338    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20339    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20340
20341 ;; Convert epilogue deallocator to pop.
20342 (define_peephole2
20343   [(match_scratch:SI 0 "r")
20344    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20345               (clobber (reg:CC FLAGS_REG))
20346               (clobber (mem:BLK (scratch)))])]
20347   "optimize_size || !TARGET_ADD_ESP_4"
20348   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20349               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20350               (clobber (mem:BLK (scratch)))])]
20351   "")
20352
20353 ;; Two pops case is tricky, since pop causes dependency on destination register.
20354 ;; We use two registers if available.
20355 (define_peephole2
20356   [(match_scratch:SI 0 "r")
20357    (match_scratch:SI 1 "r")
20358    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20359               (clobber (reg:CC FLAGS_REG))
20360               (clobber (mem:BLK (scratch)))])]
20361   "optimize_size || !TARGET_ADD_ESP_8"
20362   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20363               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20364               (clobber (mem:BLK (scratch)))])
20365    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20366               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20367   "")
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               (clobber (mem:BLK (scratch)))])]
20374   "optimize_size"
20375   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20376               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20377               (clobber (mem:BLK (scratch)))])
20378    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20379               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20380   "")
20381
20382 ;; Convert esp additions to pop.
20383 (define_peephole2
20384   [(match_scratch:SI 0 "r")
20385    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20386               (clobber (reg:CC FLAGS_REG))])]
20387   ""
20388   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20389               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20390   "")
20391
20392 ;; Two pops case is tricky, since pop causes dependency on destination register.
20393 ;; We use two registers if available.
20394 (define_peephole2
20395   [(match_scratch:SI 0 "r")
20396    (match_scratch:SI 1 "r")
20397    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20398               (clobber (reg:CC FLAGS_REG))])]
20399   ""
20400   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20401               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
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   "optimize_size"
20411   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20412               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20413    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20414               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20415   "")
20416 \f
20417 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20418 ;; required and register dies.  Similarly for 128 to plus -128.
20419 (define_peephole2
20420   [(set (match_operand 0 "flags_reg_operand" "")
20421         (match_operator 1 "compare_operator"
20422           [(match_operand 2 "register_operand" "")
20423            (match_operand 3 "const_int_operand" "")]))]
20424   "(INTVAL (operands[3]) == -1
20425     || INTVAL (operands[3]) == 1
20426     || INTVAL (operands[3]) == 128)
20427    && ix86_match_ccmode (insn, CCGCmode)
20428    && peep2_reg_dead_p (1, operands[2])"
20429   [(parallel [(set (match_dup 0)
20430                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20431               (clobber (match_dup 2))])]
20432   "")
20433 \f
20434 (define_peephole2
20435   [(match_scratch:DI 0 "r")
20436    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20437               (clobber (reg:CC FLAGS_REG))
20438               (clobber (mem:BLK (scratch)))])]
20439   "optimize_size || !TARGET_SUB_ESP_4"
20440   [(clobber (match_dup 0))
20441    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20442               (clobber (mem:BLK (scratch)))])])
20443
20444 (define_peephole2
20445   [(match_scratch:DI 0 "r")
20446    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20447               (clobber (reg:CC FLAGS_REG))
20448               (clobber (mem:BLK (scratch)))])]
20449   "optimize_size || !TARGET_SUB_ESP_8"
20450   [(clobber (match_dup 0))
20451    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20452    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20453               (clobber (mem:BLK (scratch)))])])
20454
20455 ;; Convert esp subtractions to push.
20456 (define_peephole2
20457   [(match_scratch:DI 0 "r")
20458    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20459               (clobber (reg:CC FLAGS_REG))])]
20460   "optimize_size || !TARGET_SUB_ESP_4"
20461   [(clobber (match_dup 0))
20462    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20463
20464 (define_peephole2
20465   [(match_scratch:DI 0 "r")
20466    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20467               (clobber (reg:CC FLAGS_REG))])]
20468   "optimize_size || !TARGET_SUB_ESP_8"
20469   [(clobber (match_dup 0))
20470    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20471    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20472
20473 ;; Convert epilogue deallocator to pop.
20474 (define_peephole2
20475   [(match_scratch:DI 0 "r")
20476    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20477               (clobber (reg:CC FLAGS_REG))
20478               (clobber (mem:BLK (scratch)))])]
20479   "optimize_size || !TARGET_ADD_ESP_4"
20480   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20481               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20482               (clobber (mem:BLK (scratch)))])]
20483   "")
20484
20485 ;; Two pops case is tricky, since pop causes dependency on destination register.
20486 ;; We use two registers if available.
20487 (define_peephole2
20488   [(match_scratch:DI 0 "r")
20489    (match_scratch:DI 1 "r")
20490    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20491               (clobber (reg:CC FLAGS_REG))
20492               (clobber (mem:BLK (scratch)))])]
20493   "optimize_size || !TARGET_ADD_ESP_8"
20494   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20495               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20496               (clobber (mem:BLK (scratch)))])
20497    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20498               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20499   "")
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               (clobber (mem:BLK (scratch)))])]
20506   "optimize_size"
20507   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20508               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20509               (clobber (mem:BLK (scratch)))])
20510    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20511               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20512   "")
20513
20514 ;; Convert esp additions to pop.
20515 (define_peephole2
20516   [(match_scratch:DI 0 "r")
20517    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20518               (clobber (reg:CC FLAGS_REG))])]
20519   ""
20520   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20521               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20522   "")
20523
20524 ;; Two pops case is tricky, since pop causes dependency on destination register.
20525 ;; We use two registers if available.
20526 (define_peephole2
20527   [(match_scratch:DI 0 "r")
20528    (match_scratch:DI 1 "r")
20529    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20530               (clobber (reg:CC FLAGS_REG))])]
20531   ""
20532   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20533               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
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   "optimize_size"
20543   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20544               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20545    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20546               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20547   "")
20548 \f
20549 ;; Convert imul by three, five and nine into lea
20550 (define_peephole2
20551   [(parallel
20552     [(set (match_operand:SI 0 "register_operand" "")
20553           (mult:SI (match_operand:SI 1 "register_operand" "")
20554                    (match_operand:SI 2 "const_int_operand" "")))
20555      (clobber (reg:CC FLAGS_REG))])]
20556   "INTVAL (operands[2]) == 3
20557    || INTVAL (operands[2]) == 5
20558    || INTVAL (operands[2]) == 9"
20559   [(set (match_dup 0)
20560         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20561                  (match_dup 1)))]
20562   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20563
20564 (define_peephole2
20565   [(parallel
20566     [(set (match_operand:SI 0 "register_operand" "")
20567           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20568                    (match_operand:SI 2 "const_int_operand" "")))
20569      (clobber (reg:CC FLAGS_REG))])]
20570   "!optimize_size
20571    && (INTVAL (operands[2]) == 3
20572        || INTVAL (operands[2]) == 5
20573        || INTVAL (operands[2]) == 9)"
20574   [(set (match_dup 0) (match_dup 1))
20575    (set (match_dup 0)
20576         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20577                  (match_dup 0)))]
20578   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20579
20580 (define_peephole2
20581   [(parallel
20582     [(set (match_operand:DI 0 "register_operand" "")
20583           (mult:DI (match_operand:DI 1 "register_operand" "")
20584                    (match_operand:DI 2 "const_int_operand" "")))
20585      (clobber (reg:CC FLAGS_REG))])]
20586   "TARGET_64BIT
20587    && (INTVAL (operands[2]) == 3
20588        || INTVAL (operands[2]) == 5
20589        || INTVAL (operands[2]) == 9)"
20590   [(set (match_dup 0)
20591         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20592                  (match_dup 1)))]
20593   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20594
20595 (define_peephole2
20596   [(parallel
20597     [(set (match_operand:DI 0 "register_operand" "")
20598           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20599                    (match_operand:DI 2 "const_int_operand" "")))
20600      (clobber (reg:CC FLAGS_REG))])]
20601   "TARGET_64BIT
20602    && !optimize_size
20603    && (INTVAL (operands[2]) == 3
20604        || INTVAL (operands[2]) == 5
20605        || INTVAL (operands[2]) == 9)"
20606   [(set (match_dup 0) (match_dup 1))
20607    (set (match_dup 0)
20608         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20609                  (match_dup 0)))]
20610   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20611
20612 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20613 ;; imul $32bit_imm, reg, reg is direct decoded.
20614 (define_peephole2
20615   [(match_scratch:DI 3 "r")
20616    (parallel [(set (match_operand:DI 0 "register_operand" "")
20617                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20618                             (match_operand:DI 2 "immediate_operand" "")))
20619               (clobber (reg:CC FLAGS_REG))])]
20620   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20621    && !satisfies_constraint_K (operands[2])"
20622   [(set (match_dup 3) (match_dup 1))
20623    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20624               (clobber (reg:CC FLAGS_REG))])]
20625 "")
20626
20627 (define_peephole2
20628   [(match_scratch:SI 3 "r")
20629    (parallel [(set (match_operand:SI 0 "register_operand" "")
20630                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20631                             (match_operand:SI 2 "immediate_operand" "")))
20632               (clobber (reg:CC FLAGS_REG))])]
20633   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20634    && !satisfies_constraint_K (operands[2])"
20635   [(set (match_dup 3) (match_dup 1))
20636    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20637               (clobber (reg:CC FLAGS_REG))])]
20638 "")
20639
20640 (define_peephole2
20641   [(match_scratch:SI 3 "r")
20642    (parallel [(set (match_operand:DI 0 "register_operand" "")
20643                    (zero_extend:DI
20644                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20645                               (match_operand:SI 2 "immediate_operand" ""))))
20646               (clobber (reg:CC FLAGS_REG))])]
20647   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20648    && !satisfies_constraint_K (operands[2])"
20649   [(set (match_dup 3) (match_dup 1))
20650    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20651               (clobber (reg:CC FLAGS_REG))])]
20652 "")
20653
20654 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20655 ;; Convert it into imul reg, reg
20656 ;; It would be better to force assembler to encode instruction using long
20657 ;; immediate, but there is apparently no way to do so.
20658 (define_peephole2
20659   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20660                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20661                             (match_operand:DI 2 "const_int_operand" "")))
20662               (clobber (reg:CC FLAGS_REG))])
20663    (match_scratch:DI 3 "r")]
20664   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20665    && satisfies_constraint_K (operands[2])"
20666   [(set (match_dup 3) (match_dup 2))
20667    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20668               (clobber (reg:CC FLAGS_REG))])]
20669 {
20670   if (!rtx_equal_p (operands[0], operands[1]))
20671     emit_move_insn (operands[0], operands[1]);
20672 })
20673
20674 (define_peephole2
20675   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20676                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20677                             (match_operand:SI 2 "const_int_operand" "")))
20678               (clobber (reg:CC FLAGS_REG))])
20679    (match_scratch:SI 3 "r")]
20680   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20681    && satisfies_constraint_K (operands[2])"
20682   [(set (match_dup 3) (match_dup 2))
20683    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20684               (clobber (reg:CC FLAGS_REG))])]
20685 {
20686   if (!rtx_equal_p (operands[0], operands[1]))
20687     emit_move_insn (operands[0], operands[1]);
20688 })
20689
20690 (define_peephole2
20691   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20692                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20693                             (match_operand:HI 2 "immediate_operand" "")))
20694               (clobber (reg:CC FLAGS_REG))])
20695    (match_scratch:HI 3 "r")]
20696   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size"
20697   [(set (match_dup 3) (match_dup 2))
20698    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20699               (clobber (reg:CC FLAGS_REG))])]
20700 {
20701   if (!rtx_equal_p (operands[0], operands[1]))
20702     emit_move_insn (operands[0], operands[1]);
20703 })
20704
20705 ;; After splitting up read-modify operations, array accesses with memory
20706 ;; operands might end up in form:
20707 ;;  sall    $2, %eax
20708 ;;  movl    4(%esp), %edx
20709 ;;  addl    %edx, %eax
20710 ;; instead of pre-splitting:
20711 ;;  sall    $2, %eax
20712 ;;  addl    4(%esp), %eax
20713 ;; Turn it into:
20714 ;;  movl    4(%esp), %edx
20715 ;;  leal    (%edx,%eax,4), %eax
20716
20717 (define_peephole2
20718   [(parallel [(set (match_operand 0 "register_operand" "")
20719                    (ashift (match_operand 1 "register_operand" "")
20720                            (match_operand 2 "const_int_operand" "")))
20721                (clobber (reg:CC FLAGS_REG))])
20722    (set (match_operand 3 "register_operand")
20723         (match_operand 4 "x86_64_general_operand" ""))
20724    (parallel [(set (match_operand 5 "register_operand" "")
20725                    (plus (match_operand 6 "register_operand" "")
20726                          (match_operand 7 "register_operand" "")))
20727                    (clobber (reg:CC FLAGS_REG))])]
20728   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20729    /* Validate MODE for lea.  */
20730    && ((!TARGET_PARTIAL_REG_STALL
20731         && (GET_MODE (operands[0]) == QImode
20732             || GET_MODE (operands[0]) == HImode))
20733        || GET_MODE (operands[0]) == SImode
20734        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20735    /* We reorder load and the shift.  */
20736    && !rtx_equal_p (operands[1], operands[3])
20737    && !reg_overlap_mentioned_p (operands[0], operands[4])
20738    /* Last PLUS must consist of operand 0 and 3.  */
20739    && !rtx_equal_p (operands[0], operands[3])
20740    && (rtx_equal_p (operands[3], operands[6])
20741        || rtx_equal_p (operands[3], operands[7]))
20742    && (rtx_equal_p (operands[0], operands[6])
20743        || rtx_equal_p (operands[0], operands[7]))
20744    /* The intermediate operand 0 must die or be same as output.  */
20745    && (rtx_equal_p (operands[0], operands[5])
20746        || peep2_reg_dead_p (3, operands[0]))"
20747   [(set (match_dup 3) (match_dup 4))
20748    (set (match_dup 0) (match_dup 1))]
20749 {
20750   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20751   int scale = 1 << INTVAL (operands[2]);
20752   rtx index = gen_lowpart (Pmode, operands[1]);
20753   rtx base = gen_lowpart (Pmode, operands[3]);
20754   rtx dest = gen_lowpart (mode, operands[5]);
20755
20756   operands[1] = gen_rtx_PLUS (Pmode, base,
20757                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20758   if (mode != Pmode)
20759     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20760   operands[0] = dest;
20761 })
20762 \f
20763 ;; Call-value patterns last so that the wildcard operand does not
20764 ;; disrupt insn-recog's switch tables.
20765
20766 (define_insn "*call_value_pop_0"
20767   [(set (match_operand 0 "" "")
20768         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20769               (match_operand:SI 2 "" "")))
20770    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20771                             (match_operand:SI 3 "immediate_operand" "")))]
20772   "!TARGET_64BIT"
20773 {
20774   if (SIBLING_CALL_P (insn))
20775     return "jmp\t%P1";
20776   else
20777     return "call\t%P1";
20778 }
20779   [(set_attr "type" "callv")])
20780
20781 (define_insn "*call_value_pop_1"
20782   [(set (match_operand 0 "" "")
20783         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20784               (match_operand:SI 2 "" "")))
20785    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20786                             (match_operand:SI 3 "immediate_operand" "i")))]
20787   "!TARGET_64BIT"
20788 {
20789   if (constant_call_address_operand (operands[1], Pmode))
20790     {
20791       if (SIBLING_CALL_P (insn))
20792         return "jmp\t%P1";
20793       else
20794         return "call\t%P1";
20795     }
20796   if (SIBLING_CALL_P (insn))
20797     return "jmp\t%A1";
20798   else
20799     return "call\t%A1";
20800 }
20801   [(set_attr "type" "callv")])
20802
20803 (define_insn "*call_value_0"
20804   [(set (match_operand 0 "" "")
20805         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20806               (match_operand:SI 2 "" "")))]
20807   "!TARGET_64BIT"
20808 {
20809   if (SIBLING_CALL_P (insn))
20810     return "jmp\t%P1";
20811   else
20812     return "call\t%P1";
20813 }
20814   [(set_attr "type" "callv")])
20815
20816 (define_insn "*call_value_0_rex64"
20817   [(set (match_operand 0 "" "")
20818         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20819               (match_operand:DI 2 "const_int_operand" "")))]
20820   "TARGET_64BIT"
20821 {
20822   if (SIBLING_CALL_P (insn))
20823     return "jmp\t%P1";
20824   else
20825     return "call\t%P1";
20826 }
20827   [(set_attr "type" "callv")])
20828
20829 (define_insn "*call_value_1"
20830   [(set (match_operand 0 "" "")
20831         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20832               (match_operand:SI 2 "" "")))]
20833   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20834 {
20835   if (constant_call_address_operand (operands[1], Pmode))
20836     return "call\t%P1";
20837   return "call\t%A1";
20838 }
20839   [(set_attr "type" "callv")])
20840
20841 (define_insn "*sibcall_value_1"
20842   [(set (match_operand 0 "" "")
20843         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20844               (match_operand:SI 2 "" "")))]
20845   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20846 {
20847   if (constant_call_address_operand (operands[1], Pmode))
20848     return "jmp\t%P1";
20849   return "jmp\t%A1";
20850 }
20851   [(set_attr "type" "callv")])
20852
20853 (define_insn "*call_value_1_rex64"
20854   [(set (match_operand 0 "" "")
20855         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20856               (match_operand:DI 2 "" "")))]
20857   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20858 {
20859   if (constant_call_address_operand (operands[1], Pmode))
20860     return "call\t%P1";
20861   return "call\t%A1";
20862 }
20863   [(set_attr "type" "callv")])
20864
20865 (define_insn "*sibcall_value_1_rex64"
20866   [(set (match_operand 0 "" "")
20867         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20868               (match_operand:DI 2 "" "")))]
20869   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20870   "jmp\t%P1"
20871   [(set_attr "type" "callv")])
20872
20873 (define_insn "*sibcall_value_1_rex64_v"
20874   [(set (match_operand 0 "" "")
20875         (call (mem:QI (reg:DI R11_REG))
20876               (match_operand:DI 1 "" "")))]
20877   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20878   "jmp\t*%%r11"
20879   [(set_attr "type" "callv")])
20880 \f
20881 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20882 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20883 ;; caught for use by garbage collectors and the like.  Using an insn that
20884 ;; maps to SIGILL makes it more likely the program will rightfully die.
20885 ;; Keeping with tradition, "6" is in honor of #UD.
20886 (define_insn "trap"
20887   [(trap_if (const_int 1) (const_int 6))]
20888   ""
20889   { return ASM_SHORT "0x0b0f"; }
20890   [(set_attr "length" "2")])
20891
20892 (define_expand "sse_prologue_save"
20893   [(parallel [(set (match_operand:BLK 0 "" "")
20894                    (unspec:BLK [(reg:DI 21)
20895                                 (reg:DI 22)
20896                                 (reg:DI 23)
20897                                 (reg:DI 24)
20898                                 (reg:DI 25)
20899                                 (reg:DI 26)
20900                                 (reg:DI 27)
20901                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20902               (use (match_operand:DI 1 "register_operand" ""))
20903               (use (match_operand:DI 2 "immediate_operand" ""))
20904               (use (label_ref:DI (match_operand 3 "" "")))])]
20905   "TARGET_64BIT"
20906   "")
20907
20908 (define_insn "*sse_prologue_save_insn"
20909   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20910                           (match_operand:DI 4 "const_int_operand" "n")))
20911         (unspec:BLK [(reg:DI 21)
20912                      (reg:DI 22)
20913                      (reg:DI 23)
20914                      (reg:DI 24)
20915                      (reg:DI 25)
20916                      (reg:DI 26)
20917                      (reg:DI 27)
20918                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20919    (use (match_operand:DI 1 "register_operand" "r"))
20920    (use (match_operand:DI 2 "const_int_operand" "i"))
20921    (use (label_ref:DI (match_operand 3 "" "X")))]
20922   "TARGET_64BIT
20923    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20924    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20925   "*
20926 {
20927   int i;
20928   operands[0] = gen_rtx_MEM (Pmode,
20929                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20930   output_asm_insn (\"jmp\\t%A1\", operands);
20931   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20932     {
20933       operands[4] = adjust_address (operands[0], DImode, i*16);
20934       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20935       PUT_MODE (operands[4], TImode);
20936       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20937         output_asm_insn (\"rex\", operands);
20938       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20939     }
20940   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20941                              CODE_LABEL_NUMBER (operands[3]));
20942   return \"\";
20943 }
20944   "
20945   [(set_attr "type" "other")
20946    (set_attr "length_immediate" "0")
20947    (set_attr "length_address" "0")
20948    (set_attr "length" "135")
20949    (set_attr "memory" "store")
20950    (set_attr "modrm" "0")
20951    (set_attr "mode" "DI")])
20952
20953 (define_expand "prefetch"
20954   [(prefetch (match_operand 0 "address_operand" "")
20955              (match_operand:SI 1 "const_int_operand" "")
20956              (match_operand:SI 2 "const_int_operand" ""))]
20957   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20958 {
20959   int rw = INTVAL (operands[1]);
20960   int locality = INTVAL (operands[2]);
20961
20962   gcc_assert (rw == 0 || rw == 1);
20963   gcc_assert (locality >= 0 && locality <= 3);
20964   gcc_assert (GET_MODE (operands[0]) == Pmode
20965               || GET_MODE (operands[0]) == VOIDmode);
20966
20967   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20968      supported by SSE counterpart or the SSE prefetch is not available
20969      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20970      of locality.  */
20971   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20972     operands[2] = GEN_INT (3);
20973   else
20974     operands[1] = const0_rtx;
20975 })
20976
20977 (define_insn "*prefetch_sse"
20978   [(prefetch (match_operand:SI 0 "address_operand" "p")
20979              (const_int 0)
20980              (match_operand:SI 1 "const_int_operand" ""))]
20981   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20982 {
20983   static const char * const patterns[4] = {
20984    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20985   };
20986
20987   int locality = INTVAL (operands[1]);
20988   gcc_assert (locality >= 0 && locality <= 3);
20989
20990   return patterns[locality];
20991 }
20992   [(set_attr "type" "sse")
20993    (set_attr "memory" "none")])
20994
20995 (define_insn "*prefetch_sse_rex"
20996   [(prefetch (match_operand:DI 0 "address_operand" "p")
20997              (const_int 0)
20998              (match_operand:SI 1 "const_int_operand" ""))]
20999   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21000 {
21001   static const char * const patterns[4] = {
21002    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21003   };
21004
21005   int locality = INTVAL (operands[1]);
21006   gcc_assert (locality >= 0 && locality <= 3);
21007
21008   return patterns[locality];
21009 }
21010   [(set_attr "type" "sse")
21011    (set_attr "memory" "none")])
21012
21013 (define_insn "*prefetch_3dnow"
21014   [(prefetch (match_operand:SI 0 "address_operand" "p")
21015              (match_operand:SI 1 "const_int_operand" "n")
21016              (const_int 3))]
21017   "TARGET_3DNOW && !TARGET_64BIT"
21018 {
21019   if (INTVAL (operands[1]) == 0)
21020     return "prefetch\t%a0";
21021   else
21022     return "prefetchw\t%a0";
21023 }
21024   [(set_attr "type" "mmx")
21025    (set_attr "memory" "none")])
21026
21027 (define_insn "*prefetch_3dnow_rex"
21028   [(prefetch (match_operand:DI 0 "address_operand" "p")
21029              (match_operand:SI 1 "const_int_operand" "n")
21030              (const_int 3))]
21031   "TARGET_3DNOW && TARGET_64BIT"
21032 {
21033   if (INTVAL (operands[1]) == 0)
21034     return "prefetch\t%a0";
21035   else
21036     return "prefetchw\t%a0";
21037 }
21038   [(set_attr "type" "mmx")
21039    (set_attr "memory" "none")])
21040
21041 (define_expand "stack_protect_set"
21042   [(match_operand 0 "memory_operand" "")
21043    (match_operand 1 "memory_operand" "")]
21044   ""
21045 {
21046 #ifdef TARGET_THREAD_SSP_OFFSET
21047   if (TARGET_64BIT)
21048     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21049                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21050   else
21051     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21052                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21053 #else
21054   if (TARGET_64BIT)
21055     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21056   else
21057     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21058 #endif
21059   DONE;
21060 })
21061
21062 (define_insn "stack_protect_set_si"
21063   [(set (match_operand:SI 0 "memory_operand" "=m")
21064         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21065    (set (match_scratch:SI 2 "=&r") (const_int 0))
21066    (clobber (reg:CC FLAGS_REG))]
21067   ""
21068   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21069   [(set_attr "type" "multi")])
21070
21071 (define_insn "stack_protect_set_di"
21072   [(set (match_operand:DI 0 "memory_operand" "=m")
21073         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21074    (set (match_scratch:DI 2 "=&r") (const_int 0))
21075    (clobber (reg:CC FLAGS_REG))]
21076   "TARGET_64BIT"
21077   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21078   [(set_attr "type" "multi")])
21079
21080 (define_insn "stack_tls_protect_set_si"
21081   [(set (match_operand:SI 0 "memory_operand" "=m")
21082         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21083    (set (match_scratch:SI 2 "=&r") (const_int 0))
21084    (clobber (reg:CC FLAGS_REG))]
21085   ""
21086   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21087   [(set_attr "type" "multi")])
21088
21089 (define_insn "stack_tls_protect_set_di"
21090   [(set (match_operand:DI 0 "memory_operand" "=m")
21091         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21092    (set (match_scratch:DI 2 "=&r") (const_int 0))
21093    (clobber (reg:CC FLAGS_REG))]
21094   "TARGET_64BIT"
21095   {
21096      /* The kernel uses a different segment register for performance reasons; a
21097         system call would not have to trash the userspace segment register,
21098         which would be expensive */
21099      if (ix86_cmodel != CM_KERNEL)
21100         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21101      else
21102         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21103   }
21104   [(set_attr "type" "multi")])
21105
21106 (define_expand "stack_protect_test"
21107   [(match_operand 0 "memory_operand" "")
21108    (match_operand 1 "memory_operand" "")
21109    (match_operand 2 "" "")]
21110   ""
21111 {
21112   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21113   ix86_compare_op0 = operands[0];
21114   ix86_compare_op1 = operands[1];
21115   ix86_compare_emitted = flags;
21116
21117 #ifdef TARGET_THREAD_SSP_OFFSET
21118   if (TARGET_64BIT)
21119     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21120                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21121   else
21122     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21123                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21124 #else
21125   if (TARGET_64BIT)
21126     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21127   else
21128     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21129 #endif
21130   emit_jump_insn (gen_beq (operands[2]));
21131   DONE;
21132 })
21133
21134 (define_insn "stack_protect_test_si"
21135   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21136         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21137                      (match_operand:SI 2 "memory_operand" "m")]
21138                     UNSPEC_SP_TEST))
21139    (clobber (match_scratch:SI 3 "=&r"))]
21140   ""
21141   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21142   [(set_attr "type" "multi")])
21143
21144 (define_insn "stack_protect_test_di"
21145   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21146         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21147                      (match_operand:DI 2 "memory_operand" "m")]
21148                     UNSPEC_SP_TEST))
21149    (clobber (match_scratch:DI 3 "=&r"))]
21150   "TARGET_64BIT"
21151   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21152   [(set_attr "type" "multi")])
21153
21154 (define_insn "stack_tls_protect_test_si"
21155   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21156         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21157                      (match_operand:SI 2 "const_int_operand" "i")]
21158                     UNSPEC_SP_TLS_TEST))
21159    (clobber (match_scratch:SI 3 "=r"))]
21160   ""
21161   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21162   [(set_attr "type" "multi")])
21163
21164 (define_insn "stack_tls_protect_test_di"
21165   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21166         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21167                      (match_operand:DI 2 "const_int_operand" "i")]
21168                     UNSPEC_SP_TLS_TEST))
21169    (clobber (match_scratch:DI 3 "=r"))]
21170   "TARGET_64BIT"
21171   {
21172      /* The kernel uses a different segment register for performance reasons; a
21173         system call would not have to trash the userspace segment register,
21174         which would be expensive */
21175      if (ix86_cmodel != CM_KERNEL)
21176         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21177      else
21178         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21179   }
21180   [(set_attr "type" "multi")])
21181
21182 (include "mmx.md")
21183 (include "sse.md")
21184 (include "sync.md")