OSDN Git Service

amdfam10
[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 \f
492 ;; Scheduling descriptions
493
494 (include "pentium.md")
495 (include "ppro.md")
496 (include "k6.md")
497 (include "athlon.md")
498 (include "geode.md")
499
500 \f
501 ;; Operand and operator predicates and constraints
502
503 (include "predicates.md")
504 (include "constraints.md")
505
506 \f
507 ;; Compare instructions.
508
509 ;; All compare insns have expanders that save the operands away without
510 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
511 ;; after the cmp) will actually emit the cmpM.
512
513 (define_expand "cmpti"
514   [(set (reg:CC FLAGS_REG)
515         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
516                     (match_operand:TI 1 "x86_64_general_operand" "")))]
517   "TARGET_64BIT"
518 {
519   if (MEM_P (operands[0]) && MEM_P (operands[1]))
520     operands[0] = force_reg (TImode, operands[0]);
521   ix86_compare_op0 = operands[0];
522   ix86_compare_op1 = operands[1];
523   DONE;
524 })
525
526 (define_expand "cmpdi"
527   [(set (reg:CC FLAGS_REG)
528         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
529                     (match_operand:DI 1 "x86_64_general_operand" "")))]
530   ""
531 {
532   if (MEM_P (operands[0]) && MEM_P (operands[1]))
533     operands[0] = force_reg (DImode, operands[0]);
534   ix86_compare_op0 = operands[0];
535   ix86_compare_op1 = operands[1];
536   DONE;
537 })
538
539 (define_expand "cmpsi"
540   [(set (reg:CC FLAGS_REG)
541         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
542                     (match_operand:SI 1 "general_operand" "")))]
543   ""
544 {
545   if (MEM_P (operands[0]) && MEM_P (operands[1]))
546     operands[0] = force_reg (SImode, operands[0]);
547   ix86_compare_op0 = operands[0];
548   ix86_compare_op1 = operands[1];
549   DONE;
550 })
551
552 (define_expand "cmphi"
553   [(set (reg:CC FLAGS_REG)
554         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
555                     (match_operand:HI 1 "general_operand" "")))]
556   ""
557 {
558   if (MEM_P (operands[0]) && MEM_P (operands[1]))
559     operands[0] = force_reg (HImode, operands[0]);
560   ix86_compare_op0 = operands[0];
561   ix86_compare_op1 = operands[1];
562   DONE;
563 })
564
565 (define_expand "cmpqi"
566   [(set (reg:CC FLAGS_REG)
567         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
568                     (match_operand:QI 1 "general_operand" "")))]
569   "TARGET_QIMODE_MATH"
570 {
571   if (MEM_P (operands[0]) && MEM_P (operands[1]))
572     operands[0] = force_reg (QImode, operands[0]);
573   ix86_compare_op0 = operands[0];
574   ix86_compare_op1 = operands[1];
575   DONE;
576 })
577
578 (define_insn "cmpdi_ccno_1_rex64"
579   [(set (reg FLAGS_REG)
580         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
581                  (match_operand:DI 1 "const0_operand" "n,n")))]
582   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
583   "@
584    test{q}\t{%0, %0|%0, %0}
585    cmp{q}\t{%1, %0|%0, %1}"
586   [(set_attr "type" "test,icmp")
587    (set_attr "length_immediate" "0,1")
588    (set_attr "mode" "DI")])
589
590 (define_insn "*cmpdi_minus_1_rex64"
591   [(set (reg FLAGS_REG)
592         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
593                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
594                  (const_int 0)))]
595   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
596   "cmp{q}\t{%1, %0|%0, %1}"
597   [(set_attr "type" "icmp")
598    (set_attr "mode" "DI")])
599
600 (define_expand "cmpdi_1_rex64"
601   [(set (reg:CC FLAGS_REG)
602         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
603                     (match_operand:DI 1 "general_operand" "")))]
604   "TARGET_64BIT"
605   "")
606
607 (define_insn "cmpdi_1_insn_rex64"
608   [(set (reg FLAGS_REG)
609         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
610                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
611   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
612   "cmp{q}\t{%1, %0|%0, %1}"
613   [(set_attr "type" "icmp")
614    (set_attr "mode" "DI")])
615
616
617 (define_insn "*cmpsi_ccno_1"
618   [(set (reg FLAGS_REG)
619         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
620                  (match_operand:SI 1 "const0_operand" "n,n")))]
621   "ix86_match_ccmode (insn, CCNOmode)"
622   "@
623    test{l}\t{%0, %0|%0, %0}
624    cmp{l}\t{%1, %0|%0, %1}"
625   [(set_attr "type" "test,icmp")
626    (set_attr "length_immediate" "0,1")
627    (set_attr "mode" "SI")])
628
629 (define_insn "*cmpsi_minus_1"
630   [(set (reg FLAGS_REG)
631         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
632                            (match_operand:SI 1 "general_operand" "ri,mr"))
633                  (const_int 0)))]
634   "ix86_match_ccmode (insn, CCGOCmode)"
635   "cmp{l}\t{%1, %0|%0, %1}"
636   [(set_attr "type" "icmp")
637    (set_attr "mode" "SI")])
638
639 (define_expand "cmpsi_1"
640   [(set (reg:CC FLAGS_REG)
641         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
642                     (match_operand:SI 1 "general_operand" "ri,mr")))]
643   ""
644   "")
645
646 (define_insn "*cmpsi_1_insn"
647   [(set (reg FLAGS_REG)
648         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
649                  (match_operand:SI 1 "general_operand" "ri,mr")))]
650   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
651     && ix86_match_ccmode (insn, CCmode)"
652   "cmp{l}\t{%1, %0|%0, %1}"
653   [(set_attr "type" "icmp")
654    (set_attr "mode" "SI")])
655
656 (define_insn "*cmphi_ccno_1"
657   [(set (reg FLAGS_REG)
658         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
659                  (match_operand:HI 1 "const0_operand" "n,n")))]
660   "ix86_match_ccmode (insn, CCNOmode)"
661   "@
662    test{w}\t{%0, %0|%0, %0}
663    cmp{w}\t{%1, %0|%0, %1}"
664   [(set_attr "type" "test,icmp")
665    (set_attr "length_immediate" "0,1")
666    (set_attr "mode" "HI")])
667
668 (define_insn "*cmphi_minus_1"
669   [(set (reg FLAGS_REG)
670         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
671                            (match_operand:HI 1 "general_operand" "ri,mr"))
672                  (const_int 0)))]
673   "ix86_match_ccmode (insn, CCGOCmode)"
674   "cmp{w}\t{%1, %0|%0, %1}"
675   [(set_attr "type" "icmp")
676    (set_attr "mode" "HI")])
677
678 (define_insn "*cmphi_1"
679   [(set (reg FLAGS_REG)
680         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
681                  (match_operand:HI 1 "general_operand" "ri,mr")))]
682   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
683    && ix86_match_ccmode (insn, CCmode)"
684   "cmp{w}\t{%1, %0|%0, %1}"
685   [(set_attr "type" "icmp")
686    (set_attr "mode" "HI")])
687
688 (define_insn "*cmpqi_ccno_1"
689   [(set (reg FLAGS_REG)
690         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
691                  (match_operand:QI 1 "const0_operand" "n,n")))]
692   "ix86_match_ccmode (insn, CCNOmode)"
693   "@
694    test{b}\t{%0, %0|%0, %0}
695    cmp{b}\t{$0, %0|%0, 0}"
696   [(set_attr "type" "test,icmp")
697    (set_attr "length_immediate" "0,1")
698    (set_attr "mode" "QI")])
699
700 (define_insn "*cmpqi_1"
701   [(set (reg FLAGS_REG)
702         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
703                  (match_operand:QI 1 "general_operand" "qi,mq")))]
704   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
705     && ix86_match_ccmode (insn, CCmode)"
706   "cmp{b}\t{%1, %0|%0, %1}"
707   [(set_attr "type" "icmp")
708    (set_attr "mode" "QI")])
709
710 (define_insn "*cmpqi_minus_1"
711   [(set (reg FLAGS_REG)
712         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
713                            (match_operand:QI 1 "general_operand" "qi,mq"))
714                  (const_int 0)))]
715   "ix86_match_ccmode (insn, CCGOCmode)"
716   "cmp{b}\t{%1, %0|%0, %1}"
717   [(set_attr "type" "icmp")
718    (set_attr "mode" "QI")])
719
720 (define_insn "*cmpqi_ext_1"
721   [(set (reg FLAGS_REG)
722         (compare
723           (match_operand:QI 0 "general_operand" "Qm")
724           (subreg:QI
725             (zero_extract:SI
726               (match_operand 1 "ext_register_operand" "Q")
727               (const_int 8)
728               (const_int 8)) 0)))]
729   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
730   "cmp{b}\t{%h1, %0|%0, %h1}"
731   [(set_attr "type" "icmp")
732    (set_attr "mode" "QI")])
733
734 (define_insn "*cmpqi_ext_1_rex64"
735   [(set (reg FLAGS_REG)
736         (compare
737           (match_operand:QI 0 "register_operand" "Q")
738           (subreg:QI
739             (zero_extract:SI
740               (match_operand 1 "ext_register_operand" "Q")
741               (const_int 8)
742               (const_int 8)) 0)))]
743   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
744   "cmp{b}\t{%h1, %0|%0, %h1}"
745   [(set_attr "type" "icmp")
746    (set_attr "mode" "QI")])
747
748 (define_insn "*cmpqi_ext_2"
749   [(set (reg FLAGS_REG)
750         (compare
751           (subreg:QI
752             (zero_extract:SI
753               (match_operand 0 "ext_register_operand" "Q")
754               (const_int 8)
755               (const_int 8)) 0)
756           (match_operand:QI 1 "const0_operand" "n")))]
757   "ix86_match_ccmode (insn, CCNOmode)"
758   "test{b}\t%h0, %h0"
759   [(set_attr "type" "test")
760    (set_attr "length_immediate" "0")
761    (set_attr "mode" "QI")])
762
763 (define_expand "cmpqi_ext_3"
764   [(set (reg:CC FLAGS_REG)
765         (compare:CC
766           (subreg:QI
767             (zero_extract:SI
768               (match_operand 0 "ext_register_operand" "")
769               (const_int 8)
770               (const_int 8)) 0)
771           (match_operand:QI 1 "general_operand" "")))]
772   ""
773   "")
774
775 (define_insn "cmpqi_ext_3_insn"
776   [(set (reg FLAGS_REG)
777         (compare
778           (subreg:QI
779             (zero_extract:SI
780               (match_operand 0 "ext_register_operand" "Q")
781               (const_int 8)
782               (const_int 8)) 0)
783           (match_operand:QI 1 "general_operand" "Qmn")))]
784   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
785   "cmp{b}\t{%1, %h0|%h0, %1}"
786   [(set_attr "type" "icmp")
787    (set_attr "mode" "QI")])
788
789 (define_insn "cmpqi_ext_3_insn_rex64"
790   [(set (reg FLAGS_REG)
791         (compare
792           (subreg:QI
793             (zero_extract:SI
794               (match_operand 0 "ext_register_operand" "Q")
795               (const_int 8)
796               (const_int 8)) 0)
797           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
798   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
799   "cmp{b}\t{%1, %h0|%h0, %1}"
800   [(set_attr "type" "icmp")
801    (set_attr "mode" "QI")])
802
803 (define_insn "*cmpqi_ext_4"
804   [(set (reg FLAGS_REG)
805         (compare
806           (subreg:QI
807             (zero_extract:SI
808               (match_operand 0 "ext_register_operand" "Q")
809               (const_int 8)
810               (const_int 8)) 0)
811           (subreg:QI
812             (zero_extract:SI
813               (match_operand 1 "ext_register_operand" "Q")
814               (const_int 8)
815               (const_int 8)) 0)))]
816   "ix86_match_ccmode (insn, CCmode)"
817   "cmp{b}\t{%h1, %h0|%h0, %h1}"
818   [(set_attr "type" "icmp")
819    (set_attr "mode" "QI")])
820
821 ;; These implement float point compares.
822 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
823 ;; which would allow mix and match FP modes on the compares.  Which is what
824 ;; the old patterns did, but with many more of them.
825
826 (define_expand "cmpxf"
827   [(set (reg:CC FLAGS_REG)
828         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
829                     (match_operand:XF 1 "nonmemory_operand" "")))]
830   "TARGET_80387"
831 {
832   ix86_compare_op0 = operands[0];
833   ix86_compare_op1 = operands[1];
834   DONE;
835 })
836
837 (define_expand "cmpdf"
838   [(set (reg:CC FLAGS_REG)
839         (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
840                     (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
841   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
842 {
843   ix86_compare_op0 = operands[0];
844   ix86_compare_op1 = operands[1];
845   DONE;
846 })
847
848 (define_expand "cmpsf"
849   [(set (reg:CC FLAGS_REG)
850         (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
851                     (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
852   "TARGET_80387 || TARGET_SSE_MATH"
853 {
854   ix86_compare_op0 = operands[0];
855   ix86_compare_op1 = operands[1];
856   DONE;
857 })
858
859 ;; FP compares, step 1:
860 ;; Set the FP condition codes.
861 ;;
862 ;; CCFPmode     compare with exceptions
863 ;; CCFPUmode    compare with no exceptions
864
865 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
866 ;; used to manage the reg stack popping would not be preserved.
867
868 (define_insn "*cmpfp_0"
869   [(set (match_operand:HI 0 "register_operand" "=a")
870         (unspec:HI
871           [(compare:CCFP
872              (match_operand 1 "register_operand" "f")
873              (match_operand 2 "const0_operand" "X"))]
874         UNSPEC_FNSTSW))]
875   "TARGET_80387
876    && FLOAT_MODE_P (GET_MODE (operands[1]))
877    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
878   "* return output_fp_compare (insn, operands, 0, 0);"
879   [(set_attr "type" "multi")
880    (set_attr "unit" "i387")
881    (set (attr "mode")
882      (cond [(match_operand:SF 1 "" "")
883               (const_string "SF")
884             (match_operand:DF 1 "" "")
885               (const_string "DF")
886            ]
887            (const_string "XF")))])
888
889 (define_insn "*cmpfp_sf"
890   [(set (match_operand:HI 0 "register_operand" "=a")
891         (unspec:HI
892           [(compare:CCFP
893              (match_operand:SF 1 "register_operand" "f")
894              (match_operand:SF 2 "nonimmediate_operand" "fm"))]
895           UNSPEC_FNSTSW))]
896   "TARGET_80387"
897   "* return output_fp_compare (insn, operands, 0, 0);"
898   [(set_attr "type" "multi")
899    (set_attr "unit" "i387")
900    (set_attr "mode" "SF")])
901
902 (define_insn "*cmpfp_df"
903   [(set (match_operand:HI 0 "register_operand" "=a")
904         (unspec:HI
905           [(compare:CCFP
906              (match_operand:DF 1 "register_operand" "f")
907              (match_operand:DF 2 "nonimmediate_operand" "fm"))]
908           UNSPEC_FNSTSW))]
909   "TARGET_80387"
910   "* return output_fp_compare (insn, operands, 0, 0);"
911   [(set_attr "type" "multi")
912    (set_attr "unit" "i387")
913    (set_attr "mode" "DF")])
914
915 (define_insn "*cmpfp_xf"
916   [(set (match_operand:HI 0 "register_operand" "=a")
917         (unspec:HI
918           [(compare:CCFP
919              (match_operand:XF 1 "register_operand" "f")
920              (match_operand:XF 2 "register_operand" "f"))]
921           UNSPEC_FNSTSW))]
922   "TARGET_80387"
923   "* return output_fp_compare (insn, operands, 0, 0);"
924   [(set_attr "type" "multi")
925    (set_attr "unit" "i387")
926    (set_attr "mode" "XF")])
927
928 (define_insn "*cmpfp_u"
929   [(set (match_operand:HI 0 "register_operand" "=a")
930         (unspec:HI
931           [(compare:CCFPU
932              (match_operand 1 "register_operand" "f")
933              (match_operand 2 "register_operand" "f"))]
934           UNSPEC_FNSTSW))]
935   "TARGET_80387
936    && FLOAT_MODE_P (GET_MODE (operands[1]))
937    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
938   "* return output_fp_compare (insn, operands, 0, 1);"
939   [(set_attr "type" "multi")
940    (set_attr "unit" "i387")
941    (set (attr "mode")
942      (cond [(match_operand:SF 1 "" "")
943               (const_string "SF")
944             (match_operand:DF 1 "" "")
945               (const_string "DF")
946            ]
947            (const_string "XF")))])
948
949 (define_insn "*cmpfp_<mode>"
950   [(set (match_operand:HI 0 "register_operand" "=a")
951         (unspec:HI
952           [(compare:CCFP
953              (match_operand 1 "register_operand" "f")
954              (match_operator 3 "float_operator"
955                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
956           UNSPEC_FNSTSW))]
957   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
958    && FLOAT_MODE_P (GET_MODE (operands[1]))
959    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
960   "* return output_fp_compare (insn, operands, 0, 0);"
961   [(set_attr "type" "multi")
962    (set_attr "unit" "i387")
963    (set_attr "fp_int_src" "true")
964    (set_attr "mode" "<MODE>")])
965
966 ;; FP compares, step 2
967 ;; Move the fpsw to ax.
968
969 (define_insn "x86_fnstsw_1"
970   [(set (match_operand:HI 0 "register_operand" "=a")
971         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
972   "TARGET_80387"
973   "fnstsw\t%0"
974   [(set_attr "length" "2")
975    (set_attr "mode" "SI")
976    (set_attr "unit" "i387")])
977
978 ;; FP compares, step 3
979 ;; Get ax into flags, general case.
980
981 (define_insn "x86_sahf_1"
982   [(set (reg:CC FLAGS_REG)
983         (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
984   "!TARGET_64BIT"
985   "sahf"
986   [(set_attr "length" "1")
987    (set_attr "athlon_decode" "vector")
988    (set_attr "amdfam10_decode" "direct")
989    (set_attr "mode" "SI")])
990
991 ;; Pentium Pro can do steps 1 through 3 in one go.
992 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes) 
993 (define_insn "*cmpfp_i_mixed"
994   [(set (reg:CCFP FLAGS_REG)
995         (compare:CCFP (match_operand 0 "register_operand" "f,x")
996                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
997   "TARGET_MIX_SSE_I387
998    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
999    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1000   "* return output_fp_compare (insn, operands, 1, 0);"
1001   [(set_attr "type" "fcmp,ssecomi")
1002    (set (attr "mode")
1003      (if_then_else (match_operand:SF 1 "" "")
1004         (const_string "SF")
1005         (const_string "DF")))
1006    (set_attr "athlon_decode" "vector")
1007    (set_attr "amdfam10_decode" "direct")])
1008
1009 (define_insn "*cmpfp_i_sse"
1010   [(set (reg:CCFP FLAGS_REG)
1011         (compare:CCFP (match_operand 0 "register_operand" "x")
1012                       (match_operand 1 "nonimmediate_operand" "xm")))]
1013   "TARGET_SSE_MATH
1014    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1015    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1016   "* return output_fp_compare (insn, operands, 1, 0);"
1017   [(set_attr "type" "ssecomi")
1018    (set (attr "mode")
1019      (if_then_else (match_operand:SF 1 "" "")
1020         (const_string "SF")
1021         (const_string "DF")))
1022    (set_attr "athlon_decode" "vector")
1023    (set_attr "amdfam10_decode" "direct")])
1024
1025 (define_insn "*cmpfp_i_i387"
1026   [(set (reg:CCFP FLAGS_REG)
1027         (compare:CCFP (match_operand 0 "register_operand" "f")
1028                       (match_operand 1 "register_operand" "f")))]
1029   "TARGET_80387 && TARGET_CMOVE
1030    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1031    && FLOAT_MODE_P (GET_MODE (operands[0]))
1032    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1033   "* return output_fp_compare (insn, operands, 1, 0);"
1034   [(set_attr "type" "fcmp")
1035    (set (attr "mode")
1036      (cond [(match_operand:SF 1 "" "")
1037               (const_string "SF")
1038             (match_operand:DF 1 "" "")
1039               (const_string "DF")
1040            ]
1041            (const_string "XF")))
1042    (set_attr "athlon_decode" "vector")
1043    (set_attr "amdfam10_decode" "direct")])
1044
1045 (define_insn "*cmpfp_iu_mixed"
1046   [(set (reg:CCFPU FLAGS_REG)
1047         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1048                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1049   "TARGET_MIX_SSE_I387
1050    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1051    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1052   "* return output_fp_compare (insn, operands, 1, 1);"
1053   [(set_attr "type" "fcmp,ssecomi")
1054    (set (attr "mode")
1055      (if_then_else (match_operand:SF 1 "" "")
1056         (const_string "SF")
1057         (const_string "DF")))
1058    (set_attr "athlon_decode" "vector")
1059    (set_attr "amdfam10_decode" "direct")])
1060
1061 (define_insn "*cmpfp_iu_sse"
1062   [(set (reg:CCFPU FLAGS_REG)
1063         (compare:CCFPU (match_operand 0 "register_operand" "x")
1064                        (match_operand 1 "nonimmediate_operand" "xm")))]
1065   "TARGET_SSE_MATH
1066    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1067    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1068   "* return output_fp_compare (insn, operands, 1, 1);"
1069   [(set_attr "type" "ssecomi")
1070    (set (attr "mode")
1071      (if_then_else (match_operand:SF 1 "" "")
1072         (const_string "SF")
1073         (const_string "DF")))
1074    (set_attr "athlon_decode" "vector")
1075    (set_attr "amdfam10_decode" "direct")])
1076
1077 (define_insn "*cmpfp_iu_387"
1078   [(set (reg:CCFPU FLAGS_REG)
1079         (compare:CCFPU (match_operand 0 "register_operand" "f")
1080                        (match_operand 1 "register_operand" "f")))]
1081   "TARGET_80387 && TARGET_CMOVE
1082    && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1083    && FLOAT_MODE_P (GET_MODE (operands[0]))
1084    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1085   "* return output_fp_compare (insn, operands, 1, 1);"
1086   [(set_attr "type" "fcmp")
1087    (set (attr "mode")
1088      (cond [(match_operand:SF 1 "" "")
1089               (const_string "SF")
1090             (match_operand:DF 1 "" "")
1091               (const_string "DF")
1092            ]
1093            (const_string "XF")))
1094    (set_attr "athlon_decode" "vector")
1095    (set_attr "amdfam10_decode" "direct")])
1096 \f
1097 ;; Move instructions.
1098
1099 ;; General case of fullword move.
1100
1101 (define_expand "movsi"
1102   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1103         (match_operand:SI 1 "general_operand" ""))]
1104   ""
1105   "ix86_expand_move (SImode, operands); DONE;")
1106
1107 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1108 ;; general_operand.
1109 ;;
1110 ;; %%% We don't use a post-inc memory reference because x86 is not a
1111 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1112 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1113 ;; targets without our curiosities, and it is just as easy to represent
1114 ;; this differently.
1115
1116 (define_insn "*pushsi2"
1117   [(set (match_operand:SI 0 "push_operand" "=<")
1118         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1119   "!TARGET_64BIT"
1120   "push{l}\t%1"
1121   [(set_attr "type" "push")
1122    (set_attr "mode" "SI")])
1123
1124 ;; For 64BIT abi we always round up to 8 bytes.
1125 (define_insn "*pushsi2_rex64"
1126   [(set (match_operand:SI 0 "push_operand" "=X")
1127         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1128   "TARGET_64BIT"
1129   "push{q}\t%q1"
1130   [(set_attr "type" "push")
1131    (set_attr "mode" "SI")])
1132
1133 (define_insn "*pushsi2_prologue"
1134   [(set (match_operand:SI 0 "push_operand" "=<")
1135         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1136    (clobber (mem:BLK (scratch)))]
1137   "!TARGET_64BIT"
1138   "push{l}\t%1"
1139   [(set_attr "type" "push")
1140    (set_attr "mode" "SI")])
1141
1142 (define_insn "*popsi1_epilogue"
1143   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1144         (mem:SI (reg:SI SP_REG)))
1145    (set (reg:SI SP_REG)
1146         (plus:SI (reg:SI SP_REG) (const_int 4)))
1147    (clobber (mem:BLK (scratch)))]
1148   "!TARGET_64BIT"
1149   "pop{l}\t%0"
1150   [(set_attr "type" "pop")
1151    (set_attr "mode" "SI")])
1152
1153 (define_insn "popsi1"
1154   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1155         (mem:SI (reg:SI SP_REG)))
1156    (set (reg:SI SP_REG)
1157         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1158   "!TARGET_64BIT"
1159   "pop{l}\t%0"
1160   [(set_attr "type" "pop")
1161    (set_attr "mode" "SI")])
1162
1163 (define_insn "*movsi_xor"
1164   [(set (match_operand:SI 0 "register_operand" "=r")
1165         (match_operand:SI 1 "const0_operand" "i"))
1166    (clobber (reg:CC FLAGS_REG))]
1167   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1168   "xor{l}\t{%0, %0|%0, %0}"
1169   [(set_attr "type" "alu1")
1170    (set_attr "mode" "SI")
1171    (set_attr "length_immediate" "0")])
1172
1173 (define_insn "*movsi_or"
1174   [(set (match_operand:SI 0 "register_operand" "=r")
1175         (match_operand:SI 1 "immediate_operand" "i"))
1176    (clobber (reg:CC FLAGS_REG))]
1177   "reload_completed
1178    && operands[1] == constm1_rtx
1179    && (TARGET_PENTIUM || optimize_size)"
1180 {
1181   operands[1] = constm1_rtx;
1182   return "or{l}\t{%1, %0|%0, %1}";
1183 }
1184   [(set_attr "type" "alu1")
1185    (set_attr "mode" "SI")
1186    (set_attr "length_immediate" "1")])
1187
1188 (define_insn "*movsi_1"
1189   [(set (match_operand:SI 0 "nonimmediate_operand"
1190                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1191         (match_operand:SI 1 "general_operand"
1192                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r  ,m "))]
1193   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1194 {
1195   switch (get_attr_type (insn))
1196     {
1197     case TYPE_SSELOG1:
1198       if (get_attr_mode (insn) == MODE_TI)
1199         return "pxor\t%0, %0";
1200       return "xorps\t%0, %0";
1201
1202     case TYPE_SSEMOV:
1203       switch (get_attr_mode (insn))
1204         {
1205         case MODE_TI:
1206           return "movdqa\t{%1, %0|%0, %1}";
1207         case MODE_V4SF:
1208           return "movaps\t{%1, %0|%0, %1}";
1209         case MODE_SI:
1210           return "movd\t{%1, %0|%0, %1}";
1211         case MODE_SF:
1212           return "movss\t{%1, %0|%0, %1}";
1213         default:
1214           gcc_unreachable ();
1215         }
1216
1217     case TYPE_MMXADD:
1218       return "pxor\t%0, %0";
1219
1220     case TYPE_MMXMOV:
1221       if (get_attr_mode (insn) == MODE_DI)
1222         return "movq\t{%1, %0|%0, %1}";
1223       return "movd\t{%1, %0|%0, %1}";
1224
1225     case TYPE_LEA:
1226       return "lea{l}\t{%1, %0|%0, %1}";
1227
1228     default:
1229       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1230       return "mov{l}\t{%1, %0|%0, %1}";
1231     }
1232 }
1233   [(set (attr "type")
1234      (cond [(eq_attr "alternative" "2")
1235               (const_string "mmxadd")
1236             (eq_attr "alternative" "3,4,5")
1237               (const_string "mmxmov")
1238             (eq_attr "alternative" "6")
1239               (const_string "sselog1")
1240             (eq_attr "alternative" "7,8,9,10,11")
1241               (const_string "ssemov")
1242             (match_operand:DI 1 "pic_32bit_operand" "")
1243               (const_string "lea")
1244            ]
1245            (const_string "imov")))
1246    (set (attr "mode")
1247      (cond [(eq_attr "alternative" "2,3")
1248               (const_string "DI")
1249             (eq_attr "alternative" "6,7")
1250               (if_then_else
1251                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1252                 (const_string "V4SF")
1253                 (const_string "TI"))
1254             (and (eq_attr "alternative" "8,9,10,11")
1255                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1256               (const_string "SF")
1257            ]
1258            (const_string "SI")))])
1259
1260 ;; Stores and loads of ax to arbitrary constant address.
1261 ;; We fake an second form of instruction to force reload to load address
1262 ;; into register when rax is not available
1263 (define_insn "*movabssi_1_rex64"
1264   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1265         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1266   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1267   "@
1268    movabs{l}\t{%1, %P0|%P0, %1}
1269    mov{l}\t{%1, %a0|%a0, %1}"
1270   [(set_attr "type" "imov")
1271    (set_attr "modrm" "0,*")
1272    (set_attr "length_address" "8,0")
1273    (set_attr "length_immediate" "0,*")
1274    (set_attr "memory" "store")
1275    (set_attr "mode" "SI")])
1276
1277 (define_insn "*movabssi_2_rex64"
1278   [(set (match_operand:SI 0 "register_operand" "=a,r")
1279         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1280   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1281   "@
1282    movabs{l}\t{%P1, %0|%0, %P1}
1283    mov{l}\t{%a1, %0|%0, %a1}"
1284   [(set_attr "type" "imov")
1285    (set_attr "modrm" "0,*")
1286    (set_attr "length_address" "8,0")
1287    (set_attr "length_immediate" "0")
1288    (set_attr "memory" "load")
1289    (set_attr "mode" "SI")])
1290
1291 (define_insn "*swapsi"
1292   [(set (match_operand:SI 0 "register_operand" "+r")
1293         (match_operand:SI 1 "register_operand" "+r"))
1294    (set (match_dup 1)
1295         (match_dup 0))]
1296   ""
1297   "xchg{l}\t%1, %0"
1298   [(set_attr "type" "imov")
1299    (set_attr "mode" "SI")
1300    (set_attr "pent_pair" "np")
1301    (set_attr "athlon_decode" "vector")
1302    (set_attr "amdfam10_decode" "double")])   
1303
1304 (define_expand "movhi"
1305   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1306         (match_operand:HI 1 "general_operand" ""))]
1307   ""
1308   "ix86_expand_move (HImode, operands); DONE;")
1309
1310 (define_insn "*pushhi2"
1311   [(set (match_operand:HI 0 "push_operand" "=X")
1312         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1313   "!TARGET_64BIT"
1314   "push{l}\t%k1"
1315   [(set_attr "type" "push")
1316    (set_attr "mode" "SI")])
1317
1318 ;; For 64BIT abi we always round up to 8 bytes.
1319 (define_insn "*pushhi2_rex64"
1320   [(set (match_operand:HI 0 "push_operand" "=X")
1321         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1322   "TARGET_64BIT"
1323   "push{q}\t%q1"
1324   [(set_attr "type" "push")
1325    (set_attr "mode" "DI")])
1326
1327 (define_insn "*movhi_1"
1328   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1329         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1330   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1331 {
1332   switch (get_attr_type (insn))
1333     {
1334     case TYPE_IMOVX:
1335       /* movzwl is faster than movw on p2 due to partial word stalls,
1336          though not as fast as an aligned movl.  */
1337       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1338     default:
1339       if (get_attr_mode (insn) == MODE_SI)
1340         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1341       else
1342         return "mov{w}\t{%1, %0|%0, %1}";
1343     }
1344 }
1345   [(set (attr "type")
1346      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1347               (const_string "imov")
1348             (and (eq_attr "alternative" "0")
1349                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1350                           (const_int 0))
1351                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1352                           (const_int 0))))
1353               (const_string "imov")
1354             (and (eq_attr "alternative" "1,2")
1355                  (match_operand:HI 1 "aligned_operand" ""))
1356               (const_string "imov")
1357             (and (ne (symbol_ref "TARGET_MOVX")
1358                      (const_int 0))
1359                  (eq_attr "alternative" "0,2"))
1360               (const_string "imovx")
1361            ]
1362            (const_string "imov")))
1363     (set (attr "mode")
1364       (cond [(eq_attr "type" "imovx")
1365                (const_string "SI")
1366              (and (eq_attr "alternative" "1,2")
1367                   (match_operand:HI 1 "aligned_operand" ""))
1368                (const_string "SI")
1369              (and (eq_attr "alternative" "0")
1370                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1371                            (const_int 0))
1372                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1373                            (const_int 0))))
1374                (const_string "SI")
1375             ]
1376             (const_string "HI")))])
1377
1378 ;; Stores and loads of ax to arbitrary constant address.
1379 ;; We fake an second form of instruction to force reload to load address
1380 ;; into register when rax is not available
1381 (define_insn "*movabshi_1_rex64"
1382   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1383         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1384   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1385   "@
1386    movabs{w}\t{%1, %P0|%P0, %1}
1387    mov{w}\t{%1, %a0|%a0, %1}"
1388   [(set_attr "type" "imov")
1389    (set_attr "modrm" "0,*")
1390    (set_attr "length_address" "8,0")
1391    (set_attr "length_immediate" "0,*")
1392    (set_attr "memory" "store")
1393    (set_attr "mode" "HI")])
1394
1395 (define_insn "*movabshi_2_rex64"
1396   [(set (match_operand:HI 0 "register_operand" "=a,r")
1397         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1398   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1399   "@
1400    movabs{w}\t{%P1, %0|%0, %P1}
1401    mov{w}\t{%a1, %0|%0, %a1}"
1402   [(set_attr "type" "imov")
1403    (set_attr "modrm" "0,*")
1404    (set_attr "length_address" "8,0")
1405    (set_attr "length_immediate" "0")
1406    (set_attr "memory" "load")
1407    (set_attr "mode" "HI")])
1408
1409 (define_insn "*swaphi_1"
1410   [(set (match_operand:HI 0 "register_operand" "+r")
1411         (match_operand:HI 1 "register_operand" "+r"))
1412    (set (match_dup 1)
1413         (match_dup 0))]
1414   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1415   "xchg{l}\t%k1, %k0"
1416   [(set_attr "type" "imov")
1417    (set_attr "mode" "SI")
1418    (set_attr "pent_pair" "np")
1419    (set_attr "athlon_decode" "vector")
1420    (set_attr "amdfam10_decode" "double")])   
1421
1422 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1423 (define_insn "*swaphi_2"
1424   [(set (match_operand:HI 0 "register_operand" "+r")
1425         (match_operand:HI 1 "register_operand" "+r"))
1426    (set (match_dup 1)
1427         (match_dup 0))]
1428   "TARGET_PARTIAL_REG_STALL"
1429   "xchg{w}\t%1, %0"
1430   [(set_attr "type" "imov")
1431    (set_attr "mode" "HI")
1432    (set_attr "pent_pair" "np")
1433    (set_attr "athlon_decode" "vector")])
1434
1435 (define_expand "movstricthi"
1436   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1437         (match_operand:HI 1 "general_operand" ""))]
1438   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1439 {
1440   /* Don't generate memory->memory moves, go through a register */
1441   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1442     operands[1] = force_reg (HImode, operands[1]);
1443 })
1444
1445 (define_insn "*movstricthi_1"
1446   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1447         (match_operand:HI 1 "general_operand" "rn,m"))]
1448   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1449    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1450   "mov{w}\t{%1, %0|%0, %1}"
1451   [(set_attr "type" "imov")
1452    (set_attr "mode" "HI")])
1453
1454 (define_insn "*movstricthi_xor"
1455   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1456         (match_operand:HI 1 "const0_operand" "i"))
1457    (clobber (reg:CC FLAGS_REG))]
1458   "reload_completed
1459    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1460   "xor{w}\t{%0, %0|%0, %0}"
1461   [(set_attr "type" "alu1")
1462    (set_attr "mode" "HI")
1463    (set_attr "length_immediate" "0")])
1464
1465 (define_expand "movqi"
1466   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1467         (match_operand:QI 1 "general_operand" ""))]
1468   ""
1469   "ix86_expand_move (QImode, operands); DONE;")
1470
1471 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1472 ;; "push a byte".  But actually we use pushl, which has the effect
1473 ;; of rounding the amount pushed up to a word.
1474
1475 (define_insn "*pushqi2"
1476   [(set (match_operand:QI 0 "push_operand" "=X")
1477         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1478   "!TARGET_64BIT"
1479   "push{l}\t%k1"
1480   [(set_attr "type" "push")
1481    (set_attr "mode" "SI")])
1482
1483 ;; For 64BIT abi we always round up to 8 bytes.
1484 (define_insn "*pushqi2_rex64"
1485   [(set (match_operand:QI 0 "push_operand" "=X")
1486         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1487   "TARGET_64BIT"
1488   "push{q}\t%q1"
1489   [(set_attr "type" "push")
1490    (set_attr "mode" "DI")])
1491
1492 ;; Situation is quite tricky about when to choose full sized (SImode) move
1493 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1494 ;; partial register dependency machines (such as AMD Athlon), where QImode
1495 ;; moves issue extra dependency and for partial register stalls machines
1496 ;; that don't use QImode patterns (and QImode move cause stall on the next
1497 ;; instruction).
1498 ;;
1499 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1500 ;; register stall machines with, where we use QImode instructions, since
1501 ;; partial register stall can be caused there.  Then we use movzx.
1502 (define_insn "*movqi_1"
1503   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1504         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1505   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1506 {
1507   switch (get_attr_type (insn))
1508     {
1509     case TYPE_IMOVX:
1510       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1511       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1512     default:
1513       if (get_attr_mode (insn) == MODE_SI)
1514         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1515       else
1516         return "mov{b}\t{%1, %0|%0, %1}";
1517     }
1518 }
1519   [(set (attr "type")
1520      (cond [(and (eq_attr "alternative" "5")
1521                  (not (match_operand:QI 1 "aligned_operand" "")))
1522               (const_string "imovx")
1523             (ne (symbol_ref "optimize_size") (const_int 0))
1524               (const_string "imov")
1525             (and (eq_attr "alternative" "3")
1526                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1527                           (const_int 0))
1528                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1529                           (const_int 0))))
1530               (const_string "imov")
1531             (eq_attr "alternative" "3,5")
1532               (const_string "imovx")
1533             (and (ne (symbol_ref "TARGET_MOVX")
1534                      (const_int 0))
1535                  (eq_attr "alternative" "2"))
1536               (const_string "imovx")
1537            ]
1538            (const_string "imov")))
1539    (set (attr "mode")
1540       (cond [(eq_attr "alternative" "3,4,5")
1541                (const_string "SI")
1542              (eq_attr "alternative" "6")
1543                (const_string "QI")
1544              (eq_attr "type" "imovx")
1545                (const_string "SI")
1546              (and (eq_attr "type" "imov")
1547                   (and (eq_attr "alternative" "0,1")
1548                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1549                                 (const_int 0))
1550                             (and (eq (symbol_ref "optimize_size")
1551                                      (const_int 0))
1552                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1553                                      (const_int 0))))))
1554                (const_string "SI")
1555              ;; Avoid partial register stalls when not using QImode arithmetic
1556              (and (eq_attr "type" "imov")
1557                   (and (eq_attr "alternative" "0,1")
1558                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1559                                 (const_int 0))
1560                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1561                                 (const_int 0)))))
1562                (const_string "SI")
1563            ]
1564            (const_string "QI")))])
1565
1566 (define_expand "reload_outqi"
1567   [(parallel [(match_operand:QI 0 "" "=m")
1568               (match_operand:QI 1 "register_operand" "r")
1569               (match_operand:QI 2 "register_operand" "=&q")])]
1570   ""
1571 {
1572   rtx op0, op1, op2;
1573   op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1574
1575   gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1576   if (! q_regs_operand (op1, QImode))
1577     {
1578       emit_insn (gen_movqi (op2, op1));
1579       op1 = op2;
1580     }
1581   emit_insn (gen_movqi (op0, op1));
1582   DONE;
1583 })
1584
1585 (define_insn "*swapqi_1"
1586   [(set (match_operand:QI 0 "register_operand" "+r")
1587         (match_operand:QI 1 "register_operand" "+r"))
1588    (set (match_dup 1)
1589         (match_dup 0))]
1590   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1591   "xchg{l}\t%k1, %k0"
1592   [(set_attr "type" "imov")
1593    (set_attr "mode" "SI")
1594    (set_attr "pent_pair" "np")
1595    (set_attr "athlon_decode" "vector")
1596    (set_attr "amdfam10_decode" "vector")])   
1597
1598 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1599 (define_insn "*swapqi_2"
1600   [(set (match_operand:QI 0 "register_operand" "+q")
1601         (match_operand:QI 1 "register_operand" "+q"))
1602    (set (match_dup 1)
1603         (match_dup 0))]
1604   "TARGET_PARTIAL_REG_STALL"
1605   "xchg{b}\t%1, %0"
1606   [(set_attr "type" "imov")
1607    (set_attr "mode" "QI")
1608    (set_attr "pent_pair" "np")
1609    (set_attr "athlon_decode" "vector")])
1610
1611 (define_expand "movstrictqi"
1612   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1613         (match_operand:QI 1 "general_operand" ""))]
1614   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1615 {
1616   /* Don't generate memory->memory moves, go through a register.  */
1617   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1618     operands[1] = force_reg (QImode, operands[1]);
1619 })
1620
1621 (define_insn "*movstrictqi_1"
1622   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1623         (match_operand:QI 1 "general_operand" "*qn,m"))]
1624   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1625    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1626   "mov{b}\t{%1, %0|%0, %1}"
1627   [(set_attr "type" "imov")
1628    (set_attr "mode" "QI")])
1629
1630 (define_insn "*movstrictqi_xor"
1631   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1632         (match_operand:QI 1 "const0_operand" "i"))
1633    (clobber (reg:CC FLAGS_REG))]
1634   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1635   "xor{b}\t{%0, %0|%0, %0}"
1636   [(set_attr "type" "alu1")
1637    (set_attr "mode" "QI")
1638    (set_attr "length_immediate" "0")])
1639
1640 (define_insn "*movsi_extv_1"
1641   [(set (match_operand:SI 0 "register_operand" "=R")
1642         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1643                          (const_int 8)
1644                          (const_int 8)))]
1645   ""
1646   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1647   [(set_attr "type" "imovx")
1648    (set_attr "mode" "SI")])
1649
1650 (define_insn "*movhi_extv_1"
1651   [(set (match_operand:HI 0 "register_operand" "=R")
1652         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1653                          (const_int 8)
1654                          (const_int 8)))]
1655   ""
1656   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1657   [(set_attr "type" "imovx")
1658    (set_attr "mode" "SI")])
1659
1660 (define_insn "*movqi_extv_1"
1661   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1662         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1663                          (const_int 8)
1664                          (const_int 8)))]
1665   "!TARGET_64BIT"
1666 {
1667   switch (get_attr_type (insn))
1668     {
1669     case TYPE_IMOVX:
1670       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1671     default:
1672       return "mov{b}\t{%h1, %0|%0, %h1}";
1673     }
1674 }
1675   [(set (attr "type")
1676      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1677                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1678                              (ne (symbol_ref "TARGET_MOVX")
1679                                  (const_int 0))))
1680         (const_string "imovx")
1681         (const_string "imov")))
1682    (set (attr "mode")
1683      (if_then_else (eq_attr "type" "imovx")
1684         (const_string "SI")
1685         (const_string "QI")))])
1686
1687 (define_insn "*movqi_extv_1_rex64"
1688   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1689         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1690                          (const_int 8)
1691                          (const_int 8)))]
1692   "TARGET_64BIT"
1693 {
1694   switch (get_attr_type (insn))
1695     {
1696     case TYPE_IMOVX:
1697       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1698     default:
1699       return "mov{b}\t{%h1, %0|%0, %h1}";
1700     }
1701 }
1702   [(set (attr "type")
1703      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1704                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1705                              (ne (symbol_ref "TARGET_MOVX")
1706                                  (const_int 0))))
1707         (const_string "imovx")
1708         (const_string "imov")))
1709    (set (attr "mode")
1710      (if_then_else (eq_attr "type" "imovx")
1711         (const_string "SI")
1712         (const_string "QI")))])
1713
1714 ;; Stores and loads of ax to arbitrary constant address.
1715 ;; We fake an second form of instruction to force reload to load address
1716 ;; into register when rax is not available
1717 (define_insn "*movabsqi_1_rex64"
1718   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1719         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1720   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1721   "@
1722    movabs{b}\t{%1, %P0|%P0, %1}
1723    mov{b}\t{%1, %a0|%a0, %1}"
1724   [(set_attr "type" "imov")
1725    (set_attr "modrm" "0,*")
1726    (set_attr "length_address" "8,0")
1727    (set_attr "length_immediate" "0,*")
1728    (set_attr "memory" "store")
1729    (set_attr "mode" "QI")])
1730
1731 (define_insn "*movabsqi_2_rex64"
1732   [(set (match_operand:QI 0 "register_operand" "=a,r")
1733         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1734   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1735   "@
1736    movabs{b}\t{%P1, %0|%0, %P1}
1737    mov{b}\t{%a1, %0|%0, %a1}"
1738   [(set_attr "type" "imov")
1739    (set_attr "modrm" "0,*")
1740    (set_attr "length_address" "8,0")
1741    (set_attr "length_immediate" "0")
1742    (set_attr "memory" "load")
1743    (set_attr "mode" "QI")])
1744
1745 (define_insn "*movdi_extzv_1"
1746   [(set (match_operand:DI 0 "register_operand" "=R")
1747         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1748                          (const_int 8)
1749                          (const_int 8)))]
1750   "TARGET_64BIT"
1751   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1752   [(set_attr "type" "imovx")
1753    (set_attr "mode" "DI")])
1754
1755 (define_insn "*movsi_extzv_1"
1756   [(set (match_operand:SI 0 "register_operand" "=R")
1757         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1758                          (const_int 8)
1759                          (const_int 8)))]
1760   ""
1761   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1762   [(set_attr "type" "imovx")
1763    (set_attr "mode" "SI")])
1764
1765 (define_insn "*movqi_extzv_2"
1766   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1767         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1768                                     (const_int 8)
1769                                     (const_int 8)) 0))]
1770   "!TARGET_64BIT"
1771 {
1772   switch (get_attr_type (insn))
1773     {
1774     case TYPE_IMOVX:
1775       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1776     default:
1777       return "mov{b}\t{%h1, %0|%0, %h1}";
1778     }
1779 }
1780   [(set (attr "type")
1781      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1782                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1783                              (ne (symbol_ref "TARGET_MOVX")
1784                                  (const_int 0))))
1785         (const_string "imovx")
1786         (const_string "imov")))
1787    (set (attr "mode")
1788      (if_then_else (eq_attr "type" "imovx")
1789         (const_string "SI")
1790         (const_string "QI")))])
1791
1792 (define_insn "*movqi_extzv_2_rex64"
1793   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1794         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1795                                     (const_int 8)
1796                                     (const_int 8)) 0))]
1797   "TARGET_64BIT"
1798 {
1799   switch (get_attr_type (insn))
1800     {
1801     case TYPE_IMOVX:
1802       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1803     default:
1804       return "mov{b}\t{%h1, %0|%0, %h1}";
1805     }
1806 }
1807   [(set (attr "type")
1808      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1809                         (ne (symbol_ref "TARGET_MOVX")
1810                             (const_int 0)))
1811         (const_string "imovx")
1812         (const_string "imov")))
1813    (set (attr "mode")
1814      (if_then_else (eq_attr "type" "imovx")
1815         (const_string "SI")
1816         (const_string "QI")))])
1817
1818 (define_insn "movsi_insv_1"
1819   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1820                          (const_int 8)
1821                          (const_int 8))
1822         (match_operand:SI 1 "general_operand" "Qmn"))]
1823   "!TARGET_64BIT"
1824   "mov{b}\t{%b1, %h0|%h0, %b1}"
1825   [(set_attr "type" "imov")
1826    (set_attr "mode" "QI")])
1827
1828 (define_insn "*movsi_insv_1_rex64"
1829   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1830                          (const_int 8)
1831                          (const_int 8))
1832         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1833   "TARGET_64BIT"
1834   "mov{b}\t{%b1, %h0|%h0, %b1}"
1835   [(set_attr "type" "imov")
1836    (set_attr "mode" "QI")])
1837
1838 (define_insn "movdi_insv_1_rex64"
1839   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1840                          (const_int 8)
1841                          (const_int 8))
1842         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1843   "TARGET_64BIT"
1844   "mov{b}\t{%b1, %h0|%h0, %b1}"
1845   [(set_attr "type" "imov")
1846    (set_attr "mode" "QI")])
1847
1848 (define_insn "*movqi_insv_2"
1849   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1850                          (const_int 8)
1851                          (const_int 8))
1852         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1853                      (const_int 8)))]
1854   ""
1855   "mov{b}\t{%h1, %h0|%h0, %h1}"
1856   [(set_attr "type" "imov")
1857    (set_attr "mode" "QI")])
1858
1859 (define_expand "movdi"
1860   [(set (match_operand:DI 0 "nonimmediate_operand" "")
1861         (match_operand:DI 1 "general_operand" ""))]
1862   ""
1863   "ix86_expand_move (DImode, operands); DONE;")
1864
1865 (define_insn "*pushdi"
1866   [(set (match_operand:DI 0 "push_operand" "=<")
1867         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1868   "!TARGET_64BIT"
1869   "#")
1870
1871 (define_insn "*pushdi2_rex64"
1872   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1873         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1874   "TARGET_64BIT"
1875   "@
1876    push{q}\t%1
1877    #"
1878   [(set_attr "type" "push,multi")
1879    (set_attr "mode" "DI")])
1880
1881 ;; Convert impossible pushes of immediate to existing instructions.
1882 ;; First try to get scratch register and go through it.  In case this
1883 ;; fails, push sign extended lower part first and then overwrite
1884 ;; upper part by 32bit move.
1885 (define_peephole2
1886   [(match_scratch:DI 2 "r")
1887    (set (match_operand:DI 0 "push_operand" "")
1888         (match_operand:DI 1 "immediate_operand" ""))]
1889   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1890    && !x86_64_immediate_operand (operands[1], DImode)"
1891   [(set (match_dup 2) (match_dup 1))
1892    (set (match_dup 0) (match_dup 2))]
1893   "")
1894
1895 ;; We need to define this as both peepholer and splitter for case
1896 ;; peephole2 pass is not run.
1897 ;; "&& 1" is needed to keep it from matching the previous pattern.
1898 (define_peephole2
1899   [(set (match_operand:DI 0 "push_operand" "")
1900         (match_operand:DI 1 "immediate_operand" ""))]
1901   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1902    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1903   [(set (match_dup 0) (match_dup 1))
1904    (set (match_dup 2) (match_dup 3))]
1905   "split_di (operands + 1, 1, operands + 2, operands + 3);
1906    operands[1] = gen_lowpart (DImode, operands[2]);
1907    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1908                                                     GEN_INT (4)));
1909   ")
1910
1911 (define_split
1912   [(set (match_operand:DI 0 "push_operand" "")
1913         (match_operand:DI 1 "immediate_operand" ""))]
1914   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1915                     ? flow2_completed : reload_completed)
1916    && !symbolic_operand (operands[1], DImode)
1917    && !x86_64_immediate_operand (operands[1], DImode)"
1918   [(set (match_dup 0) (match_dup 1))
1919    (set (match_dup 2) (match_dup 3))]
1920   "split_di (operands + 1, 1, operands + 2, operands + 3);
1921    operands[1] = gen_lowpart (DImode, operands[2]);
1922    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1923                                                     GEN_INT (4)));
1924   ")
1925
1926 (define_insn "*pushdi2_prologue_rex64"
1927   [(set (match_operand:DI 0 "push_operand" "=<")
1928         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1929    (clobber (mem:BLK (scratch)))]
1930   "TARGET_64BIT"
1931   "push{q}\t%1"
1932   [(set_attr "type" "push")
1933    (set_attr "mode" "DI")])
1934
1935 (define_insn "*popdi1_epilogue_rex64"
1936   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1937         (mem:DI (reg:DI SP_REG)))
1938    (set (reg:DI SP_REG)
1939         (plus:DI (reg:DI SP_REG) (const_int 8)))
1940    (clobber (mem:BLK (scratch)))]
1941   "TARGET_64BIT"
1942   "pop{q}\t%0"
1943   [(set_attr "type" "pop")
1944    (set_attr "mode" "DI")])
1945
1946 (define_insn "popdi1"
1947   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1948         (mem:DI (reg:DI SP_REG)))
1949    (set (reg:DI SP_REG)
1950         (plus:DI (reg:DI SP_REG) (const_int 8)))]
1951   "TARGET_64BIT"
1952   "pop{q}\t%0"
1953   [(set_attr "type" "pop")
1954    (set_attr "mode" "DI")])
1955
1956 (define_insn "*movdi_xor_rex64"
1957   [(set (match_operand:DI 0 "register_operand" "=r")
1958         (match_operand:DI 1 "const0_operand" "i"))
1959    (clobber (reg:CC FLAGS_REG))]
1960   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1961    && reload_completed"
1962   "xor{l}\t{%k0, %k0|%k0, %k0}"
1963   [(set_attr "type" "alu1")
1964    (set_attr "mode" "SI")
1965    (set_attr "length_immediate" "0")])
1966
1967 (define_insn "*movdi_or_rex64"
1968   [(set (match_operand:DI 0 "register_operand" "=r")
1969         (match_operand:DI 1 "const_int_operand" "i"))
1970    (clobber (reg:CC FLAGS_REG))]
1971   "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1972    && reload_completed
1973    && operands[1] == constm1_rtx"
1974 {
1975   operands[1] = constm1_rtx;
1976   return "or{q}\t{%1, %0|%0, %1}";
1977 }
1978   [(set_attr "type" "alu1")
1979    (set_attr "mode" "DI")
1980    (set_attr "length_immediate" "1")])
1981
1982 (define_insn "*movdi_2"
1983   [(set (match_operand:DI 0 "nonimmediate_operand"
1984                                 "=r  ,o  ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1985         (match_operand:DI 1 "general_operand"
1986                                 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1987   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1988   "@
1989    #
1990    #
1991    pxor\t%0, %0
1992    movq\t{%1, %0|%0, %1}
1993    movq\t{%1, %0|%0, %1}
1994    pxor\t%0, %0
1995    movq\t{%1, %0|%0, %1}
1996    movdqa\t{%1, %0|%0, %1}
1997    movq\t{%1, %0|%0, %1}
1998    xorps\t%0, %0
1999    movlps\t{%1, %0|%0, %1}
2000    movaps\t{%1, %0|%0, %1}
2001    movlps\t{%1, %0|%0, %1}"
2002   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2003    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2004
2005 (define_split
2006   [(set (match_operand:DI 0 "push_operand" "")
2007         (match_operand:DI 1 "general_operand" ""))]
2008   "!TARGET_64BIT && reload_completed
2009    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2010   [(const_int 0)]
2011   "ix86_split_long_move (operands); DONE;")
2012
2013 ;; %%% This multiword shite has got to go.
2014 (define_split
2015   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2016         (match_operand:DI 1 "general_operand" ""))]
2017   "!TARGET_64BIT && reload_completed
2018    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2019    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2020   [(const_int 0)]
2021   "ix86_split_long_move (operands); DONE;")
2022
2023 (define_insn "*movdi_1_rex64"
2024   [(set (match_operand:DI 0 "nonimmediate_operand"
2025                 "=r,r  ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
2026         (match_operand:DI 1 "general_operand"
2027                 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
2028   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2029 {
2030   switch (get_attr_type (insn))
2031     {
2032     case TYPE_SSECVT:
2033       if (which_alternative == 13)
2034         return "movq2dq\t{%1, %0|%0, %1}";
2035       else
2036         return "movdq2q\t{%1, %0|%0, %1}";
2037     case TYPE_SSEMOV:
2038       if (get_attr_mode (insn) == MODE_TI)
2039           return "movdqa\t{%1, %0|%0, %1}";
2040       /* FALLTHRU */
2041     case TYPE_MMXMOV:
2042       /* Moves from and into integer register is done using movd opcode with
2043          REX prefix.  */
2044       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2045           return "movd\t{%1, %0|%0, %1}";
2046       return "movq\t{%1, %0|%0, %1}";
2047     case TYPE_SSELOG1:
2048     case TYPE_MMXADD:
2049       return "pxor\t%0, %0";
2050     case TYPE_MULTI:
2051       return "#";
2052     case TYPE_LEA:
2053       return "lea{q}\t{%a1, %0|%0, %a1}";
2054     default:
2055       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2056       if (get_attr_mode (insn) == MODE_SI)
2057         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2058       else if (which_alternative == 2)
2059         return "movabs{q}\t{%1, %0|%0, %1}";
2060       else
2061         return "mov{q}\t{%1, %0|%0, %1}";
2062     }
2063 }
2064   [(set (attr "type")
2065      (cond [(eq_attr "alternative" "5")
2066               (const_string "mmxadd")
2067             (eq_attr "alternative" "6,7,8")
2068               (const_string "mmxmov")
2069             (eq_attr "alternative" "9")
2070               (const_string "sselog1")
2071             (eq_attr "alternative" "10,11,12")
2072               (const_string "ssemov")
2073             (eq_attr "alternative" "13,14")
2074               (const_string "ssecvt")
2075             (eq_attr "alternative" "4")
2076               (const_string "multi")
2077             (match_operand:DI 1 "pic_32bit_operand" "")
2078               (const_string "lea")
2079            ]
2080            (const_string "imov")))
2081    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2082    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2083    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2084
2085 ;; Stores and loads of ax to arbitrary constant address.
2086 ;; We fake an second form of instruction to force reload to load address
2087 ;; into register when rax is not available
2088 (define_insn "*movabsdi_1_rex64"
2089   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2090         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2091   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2092   "@
2093    movabs{q}\t{%1, %P0|%P0, %1}
2094    mov{q}\t{%1, %a0|%a0, %1}"
2095   [(set_attr "type" "imov")
2096    (set_attr "modrm" "0,*")
2097    (set_attr "length_address" "8,0")
2098    (set_attr "length_immediate" "0,*")
2099    (set_attr "memory" "store")
2100    (set_attr "mode" "DI")])
2101
2102 (define_insn "*movabsdi_2_rex64"
2103   [(set (match_operand:DI 0 "register_operand" "=a,r")
2104         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2105   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2106   "@
2107    movabs{q}\t{%P1, %0|%0, %P1}
2108    mov{q}\t{%a1, %0|%0, %a1}"
2109   [(set_attr "type" "imov")
2110    (set_attr "modrm" "0,*")
2111    (set_attr "length_address" "8,0")
2112    (set_attr "length_immediate" "0")
2113    (set_attr "memory" "load")
2114    (set_attr "mode" "DI")])
2115
2116 ;; Convert impossible stores of immediate to existing instructions.
2117 ;; First try to get scratch register and go through it.  In case this
2118 ;; fails, move by 32bit parts.
2119 (define_peephole2
2120   [(match_scratch:DI 2 "r")
2121    (set (match_operand:DI 0 "memory_operand" "")
2122         (match_operand:DI 1 "immediate_operand" ""))]
2123   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2124    && !x86_64_immediate_operand (operands[1], DImode)"
2125   [(set (match_dup 2) (match_dup 1))
2126    (set (match_dup 0) (match_dup 2))]
2127   "")
2128
2129 ;; We need to define this as both peepholer and splitter for case
2130 ;; peephole2 pass is not run.
2131 ;; "&& 1" is needed to keep it from matching the previous pattern.
2132 (define_peephole2
2133   [(set (match_operand:DI 0 "memory_operand" "")
2134         (match_operand:DI 1 "immediate_operand" ""))]
2135   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2136    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2137   [(set (match_dup 2) (match_dup 3))
2138    (set (match_dup 4) (match_dup 5))]
2139   "split_di (operands, 2, operands + 2, operands + 4);")
2140
2141 (define_split
2142   [(set (match_operand:DI 0 "memory_operand" "")
2143         (match_operand:DI 1 "immediate_operand" ""))]
2144   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2145                     ? flow2_completed : reload_completed)
2146    && !symbolic_operand (operands[1], DImode)
2147    && !x86_64_immediate_operand (operands[1], DImode)"
2148   [(set (match_dup 2) (match_dup 3))
2149    (set (match_dup 4) (match_dup 5))]
2150   "split_di (operands, 2, operands + 2, operands + 4);")
2151
2152 (define_insn "*swapdi_rex64"
2153   [(set (match_operand:DI 0 "register_operand" "+r")
2154         (match_operand:DI 1 "register_operand" "+r"))
2155    (set (match_dup 1)
2156         (match_dup 0))]
2157   "TARGET_64BIT"
2158   "xchg{q}\t%1, %0"
2159   [(set_attr "type" "imov")
2160    (set_attr "mode" "DI")
2161    (set_attr "pent_pair" "np")
2162    (set_attr "athlon_decode" "vector")
2163    (set_attr "amdfam10_decode" "double")])   
2164
2165 (define_expand "movti"
2166   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2167         (match_operand:TI 1 "nonimmediate_operand" ""))]
2168   "TARGET_SSE || TARGET_64BIT"
2169 {
2170   if (TARGET_64BIT)
2171     ix86_expand_move (TImode, operands);
2172   else
2173     ix86_expand_vector_move (TImode, operands);
2174   DONE;
2175 })
2176
2177 (define_insn "*movti_internal"
2178   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2179         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2180   "TARGET_SSE && !TARGET_64BIT
2181    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2182 {
2183   switch (which_alternative)
2184     {
2185     case 0:
2186       if (get_attr_mode (insn) == MODE_V4SF)
2187         return "xorps\t%0, %0";
2188       else
2189         return "pxor\t%0, %0";
2190     case 1:
2191     case 2:
2192       if (get_attr_mode (insn) == MODE_V4SF)
2193         return "movaps\t{%1, %0|%0, %1}";
2194       else
2195         return "movdqa\t{%1, %0|%0, %1}";
2196     default:
2197       gcc_unreachable ();
2198     }
2199 }
2200   [(set_attr "type" "sselog1,ssemov,ssemov")
2201    (set (attr "mode")
2202         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2203                     (ne (symbol_ref "optimize_size") (const_int 0)))
2204                  (const_string "V4SF")
2205                (and (eq_attr "alternative" "2")
2206                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2207                         (const_int 0)))
2208                  (const_string "V4SF")]
2209               (const_string "TI")))])
2210
2211 (define_insn "*movti_rex64"
2212   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2213         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2214   "TARGET_64BIT
2215    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2216 {
2217   switch (which_alternative)
2218     {
2219     case 0:
2220     case 1:
2221       return "#";
2222     case 2:
2223       if (get_attr_mode (insn) == MODE_V4SF)
2224         return "xorps\t%0, %0";
2225       else
2226         return "pxor\t%0, %0";
2227     case 3:
2228     case 4:
2229       if (get_attr_mode (insn) == MODE_V4SF)
2230         return "movaps\t{%1, %0|%0, %1}";
2231       else
2232         return "movdqa\t{%1, %0|%0, %1}";
2233     default:
2234       gcc_unreachable ();
2235     }
2236 }
2237   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2238    (set (attr "mode")
2239         (cond [(eq_attr "alternative" "2,3")
2240                  (if_then_else
2241                    (ne (symbol_ref "optimize_size")
2242                        (const_int 0))
2243                    (const_string "V4SF")
2244                    (const_string "TI"))
2245                (eq_attr "alternative" "4")
2246                  (if_then_else
2247                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2248                             (const_int 0))
2249                         (ne (symbol_ref "optimize_size")
2250                             (const_int 0)))
2251                    (const_string "V4SF")
2252                    (const_string "TI"))]
2253                (const_string "DI")))])
2254
2255 (define_split
2256   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2257         (match_operand:TI 1 "general_operand" ""))]
2258   "reload_completed && !SSE_REG_P (operands[0])
2259    && !SSE_REG_P (operands[1])"
2260   [(const_int 0)]
2261   "ix86_split_long_move (operands); DONE;")
2262
2263 (define_expand "movsf"
2264   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2265         (match_operand:SF 1 "general_operand" ""))]
2266   ""
2267   "ix86_expand_move (SFmode, operands); DONE;")
2268
2269 (define_insn "*pushsf"
2270   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2271         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2272   "!TARGET_64BIT"
2273 {
2274   /* Anything else should be already split before reg-stack.  */
2275   gcc_assert (which_alternative == 1);
2276   return "push{l}\t%1";
2277 }
2278   [(set_attr "type" "multi,push,multi")
2279    (set_attr "unit" "i387,*,*")
2280    (set_attr "mode" "SF,SI,SF")])
2281
2282 (define_insn "*pushsf_rex64"
2283   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2284         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2285   "TARGET_64BIT"
2286 {
2287   /* Anything else should be already split before reg-stack.  */
2288   gcc_assert (which_alternative == 1);
2289   return "push{q}\t%q1";
2290 }
2291   [(set_attr "type" "multi,push,multi")
2292    (set_attr "unit" "i387,*,*")
2293    (set_attr "mode" "SF,DI,SF")])
2294
2295 (define_split
2296   [(set (match_operand:SF 0 "push_operand" "")
2297         (match_operand:SF 1 "memory_operand" ""))]
2298   "reload_completed
2299    && MEM_P (operands[1])
2300    && constant_pool_reference_p (operands[1])"
2301   [(set (match_dup 0)
2302         (match_dup 1))]
2303   "operands[1] = avoid_constant_pool_reference (operands[1]);")
2304
2305
2306 ;; %%% Kill this when call knows how to work this out.
2307 (define_split
2308   [(set (match_operand:SF 0 "push_operand" "")
2309         (match_operand:SF 1 "any_fp_register_operand" ""))]
2310   "!TARGET_64BIT"
2311   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2312    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2313
2314 (define_split
2315   [(set (match_operand:SF 0 "push_operand" "")
2316         (match_operand:SF 1 "any_fp_register_operand" ""))]
2317   "TARGET_64BIT"
2318   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2319    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2320
2321 (define_insn "*movsf_1"
2322   [(set (match_operand:SF 0 "nonimmediate_operand"
2323           "=f,m   ,f,r  ,m    ,x,x,x ,m   ,!*y,!rm,!*y")
2324         (match_operand:SF 1 "general_operand"
2325           "fm,f,G   ,rmF,Fr,C   ,x   ,xm,x,rm ,*y ,*y"))]
2326   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2327    && (reload_in_progress || reload_completed
2328        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2329        || (!TARGET_SSE_MATH && optimize_size
2330            && standard_80387_constant_p (operands[1]))
2331        || GET_CODE (operands[1]) != CONST_DOUBLE
2332        || memory_operand (operands[0], SFmode))"
2333 {
2334   switch (which_alternative)
2335     {
2336     case 0:
2337       return output_387_reg_move (insn, operands);
2338
2339     case 1:
2340       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2341         return "fstp%z0\t%y0";
2342       else
2343         return "fst%z0\t%y0";
2344
2345     case 2:
2346       return standard_80387_constant_opcode (operands[1]);
2347
2348     case 3:
2349     case 4:
2350       return "mov{l}\t{%1, %0|%0, %1}";
2351     case 5:
2352       if (get_attr_mode (insn) == MODE_TI)
2353         return "pxor\t%0, %0";
2354       else
2355         return "xorps\t%0, %0";
2356     case 6:
2357       if (get_attr_mode (insn) == MODE_V4SF)
2358         return "movaps\t{%1, %0|%0, %1}";
2359       else
2360         return "movss\t{%1, %0|%0, %1}";
2361     case 7:
2362     case 8:
2363       return "movss\t{%1, %0|%0, %1}";
2364
2365     case 9:
2366     case 10:
2367       return "movd\t{%1, %0|%0, %1}";
2368
2369     case 11:
2370       return "movq\t{%1, %0|%0, %1}";
2371
2372     default:
2373       gcc_unreachable ();
2374     }
2375 }
2376   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2377    (set (attr "mode")
2378         (cond [(eq_attr "alternative" "3,4,9,10")
2379                  (const_string "SI")
2380                (eq_attr "alternative" "5")
2381                  (if_then_else
2382                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2383                                  (const_int 0))
2384                              (ne (symbol_ref "TARGET_SSE2")
2385                                  (const_int 0)))
2386                         (eq (symbol_ref "optimize_size")
2387                             (const_int 0)))
2388                    (const_string "TI")
2389                    (const_string "V4SF"))
2390                /* For architectures resolving dependencies on
2391                   whole SSE registers use APS move to break dependency
2392                   chains, otherwise use short move to avoid extra work.
2393
2394                   Do the same for architectures resolving dependencies on
2395                   the parts.  While in DF mode it is better to always handle
2396                   just register parts, the SF mode is different due to lack
2397                   of instructions to load just part of the register.  It is
2398                   better to maintain the whole registers in single format
2399                   to avoid problems on using packed logical operations.  */
2400                (eq_attr "alternative" "6")
2401                  (if_then_else
2402                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2403                             (const_int 0))
2404                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2405                             (const_int 0)))
2406                    (const_string "V4SF")
2407                    (const_string "SF"))
2408                (eq_attr "alternative" "11")
2409                  (const_string "DI")]
2410                (const_string "SF")))])
2411
2412 (define_insn "*swapsf"
2413   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2414         (match_operand:SF 1 "fp_register_operand" "+f"))
2415    (set (match_dup 1)
2416         (match_dup 0))]
2417   "reload_completed || TARGET_80387"
2418 {
2419   if (STACK_TOP_P (operands[0]))
2420     return "fxch\t%1";
2421   else
2422     return "fxch\t%0";
2423 }
2424   [(set_attr "type" "fxch")
2425    (set_attr "mode" "SF")])
2426
2427 (define_expand "movdf"
2428   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2429         (match_operand:DF 1 "general_operand" ""))]
2430   ""
2431   "ix86_expand_move (DFmode, operands); DONE;")
2432
2433 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2434 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2435 ;; On the average, pushdf using integers can be still shorter.  Allow this
2436 ;; pattern for optimize_size too.
2437
2438 (define_insn "*pushdf_nointeger"
2439   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2440         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2441   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2442 {
2443   /* This insn should be already split before reg-stack.  */
2444   gcc_unreachable ();
2445 }
2446   [(set_attr "type" "multi")
2447    (set_attr "unit" "i387,*,*,*")
2448    (set_attr "mode" "DF,SI,SI,DF")])
2449
2450 (define_insn "*pushdf_integer"
2451   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2452         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2453   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2454 {
2455   /* This insn should be already split before reg-stack.  */
2456   gcc_unreachable ();
2457 }
2458   [(set_attr "type" "multi")
2459    (set_attr "unit" "i387,*,*")
2460    (set_attr "mode" "DF,SI,DF")])
2461
2462 ;; %%% Kill this when call knows how to work this out.
2463 (define_split
2464   [(set (match_operand:DF 0 "push_operand" "")
2465         (match_operand:DF 1 "any_fp_register_operand" ""))]
2466   "!TARGET_64BIT && reload_completed"
2467   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2468    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2469   "")
2470
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:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2476    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2477   "")
2478
2479 (define_split
2480   [(set (match_operand:DF 0 "push_operand" "")
2481         (match_operand:DF 1 "general_operand" ""))]
2482   "reload_completed"
2483   [(const_int 0)]
2484   "ix86_split_long_move (operands); DONE;")
2485
2486 ;; Moving is usually shorter when only FP registers are used. This separate
2487 ;; movdf pattern avoids the use of integer registers for FP operations
2488 ;; when optimizing for size.
2489
2490 (define_insn "*movdf_nointeger"
2491   [(set (match_operand:DF 0 "nonimmediate_operand"
2492                         "=f,m,f,*r  ,o  ,Y*x,Y*x,Y*x ,m  ")
2493         (match_operand:DF 1 "general_operand"
2494                         "fm,f,G,*roF,F*r,C  ,Y*x,mY*x,Y*x"))]
2495   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2496    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2497    && (reload_in_progress || reload_completed
2498        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2499        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2500            && standard_80387_constant_p (operands[1]))
2501        || GET_CODE (operands[1]) != CONST_DOUBLE
2502        || memory_operand (operands[0], DFmode))"
2503 {
2504   switch (which_alternative)
2505     {
2506     case 0:
2507       return output_387_reg_move (insn, operands);
2508
2509     case 1:
2510       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2511         return "fstp%z0\t%y0";
2512       else
2513         return "fst%z0\t%y0";
2514
2515     case 2:
2516       return standard_80387_constant_opcode (operands[1]);
2517
2518     case 3:
2519     case 4:
2520       return "#";
2521     case 5:
2522       switch (get_attr_mode (insn))
2523         {
2524         case MODE_V4SF:
2525           return "xorps\t%0, %0";
2526         case MODE_V2DF:
2527           return "xorpd\t%0, %0";
2528         case MODE_TI:
2529           return "pxor\t%0, %0";
2530         default:
2531           gcc_unreachable ();
2532         }
2533     case 6:
2534     case 7:
2535     case 8:
2536       switch (get_attr_mode (insn))
2537         {
2538         case MODE_V4SF:
2539           return "movaps\t{%1, %0|%0, %1}";
2540         case MODE_V2DF:
2541           return "movapd\t{%1, %0|%0, %1}";
2542         case MODE_TI:
2543           return "movdqa\t{%1, %0|%0, %1}";
2544         case MODE_DI:
2545           return "movq\t{%1, %0|%0, %1}";
2546         case MODE_DF:
2547           return "movsd\t{%1, %0|%0, %1}";
2548         case MODE_V1DF:
2549           return "movlpd\t{%1, %0|%0, %1}";
2550         case MODE_V2SF:
2551           return "movlps\t{%1, %0|%0, %1}";
2552         default:
2553           gcc_unreachable ();
2554         }
2555
2556     default:
2557       gcc_unreachable ();
2558     }
2559 }
2560   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2561    (set (attr "mode")
2562         (cond [(eq_attr "alternative" "0,1,2")
2563                  (const_string "DF")
2564                (eq_attr "alternative" "3,4")
2565                  (const_string "SI")
2566
2567                /* For SSE1, we have many fewer alternatives.  */
2568                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2569                  (cond [(eq_attr "alternative" "5,6")
2570                           (const_string "V4SF")
2571                        ]
2572                    (const_string "V2SF"))
2573
2574                /* xorps is one byte shorter.  */
2575                (eq_attr "alternative" "5")
2576                  (cond [(ne (symbol_ref "optimize_size")
2577                             (const_int 0))
2578                           (const_string "V4SF")
2579                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2580                             (const_int 0))
2581                           (const_string "TI")
2582                        ]
2583                        (const_string "V2DF"))
2584
2585                /* For architectures resolving dependencies on
2586                   whole SSE registers use APD move to break dependency
2587                   chains, otherwise use short move to avoid extra work.
2588
2589                   movaps encodes one byte shorter.  */
2590                (eq_attr "alternative" "6")
2591                  (cond
2592                    [(ne (symbol_ref "optimize_size")
2593                         (const_int 0))
2594                       (const_string "V4SF")
2595                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2596                         (const_int 0))
2597                       (const_string "V2DF")
2598                    ]
2599                    (const_string "DF"))
2600                /* For architectures resolving dependencies on register
2601                   parts we may avoid extra work to zero out upper part
2602                   of register.  */
2603                (eq_attr "alternative" "7")
2604                  (if_then_else
2605                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2606                        (const_int 0))
2607                    (const_string "V1DF")
2608                    (const_string "DF"))
2609               ]
2610               (const_string "DF")))])
2611
2612 (define_insn "*movdf_integer"
2613   [(set (match_operand:DF 0 "nonimmediate_operand"
2614                 "=f,m,f,r  ,o ,Y*x,Y*x,Y*x,m  ")
2615         (match_operand:DF 1 "general_operand"
2616                 "fm,f,G,roF,Fr,C  ,Y*x,m  ,Y*x"))]
2617   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2618    && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2619    && (reload_in_progress || reload_completed
2620        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2621        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2622            && standard_80387_constant_p (operands[1]))
2623        || GET_CODE (operands[1]) != CONST_DOUBLE
2624        || memory_operand (operands[0], DFmode))"
2625 {
2626   switch (which_alternative)
2627     {
2628     case 0:
2629       return output_387_reg_move (insn, operands);
2630
2631     case 1:
2632       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2633         return "fstp%z0\t%y0";
2634       else
2635         return "fst%z0\t%y0";
2636
2637     case 2:
2638       return standard_80387_constant_opcode (operands[1]);
2639
2640     case 3:
2641     case 4:
2642       return "#";
2643
2644     case 5:
2645       switch (get_attr_mode (insn))
2646         {
2647         case MODE_V4SF:
2648           return "xorps\t%0, %0";
2649         case MODE_V2DF:
2650           return "xorpd\t%0, %0";
2651         case MODE_TI:
2652           return "pxor\t%0, %0";
2653         default:
2654           gcc_unreachable ();
2655         }
2656     case 6:
2657     case 7:
2658     case 8:
2659       switch (get_attr_mode (insn))
2660         {
2661         case MODE_V4SF:
2662           return "movaps\t{%1, %0|%0, %1}";
2663         case MODE_V2DF:
2664           return "movapd\t{%1, %0|%0, %1}";
2665         case MODE_TI:
2666           return "movdqa\t{%1, %0|%0, %1}";
2667         case MODE_DI:
2668           return "movq\t{%1, %0|%0, %1}";
2669         case MODE_DF:
2670           return "movsd\t{%1, %0|%0, %1}";
2671         case MODE_V1DF:
2672           return "movlpd\t{%1, %0|%0, %1}";
2673         case MODE_V2SF:
2674           return "movlps\t{%1, %0|%0, %1}";
2675         default:
2676           gcc_unreachable ();
2677         }
2678
2679     default:
2680       gcc_unreachable();
2681     }
2682 }
2683   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2684    (set (attr "mode")
2685         (cond [(eq_attr "alternative" "0,1,2")
2686                  (const_string "DF")
2687                (eq_attr "alternative" "3,4")
2688                  (const_string "SI")
2689
2690                /* For SSE1, we have many fewer alternatives.  */
2691                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2692                  (cond [(eq_attr "alternative" "5,6")
2693                           (const_string "V4SF")
2694                        ]
2695                    (const_string "V2SF"))
2696
2697                /* xorps is one byte shorter.  */
2698                (eq_attr "alternative" "5")
2699                  (cond [(ne (symbol_ref "optimize_size")
2700                             (const_int 0))
2701                           (const_string "V4SF")
2702                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2703                             (const_int 0))
2704                           (const_string "TI")
2705                        ]
2706                        (const_string "V2DF"))
2707
2708                /* For architectures resolving dependencies on
2709                   whole SSE registers use APD move to break dependency
2710                   chains, otherwise use short move to avoid extra work.
2711
2712                   movaps encodes one byte shorter.  */
2713                (eq_attr "alternative" "6")
2714                  (cond
2715                    [(ne (symbol_ref "optimize_size")
2716                         (const_int 0))
2717                       (const_string "V4SF")
2718                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2719                         (const_int 0))
2720                       (const_string "V2DF")
2721                    ]
2722                    (const_string "DF"))
2723                /* For architectures resolving dependencies on register
2724                   parts we may avoid extra work to zero out upper part
2725                   of register.  */
2726                (eq_attr "alternative" "7")
2727                  (if_then_else
2728                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2729                        (const_int 0))
2730                    (const_string "V1DF")
2731                    (const_string "DF"))
2732               ]
2733               (const_string "DF")))])
2734
2735 (define_split
2736   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2737         (match_operand:DF 1 "general_operand" ""))]
2738   "reload_completed
2739    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2740    && ! (ANY_FP_REG_P (operands[0]) ||
2741          (GET_CODE (operands[0]) == SUBREG
2742           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2743    && ! (ANY_FP_REG_P (operands[1]) ||
2744          (GET_CODE (operands[1]) == SUBREG
2745           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2746   [(const_int 0)]
2747   "ix86_split_long_move (operands); DONE;")
2748
2749 (define_insn "*swapdf"
2750   [(set (match_operand:DF 0 "fp_register_operand" "+f")
2751         (match_operand:DF 1 "fp_register_operand" "+f"))
2752    (set (match_dup 1)
2753         (match_dup 0))]
2754   "reload_completed || TARGET_80387"
2755 {
2756   if (STACK_TOP_P (operands[0]))
2757     return "fxch\t%1";
2758   else
2759     return "fxch\t%0";
2760 }
2761   [(set_attr "type" "fxch")
2762    (set_attr "mode" "DF")])
2763
2764 (define_expand "movxf"
2765   [(set (match_operand:XF 0 "nonimmediate_operand" "")
2766         (match_operand:XF 1 "general_operand" ""))]
2767   ""
2768   "ix86_expand_move (XFmode, operands); DONE;")
2769
2770 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2771 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2772 ;; Pushing using integer instructions is longer except for constants
2773 ;; and direct memory references.
2774 ;; (assuming that any given constant is pushed only once, but this ought to be
2775 ;;  handled elsewhere).
2776
2777 (define_insn "*pushxf_nointeger"
2778   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2779         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2780   "optimize_size"
2781 {
2782   /* This insn should be already split before reg-stack.  */
2783   gcc_unreachable ();
2784 }
2785   [(set_attr "type" "multi")
2786    (set_attr "unit" "i387,*,*")
2787    (set_attr "mode" "XF,SI,SI")])
2788
2789 (define_insn "*pushxf_integer"
2790   [(set (match_operand:XF 0 "push_operand" "=<,<")
2791         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2792   "!optimize_size"
2793 {
2794   /* This insn should be already split before reg-stack.  */
2795   gcc_unreachable ();
2796 }
2797   [(set_attr "type" "multi")
2798    (set_attr "unit" "i387,*")
2799    (set_attr "mode" "XF,SI")])
2800
2801 (define_split
2802   [(set (match_operand 0 "push_operand" "")
2803         (match_operand 1 "general_operand" ""))]
2804   "reload_completed
2805    && (GET_MODE (operands[0]) == XFmode
2806        || GET_MODE (operands[0]) == DFmode)
2807    && !ANY_FP_REG_P (operands[1])"
2808   [(const_int 0)]
2809   "ix86_split_long_move (operands); DONE;")
2810
2811 (define_split
2812   [(set (match_operand:XF 0 "push_operand" "")
2813         (match_operand:XF 1 "any_fp_register_operand" ""))]
2814   "!TARGET_64BIT"
2815   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2816    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2817   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2818
2819 (define_split
2820   [(set (match_operand:XF 0 "push_operand" "")
2821         (match_operand:XF 1 "any_fp_register_operand" ""))]
2822   "TARGET_64BIT"
2823   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2824    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2825   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2826
2827 ;; Do not use integer registers when optimizing for size
2828 (define_insn "*movxf_nointeger"
2829   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2830         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2831   "optimize_size
2832    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2833    && (reload_in_progress || reload_completed
2834        || (optimize_size && standard_80387_constant_p (operands[1]))
2835        || GET_CODE (operands[1]) != CONST_DOUBLE
2836        || memory_operand (operands[0], XFmode))"
2837 {
2838   switch (which_alternative)
2839     {
2840     case 0:
2841       return output_387_reg_move (insn, operands);
2842
2843     case 1:
2844       /* There is no non-popping store to memory for XFmode.  So if
2845          we need one, follow the store with a load.  */
2846       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2847         return "fstp%z0\t%y0\;fld%z0\t%y0";
2848       else
2849         return "fstp%z0\t%y0";
2850
2851     case 2:
2852       return standard_80387_constant_opcode (operands[1]);
2853
2854     case 3: case 4:
2855       return "#";
2856     default:
2857       gcc_unreachable ();
2858     }
2859 }
2860   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2861    (set_attr "mode" "XF,XF,XF,SI,SI")])
2862
2863 (define_insn "*movxf_integer"
2864   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2865         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2866   "!optimize_size
2867    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2868    && (reload_in_progress || reload_completed
2869        || (optimize_size && standard_80387_constant_p (operands[1]))
2870        || GET_CODE (operands[1]) != CONST_DOUBLE
2871        || memory_operand (operands[0], XFmode))"
2872 {
2873   switch (which_alternative)
2874     {
2875     case 0:
2876       return output_387_reg_move (insn, operands);
2877
2878     case 1:
2879       /* There is no non-popping store to memory for XFmode.  So if
2880          we need one, follow the store with a load.  */
2881       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2882         return "fstp%z0\t%y0\;fld%z0\t%y0";
2883       else
2884         return "fstp%z0\t%y0";
2885
2886     case 2:
2887       return standard_80387_constant_opcode (operands[1]);
2888
2889     case 3: case 4:
2890       return "#";
2891
2892     default:
2893       gcc_unreachable ();
2894     }
2895 }
2896   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2897    (set_attr "mode" "XF,XF,XF,SI,SI")])
2898
2899 (define_split
2900   [(set (match_operand 0 "nonimmediate_operand" "")
2901         (match_operand 1 "general_operand" ""))]
2902   "reload_completed
2903    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2904    && GET_MODE (operands[0]) == XFmode
2905    && ! (ANY_FP_REG_P (operands[0]) ||
2906          (GET_CODE (operands[0]) == SUBREG
2907           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2908    && ! (ANY_FP_REG_P (operands[1]) ||
2909          (GET_CODE (operands[1]) == SUBREG
2910           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2911   [(const_int 0)]
2912   "ix86_split_long_move (operands); DONE;")
2913
2914 (define_split
2915   [(set (match_operand 0 "register_operand" "")
2916         (match_operand 1 "memory_operand" ""))]
2917   "reload_completed
2918    && MEM_P (operands[1])
2919    && (GET_MODE (operands[0]) == XFmode
2920        || GET_MODE (operands[0]) == SFmode
2921        || GET_MODE (operands[0]) == DFmode)
2922    && constant_pool_reference_p (operands[1])"
2923   [(set (match_dup 0) (match_dup 1))]
2924 {
2925   rtx c = avoid_constant_pool_reference (operands[1]);
2926   rtx r = operands[0];
2927
2928   if (GET_CODE (r) == SUBREG)
2929     r = SUBREG_REG (r);
2930
2931   if (SSE_REG_P (r))
2932     {
2933       if (!standard_sse_constant_p (c))
2934         FAIL;
2935     }
2936   else if (FP_REG_P (r))
2937     {
2938       if (!standard_80387_constant_p (c))
2939         FAIL;
2940     }
2941   else if (MMX_REG_P (r))
2942     FAIL;
2943
2944   operands[1] = c;
2945 })
2946
2947 (define_split
2948   [(set (match_operand 0 "register_operand" "")
2949         (float_extend (match_operand 1 "memory_operand" "")))]
2950   "reload_completed
2951    && MEM_P (operands[1])
2952    && (GET_MODE (operands[0]) == XFmode
2953        || GET_MODE (operands[0]) == SFmode
2954        || GET_MODE (operands[0]) == DFmode)
2955    && constant_pool_reference_p (operands[1])"
2956   [(set (match_dup 0) (match_dup 1))]
2957 {
2958   rtx c = avoid_constant_pool_reference (SET_SRC (PATTERN (curr_insn)));
2959   rtx r = operands[0];
2960
2961   if (GET_CODE (r) == SUBREG)
2962     r = SUBREG_REG (r);
2963
2964   if (SSE_REG_P (r))
2965     {
2966       if (!standard_sse_constant_p (c))
2967         FAIL;
2968     }
2969   else if (FP_REG_P (r))
2970     {
2971       if (!standard_80387_constant_p (c))
2972         FAIL;
2973     }
2974   else if (MMX_REG_P (r))
2975     FAIL;
2976
2977   operands[1] = c;
2978 })
2979
2980 (define_insn "swapxf"
2981   [(set (match_operand:XF 0 "register_operand" "+f")
2982         (match_operand:XF 1 "register_operand" "+f"))
2983    (set (match_dup 1)
2984         (match_dup 0))]
2985   "TARGET_80387"
2986 {
2987   if (STACK_TOP_P (operands[0]))
2988     return "fxch\t%1";
2989   else
2990     return "fxch\t%0";
2991 }
2992   [(set_attr "type" "fxch")
2993    (set_attr "mode" "XF")])
2994
2995 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
2996 (define_split
2997   [(set (match_operand:X87MODEF 0 "register_operand" "")
2998         (match_operand:X87MODEF 1 "immediate_operand" ""))]
2999   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3000    && (standard_80387_constant_p (operands[1]) == 8
3001        || standard_80387_constant_p (operands[1]) == 9)"
3002   [(set (match_dup 0)(match_dup 1))
3003    (set (match_dup 0)
3004         (neg:X87MODEF (match_dup 0)))]
3005 {
3006   REAL_VALUE_TYPE r;
3007
3008   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3009   if (real_isnegzero (&r))
3010     operands[1] = CONST0_RTX (<MODE>mode);
3011   else
3012     operands[1] = CONST1_RTX (<MODE>mode);
3013 })
3014
3015 (define_expand "movtf"
3016   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3017         (match_operand:TF 1 "nonimmediate_operand" ""))]
3018   "TARGET_64BIT"
3019 {
3020   ix86_expand_move (TFmode, operands);
3021   DONE;
3022 })
3023
3024 (define_insn "*movtf_internal"
3025   [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3026         (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3027   "TARGET_64BIT
3028    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3029 {
3030   switch (which_alternative)
3031     {
3032     case 0:
3033     case 1:
3034       return "#";
3035     case 2:
3036       if (get_attr_mode (insn) == MODE_V4SF)
3037         return "xorps\t%0, %0";
3038       else
3039         return "pxor\t%0, %0";
3040     case 3:
3041     case 4:
3042       if (get_attr_mode (insn) == MODE_V4SF)
3043         return "movaps\t{%1, %0|%0, %1}";
3044       else
3045         return "movdqa\t{%1, %0|%0, %1}";
3046     default:
3047       gcc_unreachable ();
3048     }
3049 }
3050   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3051    (set (attr "mode")
3052         (cond [(eq_attr "alternative" "2,3")
3053                  (if_then_else
3054                    (ne (symbol_ref "optimize_size")
3055                        (const_int 0))
3056                    (const_string "V4SF")
3057                    (const_string "TI"))
3058                (eq_attr "alternative" "4")
3059                  (if_then_else
3060                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3061                             (const_int 0))
3062                         (ne (symbol_ref "optimize_size")
3063                             (const_int 0)))
3064                    (const_string "V4SF")
3065                    (const_string "TI"))]
3066                (const_string "DI")))])
3067
3068 (define_split
3069   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3070         (match_operand:TF 1 "general_operand" ""))]
3071   "reload_completed && !SSE_REG_P (operands[0])
3072    && !SSE_REG_P (operands[1])"
3073   [(const_int 0)]
3074   "ix86_split_long_move (operands); DONE;")
3075 \f
3076 ;; Zero extension instructions
3077
3078 (define_expand "zero_extendhisi2"
3079   [(set (match_operand:SI 0 "register_operand" "")
3080      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3081   ""
3082 {
3083   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3084     {
3085       operands[1] = force_reg (HImode, operands[1]);
3086       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3087       DONE;
3088     }
3089 })
3090
3091 (define_insn "zero_extendhisi2_and"
3092   [(set (match_operand:SI 0 "register_operand" "=r")
3093      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3094    (clobber (reg:CC FLAGS_REG))]
3095   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3096   "#"
3097   [(set_attr "type" "alu1")
3098    (set_attr "mode" "SI")])
3099
3100 (define_split
3101   [(set (match_operand:SI 0 "register_operand" "")
3102         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3103    (clobber (reg:CC FLAGS_REG))]
3104   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3105   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3106               (clobber (reg:CC FLAGS_REG))])]
3107   "")
3108
3109 (define_insn "*zero_extendhisi2_movzwl"
3110   [(set (match_operand:SI 0 "register_operand" "=r")
3111      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3112   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3113   "movz{wl|x}\t{%1, %0|%0, %1}"
3114   [(set_attr "type" "imovx")
3115    (set_attr "mode" "SI")])
3116
3117 (define_expand "zero_extendqihi2"
3118   [(parallel
3119     [(set (match_operand:HI 0 "register_operand" "")
3120        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3121      (clobber (reg:CC FLAGS_REG))])]
3122   ""
3123   "")
3124
3125 (define_insn "*zero_extendqihi2_and"
3126   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3127      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3128    (clobber (reg:CC FLAGS_REG))]
3129   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3130   "#"
3131   [(set_attr "type" "alu1")
3132    (set_attr "mode" "HI")])
3133
3134 (define_insn "*zero_extendqihi2_movzbw_and"
3135   [(set (match_operand:HI 0 "register_operand" "=r,r")
3136      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3137    (clobber (reg:CC FLAGS_REG))]
3138   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3139   "#"
3140   [(set_attr "type" "imovx,alu1")
3141    (set_attr "mode" "HI")])
3142
3143 ; zero extend to SImode here to avoid partial register stalls
3144 (define_insn "*zero_extendqihi2_movzbl"
3145   [(set (match_operand:HI 0 "register_operand" "=r")
3146      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3147   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3148   "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3149   [(set_attr "type" "imovx")
3150    (set_attr "mode" "SI")])
3151
3152 ;; For the movzbw case strip only the clobber
3153 (define_split
3154   [(set (match_operand:HI 0 "register_operand" "")
3155         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3156    (clobber (reg:CC FLAGS_REG))]
3157   "reload_completed
3158    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3159    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3160   [(set (match_operand:HI 0 "register_operand" "")
3161         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3162
3163 ;; When source and destination does not overlap, clear destination
3164 ;; first and then do the movb
3165 (define_split
3166   [(set (match_operand:HI 0 "register_operand" "")
3167         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3168    (clobber (reg:CC FLAGS_REG))]
3169   "reload_completed
3170    && ANY_QI_REG_P (operands[0])
3171    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3172    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3173   [(set (match_dup 0) (const_int 0))
3174    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3175   "operands[2] = gen_lowpart (QImode, operands[0]);")
3176
3177 ;; Rest is handled by single and.
3178 (define_split
3179   [(set (match_operand:HI 0 "register_operand" "")
3180         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3181    (clobber (reg:CC FLAGS_REG))]
3182   "reload_completed
3183    && true_regnum (operands[0]) == true_regnum (operands[1])"
3184   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3185               (clobber (reg:CC FLAGS_REG))])]
3186   "")
3187
3188 (define_expand "zero_extendqisi2"
3189   [(parallel
3190     [(set (match_operand:SI 0 "register_operand" "")
3191        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3192      (clobber (reg:CC FLAGS_REG))])]
3193   ""
3194   "")
3195
3196 (define_insn "*zero_extendqisi2_and"
3197   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3198      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3199    (clobber (reg:CC FLAGS_REG))]
3200   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3201   "#"
3202   [(set_attr "type" "alu1")
3203    (set_attr "mode" "SI")])
3204
3205 (define_insn "*zero_extendqisi2_movzbw_and"
3206   [(set (match_operand:SI 0 "register_operand" "=r,r")
3207      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3208    (clobber (reg:CC FLAGS_REG))]
3209   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3210   "#"
3211   [(set_attr "type" "imovx,alu1")
3212    (set_attr "mode" "SI")])
3213
3214 (define_insn "*zero_extendqisi2_movzbw"
3215   [(set (match_operand:SI 0 "register_operand" "=r")
3216      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3217   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3218   "movz{bl|x}\t{%1, %0|%0, %1}"
3219   [(set_attr "type" "imovx")
3220    (set_attr "mode" "SI")])
3221
3222 ;; For the movzbl case strip only the clobber
3223 (define_split
3224   [(set (match_operand:SI 0 "register_operand" "")
3225         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3226    (clobber (reg:CC FLAGS_REG))]
3227   "reload_completed
3228    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3229    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3230   [(set (match_dup 0)
3231         (zero_extend:SI (match_dup 1)))])
3232
3233 ;; When source and destination does not overlap, clear destination
3234 ;; first and then do the movb
3235 (define_split
3236   [(set (match_operand:SI 0 "register_operand" "")
3237         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3238    (clobber (reg:CC FLAGS_REG))]
3239   "reload_completed
3240    && ANY_QI_REG_P (operands[0])
3241    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3242    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3243    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3244   [(set (match_dup 0) (const_int 0))
3245    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3246   "operands[2] = gen_lowpart (QImode, operands[0]);")
3247
3248 ;; Rest is handled by single and.
3249 (define_split
3250   [(set (match_operand:SI 0 "register_operand" "")
3251         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3252    (clobber (reg:CC FLAGS_REG))]
3253   "reload_completed
3254    && true_regnum (operands[0]) == true_regnum (operands[1])"
3255   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3256               (clobber (reg:CC FLAGS_REG))])]
3257   "")
3258
3259 ;; %%% Kill me once multi-word ops are sane.
3260 (define_expand "zero_extendsidi2"
3261   [(set (match_operand:DI 0 "register_operand" "=r")
3262      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3263   ""
3264   "if (!TARGET_64BIT)
3265      {
3266        emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3267        DONE;
3268      }
3269   ")
3270
3271 (define_insn "zero_extendsidi2_32"
3272   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3273         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3274    (clobber (reg:CC FLAGS_REG))]
3275   "!TARGET_64BIT"
3276   "@
3277    #
3278    #
3279    #
3280    movd\t{%1, %0|%0, %1}
3281    movd\t{%1, %0|%0, %1}"
3282   [(set_attr "mode" "SI,SI,SI,DI,TI")
3283    (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3284
3285 (define_insn "zero_extendsidi2_rex64"
3286   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3287      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3288   "TARGET_64BIT"
3289   "@
3290    mov\t{%k1, %k0|%k0, %k1}
3291    #
3292    movd\t{%1, %0|%0, %1}
3293    movd\t{%1, %0|%0, %1}"
3294   [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3295    (set_attr "mode" "SI,DI,SI,SI")])
3296
3297 (define_split
3298   [(set (match_operand:DI 0 "memory_operand" "")
3299      (zero_extend:DI (match_dup 0)))]
3300   "TARGET_64BIT"
3301   [(set (match_dup 4) (const_int 0))]
3302   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3303
3304 (define_split
3305   [(set (match_operand:DI 0 "register_operand" "")
3306         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3307    (clobber (reg:CC FLAGS_REG))]
3308   "!TARGET_64BIT && reload_completed
3309    && true_regnum (operands[0]) == true_regnum (operands[1])"
3310   [(set (match_dup 4) (const_int 0))]
3311   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3312
3313 (define_split
3314   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3315         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3316    (clobber (reg:CC FLAGS_REG))]
3317   "!TARGET_64BIT && reload_completed
3318    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3319   [(set (match_dup 3) (match_dup 1))
3320    (set (match_dup 4) (const_int 0))]
3321   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3322
3323 (define_insn "zero_extendhidi2"
3324   [(set (match_operand:DI 0 "register_operand" "=r")
3325      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3326   "TARGET_64BIT"
3327   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3328   [(set_attr "type" "imovx")
3329    (set_attr "mode" "DI")])
3330
3331 (define_insn "zero_extendqidi2"
3332   [(set (match_operand:DI 0 "register_operand" "=r")
3333      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3334   "TARGET_64BIT"
3335   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3336   [(set_attr "type" "imovx")
3337    (set_attr "mode" "DI")])
3338 \f
3339 ;; Sign extension instructions
3340
3341 (define_expand "extendsidi2"
3342   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3343                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3344               (clobber (reg:CC FLAGS_REG))
3345               (clobber (match_scratch:SI 2 ""))])]
3346   ""
3347 {
3348   if (TARGET_64BIT)
3349     {
3350       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3351       DONE;
3352     }
3353 })
3354
3355 (define_insn "*extendsidi2_1"
3356   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3357         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3358    (clobber (reg:CC FLAGS_REG))
3359    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3360   "!TARGET_64BIT"
3361   "#")
3362
3363 (define_insn "extendsidi2_rex64"
3364   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3365         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3366   "TARGET_64BIT"
3367   "@
3368    {cltq|cdqe}
3369    movs{lq|x}\t{%1,%0|%0, %1}"
3370   [(set_attr "type" "imovx")
3371    (set_attr "mode" "DI")
3372    (set_attr "prefix_0f" "0")
3373    (set_attr "modrm" "0,1")])
3374
3375 (define_insn "extendhidi2"
3376   [(set (match_operand:DI 0 "register_operand" "=r")
3377         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3378   "TARGET_64BIT"
3379   "movs{wq|x}\t{%1,%0|%0, %1}"
3380   [(set_attr "type" "imovx")
3381    (set_attr "mode" "DI")])
3382
3383 (define_insn "extendqidi2"
3384   [(set (match_operand:DI 0 "register_operand" "=r")
3385         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3386   "TARGET_64BIT"
3387   "movs{bq|x}\t{%1,%0|%0, %1}"
3388    [(set_attr "type" "imovx")
3389     (set_attr "mode" "DI")])
3390
3391 ;; Extend to memory case when source register does die.
3392 (define_split
3393   [(set (match_operand:DI 0 "memory_operand" "")
3394         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3395    (clobber (reg:CC FLAGS_REG))
3396    (clobber (match_operand:SI 2 "register_operand" ""))]
3397   "(reload_completed
3398     && dead_or_set_p (insn, operands[1])
3399     && !reg_mentioned_p (operands[1], operands[0]))"
3400   [(set (match_dup 3) (match_dup 1))
3401    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3402               (clobber (reg:CC FLAGS_REG))])
3403    (set (match_dup 4) (match_dup 1))]
3404   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3405
3406 ;; Extend to memory case when source register does not die.
3407 (define_split
3408   [(set (match_operand:DI 0 "memory_operand" "")
3409         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3410    (clobber (reg:CC FLAGS_REG))
3411    (clobber (match_operand:SI 2 "register_operand" ""))]
3412   "reload_completed"
3413   [(const_int 0)]
3414 {
3415   split_di (&operands[0], 1, &operands[3], &operands[4]);
3416
3417   emit_move_insn (operands[3], operands[1]);
3418
3419   /* Generate a cltd if possible and doing so it profitable.  */
3420   if (true_regnum (operands[1]) == 0
3421       && true_regnum (operands[2]) == 1
3422       && (optimize_size || TARGET_USE_CLTD))
3423     {
3424       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3425     }
3426   else
3427     {
3428       emit_move_insn (operands[2], operands[1]);
3429       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3430     }
3431   emit_move_insn (operands[4], operands[2]);
3432   DONE;
3433 })
3434
3435 ;; Extend to register case.  Optimize case where source and destination
3436 ;; registers match and cases where we can use cltd.
3437 (define_split
3438   [(set (match_operand:DI 0 "register_operand" "")
3439         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3440    (clobber (reg:CC FLAGS_REG))
3441    (clobber (match_scratch:SI 2 ""))]
3442   "reload_completed"
3443   [(const_int 0)]
3444 {
3445   split_di (&operands[0], 1, &operands[3], &operands[4]);
3446
3447   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3448     emit_move_insn (operands[3], operands[1]);
3449
3450   /* Generate a cltd if possible and doing so it profitable.  */
3451   if (true_regnum (operands[3]) == 0
3452       && (optimize_size || TARGET_USE_CLTD))
3453     {
3454       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3455       DONE;
3456     }
3457
3458   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3459     emit_move_insn (operands[4], operands[1]);
3460
3461   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3462   DONE;
3463 })
3464
3465 (define_insn "extendhisi2"
3466   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3467         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3468   ""
3469 {
3470   switch (get_attr_prefix_0f (insn))
3471     {
3472     case 0:
3473       return "{cwtl|cwde}";
3474     default:
3475       return "movs{wl|x}\t{%1,%0|%0, %1}";
3476     }
3477 }
3478   [(set_attr "type" "imovx")
3479    (set_attr "mode" "SI")
3480    (set (attr "prefix_0f")
3481      ;; movsx is short decodable while cwtl is vector decoded.
3482      (if_then_else (and (eq_attr "cpu" "!k6")
3483                         (eq_attr "alternative" "0"))
3484         (const_string "0")
3485         (const_string "1")))
3486    (set (attr "modrm")
3487      (if_then_else (eq_attr "prefix_0f" "0")
3488         (const_string "0")
3489         (const_string "1")))])
3490
3491 (define_insn "*extendhisi2_zext"
3492   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3493         (zero_extend:DI
3494           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3495   "TARGET_64BIT"
3496 {
3497   switch (get_attr_prefix_0f (insn))
3498     {
3499     case 0:
3500       return "{cwtl|cwde}";
3501     default:
3502       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3503     }
3504 }
3505   [(set_attr "type" "imovx")
3506    (set_attr "mode" "SI")
3507    (set (attr "prefix_0f")
3508      ;; movsx is short decodable while cwtl is vector decoded.
3509      (if_then_else (and (eq_attr "cpu" "!k6")
3510                         (eq_attr "alternative" "0"))
3511         (const_string "0")
3512         (const_string "1")))
3513    (set (attr "modrm")
3514      (if_then_else (eq_attr "prefix_0f" "0")
3515         (const_string "0")
3516         (const_string "1")))])
3517
3518 (define_insn "extendqihi2"
3519   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3520         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3521   ""
3522 {
3523   switch (get_attr_prefix_0f (insn))
3524     {
3525     case 0:
3526       return "{cbtw|cbw}";
3527     default:
3528       return "movs{bw|x}\t{%1,%0|%0, %1}";
3529     }
3530 }
3531   [(set_attr "type" "imovx")
3532    (set_attr "mode" "HI")
3533    (set (attr "prefix_0f")
3534      ;; movsx is short decodable while cwtl is vector decoded.
3535      (if_then_else (and (eq_attr "cpu" "!k6")
3536                         (eq_attr "alternative" "0"))
3537         (const_string "0")
3538         (const_string "1")))
3539    (set (attr "modrm")
3540      (if_then_else (eq_attr "prefix_0f" "0")
3541         (const_string "0")
3542         (const_string "1")))])
3543
3544 (define_insn "extendqisi2"
3545   [(set (match_operand:SI 0 "register_operand" "=r")
3546         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3547   ""
3548   "movs{bl|x}\t{%1,%0|%0, %1}"
3549    [(set_attr "type" "imovx")
3550     (set_attr "mode" "SI")])
3551
3552 (define_insn "*extendqisi2_zext"
3553   [(set (match_operand:DI 0 "register_operand" "=r")
3554         (zero_extend:DI
3555           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3556   "TARGET_64BIT"
3557   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3558    [(set_attr "type" "imovx")
3559     (set_attr "mode" "SI")])
3560 \f
3561 ;; Conversions between float and double.
3562
3563 ;; These are all no-ops in the model used for the 80387.  So just
3564 ;; emit moves.
3565
3566 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3567 (define_insn "*dummy_extendsfdf2"
3568   [(set (match_operand:DF 0 "push_operand" "=<")
3569         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3570   "0"
3571   "#")
3572
3573 (define_split
3574   [(set (match_operand:DF 0 "push_operand" "")
3575         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3576   "!TARGET_64BIT"
3577   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3578    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3579
3580 (define_split
3581   [(set (match_operand:DF 0 "push_operand" "")
3582         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3583   "TARGET_64BIT"
3584   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3585    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3586
3587 (define_insn "*dummy_extendsfxf2"
3588   [(set (match_operand:XF 0 "push_operand" "=<")
3589         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3590   "0"
3591   "#")
3592
3593 (define_split
3594   [(set (match_operand:XF 0 "push_operand" "")
3595         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3596   ""
3597   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3598    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3599   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3600
3601 (define_split
3602   [(set (match_operand:XF 0 "push_operand" "")
3603         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3604   "TARGET_64BIT"
3605   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3606    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3607   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3608
3609 (define_split
3610   [(set (match_operand:XF 0 "push_operand" "")
3611         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3612   ""
3613   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3614    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3615   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3616
3617 (define_split
3618   [(set (match_operand:XF 0 "push_operand" "")
3619         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3620   "TARGET_64BIT"
3621   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3622    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3623   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3624
3625 (define_expand "extendsfdf2"
3626   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3627         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3628   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3629 {
3630   /* ??? Needed for compress_float_constant since all fp constants
3631      are LEGITIMATE_CONSTANT_P.  */
3632   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3633     {
3634       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3635           && standard_80387_constant_p (operands[1]) > 0)
3636         {
3637           operands[1] = simplify_const_unary_operation
3638             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3639           emit_move_insn_1 (operands[0], operands[1]);
3640           DONE;
3641         }
3642       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3643     }
3644 })
3645
3646 (define_insn "*extendsfdf2_mixed"
3647   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3648         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3649   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3650 {
3651   switch (which_alternative)
3652     {
3653     case 0:
3654       return output_387_reg_move (insn, operands);
3655
3656     case 1:
3657       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3658         return "fstp%z0\t%y0";
3659       else
3660         return "fst%z0\t%y0";
3661
3662     case 2:
3663       return "cvtss2sd\t{%1, %0|%0, %1}";
3664
3665     default:
3666       gcc_unreachable ();
3667     }
3668 }
3669   [(set_attr "type" "fmov,fmov,ssecvt")
3670    (set_attr "mode" "SF,XF,DF")])
3671
3672 (define_insn "*extendsfdf2_sse"
3673   [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3674         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3675   "TARGET_SSE2 && TARGET_SSE_MATH"
3676   "cvtss2sd\t{%1, %0|%0, %1}"
3677   [(set_attr "type" "ssecvt")
3678    (set_attr "mode" "DF")])
3679
3680 (define_insn "*extendsfdf2_i387"
3681   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3682         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3683   "TARGET_80387"
3684 {
3685   switch (which_alternative)
3686     {
3687     case 0:
3688       return output_387_reg_move (insn, operands);
3689
3690     case 1:
3691       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3692         return "fstp%z0\t%y0";
3693       else
3694         return "fst%z0\t%y0";
3695
3696     default:
3697       gcc_unreachable ();
3698     }
3699 }
3700   [(set_attr "type" "fmov")
3701    (set_attr "mode" "SF,XF")])
3702
3703 (define_expand "extendsfxf2"
3704   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3705         (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3706   "TARGET_80387"
3707 {
3708   /* ??? Needed for compress_float_constant since all fp constants
3709      are LEGITIMATE_CONSTANT_P.  */
3710   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3711     {
3712       if (standard_80387_constant_p (operands[1]) > 0)
3713         {
3714           operands[1] = simplify_const_unary_operation
3715             (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3716           emit_move_insn_1 (operands[0], operands[1]);
3717           DONE;
3718         }
3719       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3720     }
3721 })
3722
3723 (define_insn "*extendsfxf2_i387"
3724   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3725         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3726   "TARGET_80387"
3727 {
3728   switch (which_alternative)
3729     {
3730     case 0:
3731       return output_387_reg_move (insn, operands);
3732
3733     case 1:
3734       /* There is no non-popping store to memory for XFmode.  So if
3735          we need one, follow the store with a load.  */
3736       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3737         return "fstp%z0\t%y0";
3738       else
3739         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3740
3741     default:
3742       gcc_unreachable ();
3743     }
3744 }
3745   [(set_attr "type" "fmov")
3746    (set_attr "mode" "SF,XF")])
3747
3748 (define_expand "extenddfxf2"
3749   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3750         (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3751   "TARGET_80387"
3752 {
3753   /* ??? Needed for compress_float_constant since all fp constants
3754      are LEGITIMATE_CONSTANT_P.  */
3755   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3756     {
3757       if (standard_80387_constant_p (operands[1]) > 0)
3758         {
3759           operands[1] = simplify_const_unary_operation
3760             (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3761           emit_move_insn_1 (operands[0], operands[1]);
3762           DONE;
3763         }
3764       operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3765     }
3766 })
3767
3768 (define_insn "*extenddfxf2_i387"
3769   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3770         (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3771   "TARGET_80387"
3772 {
3773   switch (which_alternative)
3774     {
3775     case 0:
3776       return output_387_reg_move (insn, operands);
3777
3778     case 1:
3779       /* There is no non-popping store to memory for XFmode.  So if
3780          we need one, follow the store with a load.  */
3781       if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3782         return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3783       else
3784         return "fstp%z0\t%y0";
3785
3786     default:
3787       gcc_unreachable ();
3788     }
3789 }
3790   [(set_attr "type" "fmov")
3791    (set_attr "mode" "DF,XF")])
3792
3793 ;; %%% This seems bad bad news.
3794 ;; This cannot output into an f-reg because there is no way to be sure
3795 ;; of truncating in that case.  Otherwise this is just like a simple move
3796 ;; insn.  So we pretend we can output to a reg in order to get better
3797 ;; register preferencing, but we really use a stack slot.
3798
3799 ;; Conversion from DFmode to SFmode.
3800
3801 (define_expand "truncdfsf2"
3802   [(set (match_operand:SF 0 "nonimmediate_operand" "")
3803         (float_truncate:SF
3804           (match_operand:DF 1 "nonimmediate_operand" "")))]
3805   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3806 {
3807   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3808     ;
3809   else if (flag_unsafe_math_optimizations)
3810     ;
3811   else
3812     {
3813       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3814       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3815       DONE;
3816     }
3817 })
3818
3819 (define_expand "truncdfsf2_with_temp"
3820   [(parallel [(set (match_operand:SF 0 "" "")
3821                    (float_truncate:SF (match_operand:DF 1 "" "")))
3822               (clobber (match_operand:SF 2 "" ""))])]
3823   "")
3824
3825 (define_insn "*truncdfsf_fast_mixed"
3826   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,f,Y")
3827         (float_truncate:SF
3828           (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3829   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3830 {
3831   switch (which_alternative)
3832     {
3833     case 0:
3834       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3835         return "fstp%z0\t%y0";
3836       else
3837         return "fst%z0\t%y0";
3838     case 1:
3839       return output_387_reg_move (insn, operands);
3840     case 2:
3841       return "cvtsd2ss\t{%1, %0|%0, %1}";
3842     default:
3843       gcc_unreachable ();
3844     }
3845 }
3846   [(set_attr "type" "fmov,fmov,ssecvt")
3847    (set_attr "mode" "SF")])
3848
3849 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3850 ;; because nothing we do here is unsafe.
3851 (define_insn "*truncdfsf_fast_sse"
3852   [(set (match_operand:SF 0 "nonimmediate_operand"   "=Y")
3853         (float_truncate:SF
3854           (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3855   "TARGET_SSE2 && TARGET_SSE_MATH"
3856   "cvtsd2ss\t{%1, %0|%0, %1}"
3857   [(set_attr "type" "ssecvt")
3858    (set_attr "mode" "SF")])
3859
3860 (define_insn "*truncdfsf_fast_i387"
3861   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
3862         (float_truncate:SF
3863           (match_operand:DF 1 "nonimmediate_operand" "f")))]
3864   "TARGET_80387 && flag_unsafe_math_optimizations"
3865   "* return output_387_reg_move (insn, operands);"
3866   [(set_attr "type" "fmov")
3867    (set_attr "mode" "SF")])
3868
3869 (define_insn "*truncdfsf_mixed"
3870   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y")
3871         (float_truncate:SF
3872           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Ym")))
3873    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
3874   "TARGET_MIX_SSE_I387"
3875 {
3876   switch (which_alternative)
3877     {
3878     case 0:
3879       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3880         return "fstp%z0\t%y0";
3881       else
3882         return "fst%z0\t%y0";
3883     case 1:
3884       return "#";
3885     case 2:
3886       return "cvtsd2ss\t{%1, %0|%0, %1}";
3887     default:
3888       gcc_unreachable ();
3889     }
3890 }
3891   [(set_attr "type" "fmov,multi,ssecvt")
3892    (set_attr "unit" "*,i387,*")
3893    (set_attr "mode" "SF")])
3894
3895 (define_insn "*truncdfsf_i387"
3896   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3897         (float_truncate:SF
3898           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3899    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3900   "TARGET_80387"
3901 {
3902   switch (which_alternative)
3903     {
3904     case 0:
3905       if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3906         return "fstp%z0\t%y0";
3907       else
3908         return "fst%z0\t%y0";
3909     case 1:
3910       return "#";
3911     default:
3912       gcc_unreachable ();
3913     }
3914 }
3915   [(set_attr "type" "fmov,multi")
3916    (set_attr "unit" "*,i387")
3917    (set_attr "mode" "SF")])
3918
3919 (define_insn "*truncdfsf2_i387_1"
3920   [(set (match_operand:SF 0 "memory_operand" "=m")
3921         (float_truncate:SF
3922           (match_operand:DF 1 "register_operand" "f")))]
3923   "TARGET_80387
3924    && !(TARGET_SSE2 && TARGET_SSE_MATH)
3925    && !TARGET_MIX_SSE_I387"
3926 {
3927   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3928     return "fstp%z0\t%y0";
3929   else
3930     return "fst%z0\t%y0";
3931 }
3932   [(set_attr "type" "fmov")
3933    (set_attr "mode" "SF")])
3934
3935 (define_split
3936   [(set (match_operand:SF 0 "register_operand" "")
3937         (float_truncate:SF
3938          (match_operand:DF 1 "fp_register_operand" "")))
3939    (clobber (match_operand 2 "" ""))]
3940   "reload_completed"
3941   [(set (match_dup 2) (match_dup 1))
3942    (set (match_dup 0) (match_dup 2))]
3943 {
3944   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3945 })
3946
3947 ;; Conversion from XFmode to SFmode.
3948
3949 (define_expand "truncxfsf2"
3950   [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3951                    (float_truncate:SF
3952                     (match_operand:XF 1 "register_operand" "")))
3953               (clobber (match_dup 2))])]
3954   "TARGET_80387"
3955 {
3956   if (flag_unsafe_math_optimizations)
3957     {
3958       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3959       emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3960       if (reg != operands[0])
3961         emit_move_insn (operands[0], reg);
3962       DONE;
3963     }
3964   else
3965     operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3966 })
3967
3968 (define_insn "*truncxfsf2_mixed"
3969   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3970         (float_truncate:SF
3971          (match_operand:XF 1 "register_operand" "f,f,f,f")))
3972    (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3973   "TARGET_80387"
3974 {
3975   gcc_assert (!which_alternative);
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 }
3981   [(set_attr "type" "fmov,multi,multi,multi")
3982    (set_attr "unit" "*,i387,i387,i387")
3983    (set_attr "mode" "SF")])
3984
3985 (define_insn "truncxfsf2_i387_noop"
3986   [(set (match_operand:SF 0 "register_operand" "=f")
3987         (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3988   "TARGET_80387 && flag_unsafe_math_optimizations"
3989   "* return output_387_reg_move (insn, operands);"
3990   [(set_attr "type" "fmov")
3991    (set_attr "mode" "SF")])
3992
3993 (define_insn "*truncxfsf2_i387"
3994   [(set (match_operand:SF 0 "memory_operand" "=m")
3995         (float_truncate:SF
3996          (match_operand:XF 1 "register_operand" "f")))]
3997   "TARGET_80387"
3998 {
3999   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4000     return "fstp%z0\t%y0";
4001   else
4002     return "fst%z0\t%y0";
4003 }
4004   [(set_attr "type" "fmov")
4005    (set_attr "mode" "SF")])
4006
4007 (define_split
4008   [(set (match_operand:SF 0 "register_operand" "")
4009         (float_truncate:SF
4010          (match_operand:XF 1 "register_operand" "")))
4011    (clobber (match_operand:SF 2 "memory_operand" ""))]
4012   "TARGET_80387 && reload_completed"
4013   [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4014    (set (match_dup 0) (match_dup 2))]
4015   "")
4016
4017 (define_split
4018   [(set (match_operand:SF 0 "memory_operand" "")
4019         (float_truncate:SF
4020          (match_operand:XF 1 "register_operand" "")))
4021    (clobber (match_operand:SF 2 "memory_operand" ""))]
4022   "TARGET_80387"
4023   [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4024   "")
4025
4026 ;; Conversion from XFmode to DFmode.
4027
4028 (define_expand "truncxfdf2"
4029   [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4030                    (float_truncate:DF
4031                     (match_operand:XF 1 "register_operand" "")))
4032               (clobber (match_dup 2))])]
4033   "TARGET_80387"
4034 {
4035   if (flag_unsafe_math_optimizations)
4036     {
4037       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
4038       emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
4039       if (reg != operands[0])
4040         emit_move_insn (operands[0], reg);
4041       DONE;
4042     }
4043   else
4044     operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
4045 })
4046
4047 (define_insn "*truncxfdf2_mixed"
4048   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
4049         (float_truncate:DF
4050          (match_operand:XF 1 "register_operand" "f,f,f,f")))
4051    (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4052   "TARGET_80387"
4053 {
4054   gcc_assert (!which_alternative);
4055   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4056     return "fstp%z0\t%y0";
4057   else
4058     return "fst%z0\t%y0";
4059 }
4060   [(set_attr "type" "fmov,multi,multi,multi")
4061    (set_attr "unit" "*,i387,i387,i387")
4062    (set_attr "mode" "DF")])
4063
4064 (define_insn "truncxfdf2_i387_noop"
4065   [(set (match_operand:DF 0 "register_operand" "=f")
4066         (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4067   "TARGET_80387 && flag_unsafe_math_optimizations"
4068   "* return output_387_reg_move (insn, operands);"
4069   [(set_attr "type" "fmov")
4070    (set_attr "mode" "DF")])
4071
4072 (define_insn "*truncxfdf2_i387"
4073   [(set (match_operand:DF 0 "memory_operand" "=m")
4074         (float_truncate:DF
4075           (match_operand:XF 1 "register_operand" "f")))]
4076   "TARGET_80387"
4077 {
4078   if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4079     return "fstp%z0\t%y0";
4080   else
4081     return "fst%z0\t%y0";
4082 }
4083   [(set_attr "type" "fmov")
4084    (set_attr "mode" "DF")])
4085
4086 (define_split
4087   [(set (match_operand:DF 0 "register_operand" "")
4088         (float_truncate:DF
4089          (match_operand:XF 1 "register_operand" "")))
4090    (clobber (match_operand:DF 2 "memory_operand" ""))]
4091   "TARGET_80387 && reload_completed"
4092   [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4093    (set (match_dup 0) (match_dup 2))]
4094   "")
4095
4096 (define_split
4097   [(set (match_operand:DF 0 "memory_operand" "")
4098         (float_truncate:DF
4099          (match_operand:XF 1 "register_operand" "")))
4100    (clobber (match_operand:DF 2 "memory_operand" ""))]
4101   "TARGET_80387"
4102   [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4103   "")
4104 \f
4105 ;; Signed conversion to DImode.
4106
4107 (define_expand "fix_truncxfdi2"
4108   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4109                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4110               (clobber (reg:CC FLAGS_REG))])]
4111   "TARGET_80387"
4112 {
4113   if (TARGET_FISTTP)
4114    {
4115      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4116      DONE;
4117    }
4118 })
4119
4120 (define_expand "fix_trunc<mode>di2"
4121   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4122                    (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4123               (clobber (reg:CC FLAGS_REG))])]
4124   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4125 {
4126   if (TARGET_FISTTP
4127       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4128    {
4129      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4130      DONE;
4131    }
4132   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4133    {
4134      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4135      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4136      if (out != operands[0])
4137         emit_move_insn (operands[0], out);
4138      DONE;
4139    }
4140 })
4141
4142 ;; Signed conversion to SImode.
4143
4144 (define_expand "fix_truncxfsi2"
4145   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4146                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4147               (clobber (reg:CC FLAGS_REG))])]
4148   "TARGET_80387"
4149 {
4150   if (TARGET_FISTTP)
4151    {
4152      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4153      DONE;
4154    }
4155 })
4156
4157 (define_expand "fix_trunc<mode>si2"
4158   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4159                    (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4160               (clobber (reg:CC FLAGS_REG))])]
4161   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4162 {
4163   if (TARGET_FISTTP
4164       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4165    {
4166      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4167      DONE;
4168    }
4169   if (SSE_FLOAT_MODE_P (<MODE>mode))
4170    {
4171      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4172      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4173      if (out != operands[0])
4174         emit_move_insn (operands[0], out);
4175      DONE;
4176    }
4177 })
4178
4179 ;; Signed conversion to HImode.
4180
4181 (define_expand "fix_trunc<mode>hi2"
4182   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4183                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4184               (clobber (reg:CC FLAGS_REG))])]
4185   "TARGET_80387
4186    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4187 {
4188   if (TARGET_FISTTP)
4189    {
4190      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4191      DONE;
4192    }
4193 })
4194
4195 ;; When SSE is available, it is always faster to use it!
4196 (define_insn "fix_truncsfdi_sse"
4197   [(set (match_operand:DI 0 "register_operand" "=r,r")
4198         (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4199   "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4200   "cvttss2si{q}\t{%1, %0|%0, %1}"
4201   [(set_attr "type" "sseicvt")
4202    (set_attr "mode" "SF")
4203    (set_attr "athlon_decode" "double,vector")
4204    (set_attr "amdfam10_decode" "double,double")])
4205
4206 (define_insn "fix_truncdfdi_sse"
4207   [(set (match_operand:DI 0 "register_operand" "=r,r")
4208         (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4209   "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4210   "cvttsd2si{q}\t{%1, %0|%0, %1}"
4211   [(set_attr "type" "sseicvt")
4212    (set_attr "mode" "DF")
4213    (set_attr "athlon_decode" "double,vector")
4214    (set_attr "amdfam10_decode" "double,double")])
4215
4216 (define_insn "fix_truncsfsi_sse"
4217   [(set (match_operand:SI 0 "register_operand" "=r,r")
4218         (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4219   "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4220   "cvttss2si\t{%1, %0|%0, %1}"
4221   [(set_attr "type" "sseicvt")
4222    (set_attr "mode" "DF")
4223    (set_attr "athlon_decode" "double,vector")
4224    (set_attr "amdfam10_decode" "double,double")])
4225
4226 (define_insn "fix_truncdfsi_sse"
4227   [(set (match_operand:SI 0 "register_operand" "=r,r")
4228         (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4229   "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4230   "cvttsd2si\t{%1, %0|%0, %1}"
4231   [(set_attr "type" "sseicvt")
4232    (set_attr "mode" "DF")
4233    (set_attr "athlon_decode" "double,vector")
4234    (set_attr "amdfam10_decode" "double,double")])
4235
4236 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4237 (define_peephole2
4238   [(set (match_operand:DF 0 "register_operand" "")
4239         (match_operand:DF 1 "memory_operand" ""))
4240    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4241         (fix:SSEMODEI24 (match_dup 0)))]
4242   "!TARGET_K8
4243    && peep2_reg_dead_p (2, operands[0])"
4244   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4245   "")
4246
4247 (define_peephole2
4248   [(set (match_operand:SF 0 "register_operand" "")
4249         (match_operand:SF 1 "memory_operand" ""))
4250    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4251         (fix:SSEMODEI24 (match_dup 0)))]
4252   "!TARGET_K8
4253    && peep2_reg_dead_p (2, operands[0])"
4254   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4255   "")
4256
4257 ;; Avoid vector decoded forms of the instruction.
4258 (define_peephole2
4259   [(match_scratch:DF 2 "Y")
4260    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4261         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4262   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4263   [(set (match_dup 2) (match_dup 1))
4264    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4265   "")
4266
4267 (define_peephole2
4268   [(match_scratch:SF 2 "x")
4269    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4270         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4271   "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4272   [(set (match_dup 2) (match_dup 1))
4273    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4274   "")
4275
4276 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4277   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4278         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4279   "TARGET_FISTTP
4280    && FLOAT_MODE_P (GET_MODE (operands[1]))
4281    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4282          && (TARGET_64BIT || <MODE>mode != DImode))
4283         && TARGET_SSE_MATH)
4284    && !(reload_completed || reload_in_progress)"
4285   "#"
4286   "&& 1"
4287   [(const_int 0)]
4288 {
4289   if (memory_operand (operands[0], VOIDmode))
4290     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4291   else
4292     {
4293       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4294       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4295                                                             operands[1],
4296                                                             operands[2]));
4297     }
4298   DONE;
4299 }
4300   [(set_attr "type" "fisttp")
4301    (set_attr "mode" "<MODE>")])
4302
4303 (define_insn "fix_trunc<mode>_i387_fisttp"
4304   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4305         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4306    (clobber (match_scratch:XF 2 "=&1f"))]
4307   "TARGET_FISTTP
4308    && FLOAT_MODE_P (GET_MODE (operands[1]))
4309    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4310          && (TARGET_64BIT || <MODE>mode != DImode))
4311         && TARGET_SSE_MATH)"
4312   "* return output_fix_trunc (insn, operands, 1);"
4313   [(set_attr "type" "fisttp")
4314    (set_attr "mode" "<MODE>")])
4315
4316 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4317   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4318         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4319    (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4320    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4321   "TARGET_FISTTP
4322    && FLOAT_MODE_P (GET_MODE (operands[1]))
4323    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4324         && (TARGET_64BIT || <MODE>mode != DImode))
4325         && TARGET_SSE_MATH)"
4326   "#"
4327   [(set_attr "type" "fisttp")
4328    (set_attr "mode" "<MODE>")])
4329
4330 (define_split
4331   [(set (match_operand:X87MODEI 0 "register_operand" "")
4332         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4333    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4334    (clobber (match_scratch 3 ""))]
4335   "reload_completed"
4336   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4337               (clobber (match_dup 3))])
4338    (set (match_dup 0) (match_dup 2))]
4339   "")
4340
4341 (define_split
4342   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4343         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4344    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4345    (clobber (match_scratch 3 ""))]
4346   "reload_completed"
4347   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4348               (clobber (match_dup 3))])]
4349   "")
4350
4351 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4352 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4353 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4354 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4355 ;; function in i386.c.
4356 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4357   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4358         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4359    (clobber (reg:CC FLAGS_REG))]
4360   "TARGET_80387 && !TARGET_FISTTP
4361    && FLOAT_MODE_P (GET_MODE (operands[1]))
4362    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4363          && (TARGET_64BIT || <MODE>mode != DImode))
4364    && !(reload_completed || reload_in_progress)"
4365   "#"
4366   "&& 1"
4367   [(const_int 0)]
4368 {
4369   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4370
4371   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4372   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4373   if (memory_operand (operands[0], VOIDmode))
4374     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4375                                          operands[2], operands[3]));
4376   else
4377     {
4378       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4379       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4380                                                      operands[2], operands[3],
4381                                                      operands[4]));
4382     }
4383   DONE;
4384 }
4385   [(set_attr "type" "fistp")
4386    (set_attr "i387_cw" "trunc")
4387    (set_attr "mode" "<MODE>")])
4388
4389 (define_insn "fix_truncdi_i387"
4390   [(set (match_operand:DI 0 "memory_operand" "=m")
4391         (fix:DI (match_operand 1 "register_operand" "f")))
4392    (use (match_operand:HI 2 "memory_operand" "m"))
4393    (use (match_operand:HI 3 "memory_operand" "m"))
4394    (clobber (match_scratch:XF 4 "=&1f"))]
4395   "TARGET_80387 && !TARGET_FISTTP
4396    && FLOAT_MODE_P (GET_MODE (operands[1]))
4397    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4398   "* return output_fix_trunc (insn, operands, 0);"
4399   [(set_attr "type" "fistp")
4400    (set_attr "i387_cw" "trunc")
4401    (set_attr "mode" "DI")])
4402
4403 (define_insn "fix_truncdi_i387_with_temp"
4404   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4405         (fix:DI (match_operand 1 "register_operand" "f,f")))
4406    (use (match_operand:HI 2 "memory_operand" "m,m"))
4407    (use (match_operand:HI 3 "memory_operand" "m,m"))
4408    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4409    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4410   "TARGET_80387 && !TARGET_FISTTP
4411    && FLOAT_MODE_P (GET_MODE (operands[1]))
4412    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4413   "#"
4414   [(set_attr "type" "fistp")
4415    (set_attr "i387_cw" "trunc")
4416    (set_attr "mode" "DI")])
4417
4418 (define_split
4419   [(set (match_operand:DI 0 "register_operand" "")
4420         (fix:DI (match_operand 1 "register_operand" "")))
4421    (use (match_operand:HI 2 "memory_operand" ""))
4422    (use (match_operand:HI 3 "memory_operand" ""))
4423    (clobber (match_operand:DI 4 "memory_operand" ""))
4424    (clobber (match_scratch 5 ""))]
4425   "reload_completed"
4426   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4427               (use (match_dup 2))
4428               (use (match_dup 3))
4429               (clobber (match_dup 5))])
4430    (set (match_dup 0) (match_dup 4))]
4431   "")
4432
4433 (define_split
4434   [(set (match_operand:DI 0 "memory_operand" "")
4435         (fix:DI (match_operand 1 "register_operand" "")))
4436    (use (match_operand:HI 2 "memory_operand" ""))
4437    (use (match_operand:HI 3 "memory_operand" ""))
4438    (clobber (match_operand:DI 4 "memory_operand" ""))
4439    (clobber (match_scratch 5 ""))]
4440   "reload_completed"
4441   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4442               (use (match_dup 2))
4443               (use (match_dup 3))
4444               (clobber (match_dup 5))])]
4445   "")
4446
4447 (define_insn "fix_trunc<mode>_i387"
4448   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4449         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4450    (use (match_operand:HI 2 "memory_operand" "m"))
4451    (use (match_operand:HI 3 "memory_operand" "m"))]
4452   "TARGET_80387 && !TARGET_FISTTP
4453    && FLOAT_MODE_P (GET_MODE (operands[1]))
4454    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4455   "* return output_fix_trunc (insn, operands, 0);"
4456   [(set_attr "type" "fistp")
4457    (set_attr "i387_cw" "trunc")
4458    (set_attr "mode" "<MODE>")])
4459
4460 (define_insn "fix_trunc<mode>_i387_with_temp"
4461   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4462         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4463    (use (match_operand:HI 2 "memory_operand" "m,m"))
4464    (use (match_operand:HI 3 "memory_operand" "m,m"))
4465    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4466   "TARGET_80387 && !TARGET_FISTTP
4467    && FLOAT_MODE_P (GET_MODE (operands[1]))
4468    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4469   "#"
4470   [(set_attr "type" "fistp")
4471    (set_attr "i387_cw" "trunc")
4472    (set_attr "mode" "<MODE>")])
4473
4474 (define_split
4475   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4476         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4477    (use (match_operand:HI 2 "memory_operand" ""))
4478    (use (match_operand:HI 3 "memory_operand" ""))
4479    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4480   "reload_completed"
4481   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4482               (use (match_dup 2))
4483               (use (match_dup 3))])
4484    (set (match_dup 0) (match_dup 4))]
4485   "")
4486
4487 (define_split
4488   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4489         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4490    (use (match_operand:HI 2 "memory_operand" ""))
4491    (use (match_operand:HI 3 "memory_operand" ""))
4492    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4493   "reload_completed"
4494   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4495               (use (match_dup 2))
4496               (use (match_dup 3))])]
4497   "")
4498
4499 (define_insn "x86_fnstcw_1"
4500   [(set (match_operand:HI 0 "memory_operand" "=m")
4501         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4502   "TARGET_80387"
4503   "fnstcw\t%0"
4504   [(set_attr "length" "2")
4505    (set_attr "mode" "HI")
4506    (set_attr "unit" "i387")])
4507
4508 (define_insn "x86_fldcw_1"
4509   [(set (reg:HI FPCR_REG)
4510         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4511   "TARGET_80387"
4512   "fldcw\t%0"
4513   [(set_attr "length" "2")
4514    (set_attr "mode" "HI")
4515    (set_attr "unit" "i387")
4516    (set_attr "athlon_decode" "vector")
4517    (set_attr "amdfam10_decode" "vector")])   
4518 \f
4519 ;; Conversion between fixed point and floating point.
4520
4521 ;; Even though we only accept memory inputs, the backend _really_
4522 ;; wants to be able to do this between registers.
4523
4524 (define_expand "floathisf2"
4525   [(set (match_operand:SF 0 "register_operand" "")
4526         (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4527   "TARGET_80387 || TARGET_SSE_MATH"
4528 {
4529   if (TARGET_SSE_MATH)
4530     {
4531       emit_insn (gen_floatsisf2 (operands[0],
4532                                  convert_to_mode (SImode, operands[1], 0)));
4533       DONE;
4534     }
4535 })
4536
4537 (define_insn "*floathisf2_i387"
4538   [(set (match_operand:SF 0 "register_operand" "=f,f")
4539         (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4540   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4541   "@
4542    fild%z1\t%1
4543    #"
4544   [(set_attr "type" "fmov,multi")
4545    (set_attr "mode" "SF")
4546    (set_attr "unit" "*,i387")
4547    (set_attr "fp_int_src" "true")])
4548
4549 (define_expand "floatsisf2"
4550   [(set (match_operand:SF 0 "register_operand" "")
4551         (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4552   "TARGET_80387 || TARGET_SSE_MATH"
4553   "")
4554
4555 (define_insn "*floatsisf2_mixed"
4556   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4557         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4558   "TARGET_MIX_SSE_I387"
4559   "@
4560    fild%z1\t%1
4561    #
4562    cvtsi2ss\t{%1, %0|%0, %1}
4563    cvtsi2ss\t{%1, %0|%0, %1}"
4564   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4565    (set_attr "mode" "SF")
4566    (set_attr "unit" "*,i387,*,*")
4567    (set_attr "athlon_decode" "*,*,vector,double")
4568    (set_attr "amdfam10_decode" "*,*,vector,double")
4569    (set_attr "fp_int_src" "true")])
4570
4571 (define_insn "*floatsisf2_sse"
4572   [(set (match_operand:SF 0 "register_operand" "=x,x")
4573         (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4574   "TARGET_SSE_MATH"
4575   "cvtsi2ss\t{%1, %0|%0, %1}"
4576   [(set_attr "type" "sseicvt")
4577    (set_attr "mode" "SF")
4578    (set_attr "athlon_decode" "vector,double")
4579    (set_attr "amdfam10_decode" "vector,double")
4580    (set_attr "fp_int_src" "true")])
4581
4582 (define_insn "*floatsisf2_i387"
4583   [(set (match_operand:SF 0 "register_operand" "=f,f")
4584         (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4585   "TARGET_80387"
4586   "@
4587    fild%z1\t%1
4588    #"
4589   [(set_attr "type" "fmov,multi")
4590    (set_attr "mode" "SF")
4591    (set_attr "unit" "*,i387")
4592    (set_attr "fp_int_src" "true")])
4593
4594 (define_expand "floatdisf2"
4595   [(set (match_operand:SF 0 "register_operand" "")
4596         (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4597   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4598   "")
4599
4600 (define_insn "*floatdisf2_mixed"
4601   [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4602         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4603   "TARGET_64BIT && TARGET_MIX_SSE_I387"
4604   "@
4605    fild%z1\t%1
4606    #
4607    cvtsi2ss{q}\t{%1, %0|%0, %1}
4608    cvtsi2ss{q}\t{%1, %0|%0, %1}"
4609   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4610    (set_attr "mode" "SF")
4611    (set_attr "unit" "*,i387,*,*")
4612    (set_attr "athlon_decode" "*,*,vector,double")
4613    (set_attr "amdfam10_decode" "*,*,vector,double")
4614    (set_attr "fp_int_src" "true")])
4615
4616 (define_insn "*floatdisf2_sse"
4617   [(set (match_operand:SF 0 "register_operand" "=x,x")
4618         (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4619   "TARGET_64BIT && TARGET_SSE_MATH"
4620   "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4621   [(set_attr "type" "sseicvt")
4622    (set_attr "mode" "SF")
4623    (set_attr "athlon_decode" "vector,double")
4624    (set_attr "amdfam10_decode" "vector,double")
4625    (set_attr "fp_int_src" "true")])
4626
4627 (define_insn "*floatdisf2_i387"
4628   [(set (match_operand:SF 0 "register_operand" "=f,f")
4629         (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4630   "TARGET_80387"
4631   "@
4632    fild%z1\t%1
4633    #"
4634   [(set_attr "type" "fmov,multi")
4635    (set_attr "mode" "SF")
4636    (set_attr "unit" "*,i387")
4637    (set_attr "fp_int_src" "true")])
4638
4639 (define_expand "floathidf2"
4640   [(set (match_operand:DF 0 "register_operand" "")
4641         (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4642   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4643 {
4644   if (TARGET_SSE2 && TARGET_SSE_MATH)
4645     {
4646       emit_insn (gen_floatsidf2 (operands[0],
4647                                  convert_to_mode (SImode, operands[1], 0)));
4648       DONE;
4649     }
4650 })
4651
4652 (define_insn "*floathidf2_i387"
4653   [(set (match_operand:DF 0 "register_operand" "=f,f")
4654         (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4655   "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4656   "@
4657    fild%z1\t%1
4658    #"
4659   [(set_attr "type" "fmov,multi")
4660    (set_attr "mode" "DF")
4661    (set_attr "unit" "*,i387")
4662    (set_attr "fp_int_src" "true")])
4663
4664 (define_expand "floatsidf2"
4665   [(set (match_operand:DF 0 "register_operand" "")
4666         (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4667   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4668   "")
4669
4670 (define_insn "*floatsidf2_mixed"
4671   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4672         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4673   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4674   "@
4675    fild%z1\t%1
4676    #
4677    cvtsi2sd\t{%1, %0|%0, %1}
4678    cvtsi2sd\t{%1, %0|%0, %1}"
4679   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4680    (set_attr "mode" "DF")
4681    (set_attr "unit" "*,i387,*,*")
4682    (set_attr "athlon_decode" "*,*,double,direct")
4683    (set_attr "amdfam10_decode" "*,*,vector,double")
4684    (set_attr "fp_int_src" "true")])
4685
4686 (define_insn "*floatsidf2_sse"
4687   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4688         (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4689   "TARGET_SSE2 && TARGET_SSE_MATH"
4690   "cvtsi2sd\t{%1, %0|%0, %1}"
4691   [(set_attr "type" "sseicvt")
4692    (set_attr "mode" "DF")
4693    (set_attr "athlon_decode" "double,direct")
4694    (set_attr "amdfam10_decode" "vector,double")
4695    (set_attr "fp_int_src" "true")])
4696
4697 (define_insn "*floatsidf2_i387"
4698   [(set (match_operand:DF 0 "register_operand" "=f,f")
4699         (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4700   "TARGET_80387"
4701   "@
4702    fild%z1\t%1
4703    #"
4704   [(set_attr "type" "fmov,multi")
4705    (set_attr "mode" "DF")
4706    (set_attr "unit" "*,i387")
4707    (set_attr "fp_int_src" "true")])
4708
4709 (define_expand "floatdidf2"
4710   [(set (match_operand:DF 0 "register_operand" "")
4711         (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4712   "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4713   "")
4714
4715 (define_insn "*floatdidf2_mixed"
4716   [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4717         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4718   "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4719   "@
4720    fild%z1\t%1
4721    #
4722    cvtsi2sd{q}\t{%1, %0|%0, %1}
4723    cvtsi2sd{q}\t{%1, %0|%0, %1}"
4724   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4725    (set_attr "mode" "DF")
4726    (set_attr "unit" "*,i387,*,*")
4727    (set_attr "athlon_decode" "*,*,double,direct")
4728    (set_attr "amdfam10_decode" "*,*,vector,double")
4729    (set_attr "fp_int_src" "true")])
4730
4731 (define_insn "*floatdidf2_sse"
4732   [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4733         (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4734   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4735   "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4736   [(set_attr "type" "sseicvt")
4737    (set_attr "mode" "DF")
4738    (set_attr "athlon_decode" "double,direct")
4739    (set_attr "amdfam10_decode" "vector,double")
4740    (set_attr "fp_int_src" "true")])
4741
4742 (define_insn "*floatdidf2_i387"
4743   [(set (match_operand:DF 0 "register_operand" "=f,f")
4744         (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4745   "TARGET_80387"
4746   "@
4747    fild%z1\t%1
4748    #"
4749   [(set_attr "type" "fmov,multi")
4750    (set_attr "mode" "DF")
4751    (set_attr "unit" "*,i387")
4752    (set_attr "fp_int_src" "true")])
4753
4754 (define_insn "floathixf2"
4755   [(set (match_operand:XF 0 "register_operand" "=f,f")
4756         (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4757   "TARGET_80387"
4758   "@
4759    fild%z1\t%1
4760    #"
4761   [(set_attr "type" "fmov,multi")
4762    (set_attr "mode" "XF")
4763    (set_attr "unit" "*,i387")
4764    (set_attr "fp_int_src" "true")])
4765
4766 (define_insn "floatsixf2"
4767   [(set (match_operand:XF 0 "register_operand" "=f,f")
4768         (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4769   "TARGET_80387"
4770   "@
4771    fild%z1\t%1
4772    #"
4773   [(set_attr "type" "fmov,multi")
4774    (set_attr "mode" "XF")
4775    (set_attr "unit" "*,i387")
4776    (set_attr "fp_int_src" "true")])
4777
4778 (define_insn "floatdixf2"
4779   [(set (match_operand:XF 0 "register_operand" "=f,f")
4780         (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4781   "TARGET_80387"
4782   "@
4783    fild%z1\t%1
4784    #"
4785   [(set_attr "type" "fmov,multi")
4786    (set_attr "mode" "XF")
4787    (set_attr "unit" "*,i387")
4788    (set_attr "fp_int_src" "true")])
4789
4790 ;; %%% Kill these when reload knows how to do it.
4791 (define_split
4792   [(set (match_operand 0 "fp_register_operand" "")
4793         (float (match_operand 1 "register_operand" "")))]
4794   "reload_completed
4795    && TARGET_80387
4796    && FLOAT_MODE_P (GET_MODE (operands[0]))"
4797   [(const_int 0)]
4798 {
4799   operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4800   operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4801   emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4802   ix86_free_from_memory (GET_MODE (operands[1]));
4803   DONE;
4804 })
4805
4806 (define_expand "floatunssisf2"
4807   [(use (match_operand:SF 0 "register_operand" ""))
4808    (use (match_operand:SI 1 "register_operand" ""))]
4809   "!TARGET_64BIT && TARGET_SSE_MATH"
4810   "x86_emit_floatuns (operands); DONE;")
4811
4812 (define_expand "floatunsdisf2"
4813   [(use (match_operand:SF 0 "register_operand" ""))
4814    (use (match_operand:DI 1 "register_operand" ""))]
4815   "TARGET_64BIT && TARGET_SSE_MATH"
4816   "x86_emit_floatuns (operands); DONE;")
4817
4818 (define_expand "floatunsdidf2"
4819   [(use (match_operand:DF 0 "register_operand" ""))
4820    (use (match_operand:DI 1 "register_operand" ""))]
4821   "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4822   "x86_emit_floatuns (operands); DONE;")
4823 \f
4824 ;; SSE extract/set expanders
4825
4826 \f
4827 ;; Add instructions
4828
4829 ;; %%% splits for addditi3
4830
4831 (define_expand "addti3"
4832   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4833         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4834                  (match_operand:TI 2 "x86_64_general_operand" "")))
4835    (clobber (reg:CC FLAGS_REG))]
4836   "TARGET_64BIT"
4837   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4838
4839 (define_insn "*addti3_1"
4840   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4841         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4842                  (match_operand:TI 2 "general_operand" "roiF,riF")))
4843    (clobber (reg:CC FLAGS_REG))]
4844   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4845   "#")
4846
4847 (define_split
4848   [(set (match_operand:TI 0 "nonimmediate_operand" "")
4849         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4850                  (match_operand:TI 2 "general_operand" "")))
4851    (clobber (reg:CC FLAGS_REG))]
4852   "TARGET_64BIT && reload_completed"
4853   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4854                                           UNSPEC_ADD_CARRY))
4855               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4856    (parallel [(set (match_dup 3)
4857                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4858                                      (match_dup 4))
4859                             (match_dup 5)))
4860               (clobber (reg:CC FLAGS_REG))])]
4861   "split_ti (operands+0, 1, operands+0, operands+3);
4862    split_ti (operands+1, 1, operands+1, operands+4);
4863    split_ti (operands+2, 1, operands+2, operands+5);")
4864
4865 ;; %%% splits for addsidi3
4866 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
4867 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
4868 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4869
4870 (define_expand "adddi3"
4871   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4872         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4873                  (match_operand:DI 2 "x86_64_general_operand" "")))
4874    (clobber (reg:CC FLAGS_REG))]
4875   ""
4876   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4877
4878 (define_insn "*adddi3_1"
4879   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4880         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4881                  (match_operand:DI 2 "general_operand" "roiF,riF")))
4882    (clobber (reg:CC FLAGS_REG))]
4883   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4884   "#")
4885
4886 (define_split
4887   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4888         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4889                  (match_operand:DI 2 "general_operand" "")))
4890    (clobber (reg:CC FLAGS_REG))]
4891   "!TARGET_64BIT && reload_completed"
4892   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4893                                           UNSPEC_ADD_CARRY))
4894               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4895    (parallel [(set (match_dup 3)
4896                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4897                                      (match_dup 4))
4898                             (match_dup 5)))
4899               (clobber (reg:CC FLAGS_REG))])]
4900   "split_di (operands+0, 1, operands+0, operands+3);
4901    split_di (operands+1, 1, operands+1, operands+4);
4902    split_di (operands+2, 1, operands+2, operands+5);")
4903
4904 (define_insn "adddi3_carry_rex64"
4905   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4906           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4907                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4908                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4909    (clobber (reg:CC FLAGS_REG))]
4910   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4911   "adc{q}\t{%2, %0|%0, %2}"
4912   [(set_attr "type" "alu")
4913    (set_attr "pent_pair" "pu")
4914    (set_attr "mode" "DI")])
4915
4916 (define_insn "*adddi3_cc_rex64"
4917   [(set (reg:CC FLAGS_REG)
4918         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4919                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4920                    UNSPEC_ADD_CARRY))
4921    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4922         (plus:DI (match_dup 1) (match_dup 2)))]
4923   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4924   "add{q}\t{%2, %0|%0, %2}"
4925   [(set_attr "type" "alu")
4926    (set_attr "mode" "DI")])
4927
4928 (define_insn "addqi3_carry"
4929   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4930           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4931                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4932                    (match_operand:QI 2 "general_operand" "qi,qm")))
4933    (clobber (reg:CC FLAGS_REG))]
4934   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4935   "adc{b}\t{%2, %0|%0, %2}"
4936   [(set_attr "type" "alu")
4937    (set_attr "pent_pair" "pu")
4938    (set_attr "mode" "QI")])
4939
4940 (define_insn "addhi3_carry"
4941   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4942           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4943                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4944                    (match_operand:HI 2 "general_operand" "ri,rm")))
4945    (clobber (reg:CC FLAGS_REG))]
4946   "ix86_binary_operator_ok (PLUS, HImode, operands)"
4947   "adc{w}\t{%2, %0|%0, %2}"
4948   [(set_attr "type" "alu")
4949    (set_attr "pent_pair" "pu")
4950    (set_attr "mode" "HI")])
4951
4952 (define_insn "addsi3_carry"
4953   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4954           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4955                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4956                    (match_operand:SI 2 "general_operand" "ri,rm")))
4957    (clobber (reg:CC FLAGS_REG))]
4958   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4959   "adc{l}\t{%2, %0|%0, %2}"
4960   [(set_attr "type" "alu")
4961    (set_attr "pent_pair" "pu")
4962    (set_attr "mode" "SI")])
4963
4964 (define_insn "*addsi3_carry_zext"
4965   [(set (match_operand:DI 0 "register_operand" "=r")
4966           (zero_extend:DI
4967             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4968                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
4969                      (match_operand:SI 2 "general_operand" "rim"))))
4970    (clobber (reg:CC FLAGS_REG))]
4971   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4972   "adc{l}\t{%2, %k0|%k0, %2}"
4973   [(set_attr "type" "alu")
4974    (set_attr "pent_pair" "pu")
4975    (set_attr "mode" "SI")])
4976
4977 (define_insn "*addsi3_cc"
4978   [(set (reg:CC FLAGS_REG)
4979         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4980                     (match_operand:SI 2 "general_operand" "ri,rm")]
4981                    UNSPEC_ADD_CARRY))
4982    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4983         (plus:SI (match_dup 1) (match_dup 2)))]
4984   "ix86_binary_operator_ok (PLUS, SImode, operands)"
4985   "add{l}\t{%2, %0|%0, %2}"
4986   [(set_attr "type" "alu")
4987    (set_attr "mode" "SI")])
4988
4989 (define_insn "addqi3_cc"
4990   [(set (reg:CC FLAGS_REG)
4991         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4992                     (match_operand:QI 2 "general_operand" "qi,qm")]
4993                    UNSPEC_ADD_CARRY))
4994    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4995         (plus:QI (match_dup 1) (match_dup 2)))]
4996   "ix86_binary_operator_ok (PLUS, QImode, operands)"
4997   "add{b}\t{%2, %0|%0, %2}"
4998   [(set_attr "type" "alu")
4999    (set_attr "mode" "QI")])
5000
5001 (define_expand "addsi3"
5002   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5003                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5004                             (match_operand:SI 2 "general_operand" "")))
5005               (clobber (reg:CC FLAGS_REG))])]
5006   ""
5007   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5008
5009 (define_insn "*lea_1"
5010   [(set (match_operand:SI 0 "register_operand" "=r")
5011         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5012   "!TARGET_64BIT"
5013   "lea{l}\t{%a1, %0|%0, %a1}"
5014   [(set_attr "type" "lea")
5015    (set_attr "mode" "SI")])
5016
5017 (define_insn "*lea_1_rex64"
5018   [(set (match_operand:SI 0 "register_operand" "=r")
5019         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5020   "TARGET_64BIT"
5021   "lea{l}\t{%a1, %0|%0, %a1}"
5022   [(set_attr "type" "lea")
5023    (set_attr "mode" "SI")])
5024
5025 (define_insn "*lea_1_zext"
5026   [(set (match_operand:DI 0 "register_operand" "=r")
5027         (zero_extend:DI
5028          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5029   "TARGET_64BIT"
5030   "lea{l}\t{%a1, %k0|%k0, %a1}"
5031   [(set_attr "type" "lea")
5032    (set_attr "mode" "SI")])
5033
5034 (define_insn "*lea_2_rex64"
5035   [(set (match_operand:DI 0 "register_operand" "=r")
5036         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5037   "TARGET_64BIT"
5038   "lea{q}\t{%a1, %0|%0, %a1}"
5039   [(set_attr "type" "lea")
5040    (set_attr "mode" "DI")])
5041
5042 ;; The lea patterns for non-Pmodes needs to be matched by several
5043 ;; insns converted to real lea by splitters.
5044
5045 (define_insn_and_split "*lea_general_1"
5046   [(set (match_operand 0 "register_operand" "=r")
5047         (plus (plus (match_operand 1 "index_register_operand" "l")
5048                     (match_operand 2 "register_operand" "r"))
5049               (match_operand 3 "immediate_operand" "i")))]
5050   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5051     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5052    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5053    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5054    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5055    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5056        || GET_MODE (operands[3]) == VOIDmode)"
5057   "#"
5058   "&& reload_completed"
5059   [(const_int 0)]
5060 {
5061   rtx pat;
5062   operands[0] = gen_lowpart (SImode, operands[0]);
5063   operands[1] = gen_lowpart (Pmode, operands[1]);
5064   operands[2] = gen_lowpart (Pmode, operands[2]);
5065   operands[3] = gen_lowpart (Pmode, operands[3]);
5066   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5067                       operands[3]);
5068   if (Pmode != SImode)
5069     pat = gen_rtx_SUBREG (SImode, pat, 0);
5070   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5071   DONE;
5072 }
5073   [(set_attr "type" "lea")
5074    (set_attr "mode" "SI")])
5075
5076 (define_insn_and_split "*lea_general_1_zext"
5077   [(set (match_operand:DI 0 "register_operand" "=r")
5078         (zero_extend:DI
5079           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5080                             (match_operand:SI 2 "register_operand" "r"))
5081                    (match_operand:SI 3 "immediate_operand" "i"))))]
5082   "TARGET_64BIT"
5083   "#"
5084   "&& reload_completed"
5085   [(set (match_dup 0)
5086         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5087                                                      (match_dup 2))
5088                                             (match_dup 3)) 0)))]
5089 {
5090   operands[1] = gen_lowpart (Pmode, operands[1]);
5091   operands[2] = gen_lowpart (Pmode, operands[2]);
5092   operands[3] = gen_lowpart (Pmode, operands[3]);
5093 }
5094   [(set_attr "type" "lea")
5095    (set_attr "mode" "SI")])
5096
5097 (define_insn_and_split "*lea_general_2"
5098   [(set (match_operand 0 "register_operand" "=r")
5099         (plus (mult (match_operand 1 "index_register_operand" "l")
5100                     (match_operand 2 "const248_operand" "i"))
5101               (match_operand 3 "nonmemory_operand" "ri")))]
5102   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5103     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5104    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5105    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5106    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5107        || GET_MODE (operands[3]) == VOIDmode)"
5108   "#"
5109   "&& reload_completed"
5110   [(const_int 0)]
5111 {
5112   rtx pat;
5113   operands[0] = gen_lowpart (SImode, operands[0]);
5114   operands[1] = gen_lowpart (Pmode, operands[1]);
5115   operands[3] = gen_lowpart (Pmode, operands[3]);
5116   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5117                       operands[3]);
5118   if (Pmode != SImode)
5119     pat = gen_rtx_SUBREG (SImode, pat, 0);
5120   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5121   DONE;
5122 }
5123   [(set_attr "type" "lea")
5124    (set_attr "mode" "SI")])
5125
5126 (define_insn_and_split "*lea_general_2_zext"
5127   [(set (match_operand:DI 0 "register_operand" "=r")
5128         (zero_extend:DI
5129           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5130                             (match_operand:SI 2 "const248_operand" "n"))
5131                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5132   "TARGET_64BIT"
5133   "#"
5134   "&& reload_completed"
5135   [(set (match_dup 0)
5136         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5137                                                      (match_dup 2))
5138                                             (match_dup 3)) 0)))]
5139 {
5140   operands[1] = gen_lowpart (Pmode, operands[1]);
5141   operands[3] = gen_lowpart (Pmode, operands[3]);
5142 }
5143   [(set_attr "type" "lea")
5144    (set_attr "mode" "SI")])
5145
5146 (define_insn_and_split "*lea_general_3"
5147   [(set (match_operand 0 "register_operand" "=r")
5148         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5149                           (match_operand 2 "const248_operand" "i"))
5150                     (match_operand 3 "register_operand" "r"))
5151               (match_operand 4 "immediate_operand" "i")))]
5152   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5153     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5154    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5155    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5156    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5157   "#"
5158   "&& reload_completed"
5159   [(const_int 0)]
5160 {
5161   rtx pat;
5162   operands[0] = gen_lowpart (SImode, operands[0]);
5163   operands[1] = gen_lowpart (Pmode, operands[1]);
5164   operands[3] = gen_lowpart (Pmode, operands[3]);
5165   operands[4] = gen_lowpart (Pmode, operands[4]);
5166   pat = gen_rtx_PLUS (Pmode,
5167                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5168                                                          operands[2]),
5169                                     operands[3]),
5170                       operands[4]);
5171   if (Pmode != SImode)
5172     pat = gen_rtx_SUBREG (SImode, pat, 0);
5173   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5174   DONE;
5175 }
5176   [(set_attr "type" "lea")
5177    (set_attr "mode" "SI")])
5178
5179 (define_insn_and_split "*lea_general_3_zext"
5180   [(set (match_operand:DI 0 "register_operand" "=r")
5181         (zero_extend:DI
5182           (plus:SI (plus:SI (mult:SI
5183                               (match_operand:SI 1 "index_register_operand" "l")
5184                               (match_operand:SI 2 "const248_operand" "n"))
5185                             (match_operand:SI 3 "register_operand" "r"))
5186                    (match_operand:SI 4 "immediate_operand" "i"))))]
5187   "TARGET_64BIT"
5188   "#"
5189   "&& reload_completed"
5190   [(set (match_dup 0)
5191         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5192                                                               (match_dup 2))
5193                                                      (match_dup 3))
5194                                             (match_dup 4)) 0)))]
5195 {
5196   operands[1] = gen_lowpart (Pmode, operands[1]);
5197   operands[3] = gen_lowpart (Pmode, operands[3]);
5198   operands[4] = gen_lowpart (Pmode, operands[4]);
5199 }
5200   [(set_attr "type" "lea")
5201    (set_attr "mode" "SI")])
5202
5203 (define_insn "*adddi_1_rex64"
5204   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5205         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5206                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5207    (clobber (reg:CC FLAGS_REG))]
5208   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5209 {
5210   switch (get_attr_type (insn))
5211     {
5212     case TYPE_LEA:
5213       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5214       return "lea{q}\t{%a2, %0|%0, %a2}";
5215
5216     case TYPE_INCDEC:
5217       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5218       if (operands[2] == const1_rtx)
5219         return "inc{q}\t%0";
5220       else
5221         {
5222           gcc_assert (operands[2] == constm1_rtx);
5223           return "dec{q}\t%0";
5224         }
5225
5226     default:
5227       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5228
5229       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5230          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5231       if (CONST_INT_P (operands[2])
5232           /* Avoid overflows.  */
5233           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5234           && (INTVAL (operands[2]) == 128
5235               || (INTVAL (operands[2]) < 0
5236                   && INTVAL (operands[2]) != -128)))
5237         {
5238           operands[2] = GEN_INT (-INTVAL (operands[2]));
5239           return "sub{q}\t{%2, %0|%0, %2}";
5240         }
5241       return "add{q}\t{%2, %0|%0, %2}";
5242     }
5243 }
5244   [(set (attr "type")
5245      (cond [(eq_attr "alternative" "2")
5246               (const_string "lea")
5247             ; Current assemblers are broken and do not allow @GOTOFF in
5248             ; ought but a memory context.
5249             (match_operand:DI 2 "pic_symbolic_operand" "")
5250               (const_string "lea")
5251             (match_operand:DI 2 "incdec_operand" "")
5252               (const_string "incdec")
5253            ]
5254            (const_string "alu")))
5255    (set_attr "mode" "DI")])
5256
5257 ;; Convert lea to the lea pattern to avoid flags dependency.
5258 (define_split
5259   [(set (match_operand:DI 0 "register_operand" "")
5260         (plus:DI (match_operand:DI 1 "register_operand" "")
5261                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5262    (clobber (reg:CC FLAGS_REG))]
5263   "TARGET_64BIT && reload_completed
5264    && true_regnum (operands[0]) != true_regnum (operands[1])"
5265   [(set (match_dup 0)
5266         (plus:DI (match_dup 1)
5267                  (match_dup 2)))]
5268   "")
5269
5270 (define_insn "*adddi_2_rex64"
5271   [(set (reg FLAGS_REG)
5272         (compare
5273           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5274                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5275           (const_int 0)))
5276    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5277         (plus:DI (match_dup 1) (match_dup 2)))]
5278   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5279    && ix86_binary_operator_ok (PLUS, DImode, operands)
5280    /* Current assemblers are broken and do not allow @GOTOFF in
5281       ought but a memory context.  */
5282    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5283 {
5284   switch (get_attr_type (insn))
5285     {
5286     case TYPE_INCDEC:
5287       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5288       if (operands[2] == const1_rtx)
5289         return "inc{q}\t%0";
5290       else
5291         {
5292           gcc_assert (operands[2] == constm1_rtx);
5293           return "dec{q}\t%0";
5294         }
5295
5296     default:
5297       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5298       /* ???? We ought to handle there the 32bit case too
5299          - do we need new constraint?  */
5300       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5301          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5302       if (CONST_INT_P (operands[2])
5303           /* Avoid overflows.  */
5304           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5305           && (INTVAL (operands[2]) == 128
5306               || (INTVAL (operands[2]) < 0
5307                   && INTVAL (operands[2]) != -128)))
5308         {
5309           operands[2] = GEN_INT (-INTVAL (operands[2]));
5310           return "sub{q}\t{%2, %0|%0, %2}";
5311         }
5312       return "add{q}\t{%2, %0|%0, %2}";
5313     }
5314 }
5315   [(set (attr "type")
5316      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5317         (const_string "incdec")
5318         (const_string "alu")))
5319    (set_attr "mode" "DI")])
5320
5321 (define_insn "*adddi_3_rex64"
5322   [(set (reg FLAGS_REG)
5323         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5324                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5325    (clobber (match_scratch:DI 0 "=r"))]
5326   "TARGET_64BIT
5327    && ix86_match_ccmode (insn, CCZmode)
5328    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5329    /* Current assemblers are broken and do not allow @GOTOFF in
5330       ought but a memory context.  */
5331    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5332 {
5333   switch (get_attr_type (insn))
5334     {
5335     case TYPE_INCDEC:
5336       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5337       if (operands[2] == const1_rtx)
5338         return "inc{q}\t%0";
5339       else
5340         {
5341           gcc_assert (operands[2] == constm1_rtx);
5342           return "dec{q}\t%0";
5343         }
5344
5345     default:
5346       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5347       /* ???? We ought to handle there the 32bit case too
5348          - do we need new constraint?  */
5349       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5350          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5351       if (CONST_INT_P (operands[2])
5352           /* Avoid overflows.  */
5353           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5354           && (INTVAL (operands[2]) == 128
5355               || (INTVAL (operands[2]) < 0
5356                   && INTVAL (operands[2]) != -128)))
5357         {
5358           operands[2] = GEN_INT (-INTVAL (operands[2]));
5359           return "sub{q}\t{%2, %0|%0, %2}";
5360         }
5361       return "add{q}\t{%2, %0|%0, %2}";
5362     }
5363 }
5364   [(set (attr "type")
5365      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5366         (const_string "incdec")
5367         (const_string "alu")))
5368    (set_attr "mode" "DI")])
5369
5370 ; For comparisons against 1, -1 and 128, we may generate better code
5371 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5372 ; is matched then.  We can't accept general immediate, because for
5373 ; case of overflows,  the result is messed up.
5374 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5375 ; when negated.
5376 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5377 ; only for comparisons not depending on it.
5378 (define_insn "*adddi_4_rex64"
5379   [(set (reg FLAGS_REG)
5380         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5381                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5382    (clobber (match_scratch:DI 0 "=rm"))]
5383   "TARGET_64BIT
5384    &&  ix86_match_ccmode (insn, CCGCmode)"
5385 {
5386   switch (get_attr_type (insn))
5387     {
5388     case TYPE_INCDEC:
5389       if (operands[2] == constm1_rtx)
5390         return "inc{q}\t%0";
5391       else
5392         {
5393           gcc_assert (operands[2] == const1_rtx);
5394           return "dec{q}\t%0";
5395         }
5396
5397     default:
5398       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5399       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5400          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5401       if ((INTVAL (operands[2]) == -128
5402            || (INTVAL (operands[2]) > 0
5403                && INTVAL (operands[2]) != 128))
5404           /* Avoid overflows.  */
5405           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5406         return "sub{q}\t{%2, %0|%0, %2}";
5407       operands[2] = GEN_INT (-INTVAL (operands[2]));
5408       return "add{q}\t{%2, %0|%0, %2}";
5409     }
5410 }
5411   [(set (attr "type")
5412      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5413         (const_string "incdec")
5414         (const_string "alu")))
5415    (set_attr "mode" "DI")])
5416
5417 (define_insn "*adddi_5_rex64"
5418   [(set (reg FLAGS_REG)
5419         (compare
5420           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5421                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
5422           (const_int 0)))
5423    (clobber (match_scratch:DI 0 "=r"))]
5424   "TARGET_64BIT
5425    && ix86_match_ccmode (insn, CCGOCmode)
5426    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5427    /* Current assemblers are broken and do not allow @GOTOFF in
5428       ought but a memory context.  */
5429    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5430 {
5431   switch (get_attr_type (insn))
5432     {
5433     case TYPE_INCDEC:
5434       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5435       if (operands[2] == const1_rtx)
5436         return "inc{q}\t%0";
5437       else
5438         {
5439           gcc_assert (operands[2] == constm1_rtx);
5440           return "dec{q}\t%0";
5441         }
5442
5443     default:
5444       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5445       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5446          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5447       if (CONST_INT_P (operands[2])
5448           /* Avoid overflows.  */
5449           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5450           && (INTVAL (operands[2]) == 128
5451               || (INTVAL (operands[2]) < 0
5452                   && INTVAL (operands[2]) != -128)))
5453         {
5454           operands[2] = GEN_INT (-INTVAL (operands[2]));
5455           return "sub{q}\t{%2, %0|%0, %2}";
5456         }
5457       return "add{q}\t{%2, %0|%0, %2}";
5458     }
5459 }
5460   [(set (attr "type")
5461      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5462         (const_string "incdec")
5463         (const_string "alu")))
5464    (set_attr "mode" "DI")])
5465
5466
5467 (define_insn "*addsi_1"
5468   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5469         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5470                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5471    (clobber (reg:CC FLAGS_REG))]
5472   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5473 {
5474   switch (get_attr_type (insn))
5475     {
5476     case TYPE_LEA:
5477       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5478       return "lea{l}\t{%a2, %0|%0, %a2}";
5479
5480     case TYPE_INCDEC:
5481       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5482       if (operands[2] == const1_rtx)
5483         return "inc{l}\t%0";
5484       else
5485         {
5486           gcc_assert (operands[2] == constm1_rtx);
5487           return "dec{l}\t%0";
5488         }
5489
5490     default:
5491       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5492
5493       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5494          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5495       if (CONST_INT_P (operands[2])
5496           && (INTVAL (operands[2]) == 128
5497               || (INTVAL (operands[2]) < 0
5498                   && INTVAL (operands[2]) != -128)))
5499         {
5500           operands[2] = GEN_INT (-INTVAL (operands[2]));
5501           return "sub{l}\t{%2, %0|%0, %2}";
5502         }
5503       return "add{l}\t{%2, %0|%0, %2}";
5504     }
5505 }
5506   [(set (attr "type")
5507      (cond [(eq_attr "alternative" "2")
5508               (const_string "lea")
5509             ; Current assemblers are broken and do not allow @GOTOFF in
5510             ; ought but a memory context.
5511             (match_operand:SI 2 "pic_symbolic_operand" "")
5512               (const_string "lea")
5513             (match_operand:SI 2 "incdec_operand" "")
5514               (const_string "incdec")
5515            ]
5516            (const_string "alu")))
5517    (set_attr "mode" "SI")])
5518
5519 ;; Convert lea to the lea pattern to avoid flags dependency.
5520 (define_split
5521   [(set (match_operand 0 "register_operand" "")
5522         (plus (match_operand 1 "register_operand" "")
5523               (match_operand 2 "nonmemory_operand" "")))
5524    (clobber (reg:CC FLAGS_REG))]
5525   "reload_completed
5526    && true_regnum (operands[0]) != true_regnum (operands[1])"
5527   [(const_int 0)]
5528 {
5529   rtx pat;
5530   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5531      may confuse gen_lowpart.  */
5532   if (GET_MODE (operands[0]) != Pmode)
5533     {
5534       operands[1] = gen_lowpart (Pmode, operands[1]);
5535       operands[2] = gen_lowpart (Pmode, operands[2]);
5536     }
5537   operands[0] = gen_lowpart (SImode, operands[0]);
5538   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5539   if (Pmode != SImode)
5540     pat = gen_rtx_SUBREG (SImode, pat, 0);
5541   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5542   DONE;
5543 })
5544
5545 ;; It may seem that nonimmediate operand is proper one for operand 1.
5546 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5547 ;; we take care in ix86_binary_operator_ok to not allow two memory
5548 ;; operands so proper swapping will be done in reload.  This allow
5549 ;; patterns constructed from addsi_1 to match.
5550 (define_insn "addsi_1_zext"
5551   [(set (match_operand:DI 0 "register_operand" "=r,r")
5552         (zero_extend:DI
5553           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5554                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
5555    (clobber (reg:CC FLAGS_REG))]
5556   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5557 {
5558   switch (get_attr_type (insn))
5559     {
5560     case TYPE_LEA:
5561       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5562       return "lea{l}\t{%a2, %k0|%k0, %a2}";
5563
5564     case TYPE_INCDEC:
5565       if (operands[2] == const1_rtx)
5566         return "inc{l}\t%k0";
5567       else
5568         {
5569           gcc_assert (operands[2] == constm1_rtx);
5570           return "dec{l}\t%k0";
5571         }
5572
5573     default:
5574       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5575          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5576       if (CONST_INT_P (operands[2])
5577           && (INTVAL (operands[2]) == 128
5578               || (INTVAL (operands[2]) < 0
5579                   && INTVAL (operands[2]) != -128)))
5580         {
5581           operands[2] = GEN_INT (-INTVAL (operands[2]));
5582           return "sub{l}\t{%2, %k0|%k0, %2}";
5583         }
5584       return "add{l}\t{%2, %k0|%k0, %2}";
5585     }
5586 }
5587   [(set (attr "type")
5588      (cond [(eq_attr "alternative" "1")
5589               (const_string "lea")
5590             ; Current assemblers are broken and do not allow @GOTOFF in
5591             ; ought but a memory context.
5592             (match_operand:SI 2 "pic_symbolic_operand" "")
5593               (const_string "lea")
5594             (match_operand:SI 2 "incdec_operand" "")
5595               (const_string "incdec")
5596            ]
5597            (const_string "alu")))
5598    (set_attr "mode" "SI")])
5599
5600 ;; Convert lea to the lea pattern to avoid flags dependency.
5601 (define_split
5602   [(set (match_operand:DI 0 "register_operand" "")
5603         (zero_extend:DI
5604           (plus:SI (match_operand:SI 1 "register_operand" "")
5605                    (match_operand:SI 2 "nonmemory_operand" ""))))
5606    (clobber (reg:CC FLAGS_REG))]
5607   "TARGET_64BIT && reload_completed
5608    && true_regnum (operands[0]) != true_regnum (operands[1])"
5609   [(set (match_dup 0)
5610         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5611 {
5612   operands[1] = gen_lowpart (Pmode, operands[1]);
5613   operands[2] = gen_lowpart (Pmode, operands[2]);
5614 })
5615
5616 (define_insn "*addsi_2"
5617   [(set (reg FLAGS_REG)
5618         (compare
5619           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5620                    (match_operand:SI 2 "general_operand" "rmni,rni"))
5621           (const_int 0)))
5622    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5623         (plus:SI (match_dup 1) (match_dup 2)))]
5624   "ix86_match_ccmode (insn, CCGOCmode)
5625    && ix86_binary_operator_ok (PLUS, SImode, operands)
5626    /* Current assemblers are broken and do not allow @GOTOFF in
5627       ought but a memory context.  */
5628    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5629 {
5630   switch (get_attr_type (insn))
5631     {
5632     case TYPE_INCDEC:
5633       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5634       if (operands[2] == const1_rtx)
5635         return "inc{l}\t%0";
5636       else
5637         {
5638           gcc_assert (operands[2] == constm1_rtx);
5639           return "dec{l}\t%0";
5640         }
5641
5642     default:
5643       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5644       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5645          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5646       if (CONST_INT_P (operands[2])
5647           && (INTVAL (operands[2]) == 128
5648               || (INTVAL (operands[2]) < 0
5649                   && INTVAL (operands[2]) != -128)))
5650         {
5651           operands[2] = GEN_INT (-INTVAL (operands[2]));
5652           return "sub{l}\t{%2, %0|%0, %2}";
5653         }
5654       return "add{l}\t{%2, %0|%0, %2}";
5655     }
5656 }
5657   [(set (attr "type")
5658      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5659         (const_string "incdec")
5660         (const_string "alu")))
5661    (set_attr "mode" "SI")])
5662
5663 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5664 (define_insn "*addsi_2_zext"
5665   [(set (reg FLAGS_REG)
5666         (compare
5667           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5668                    (match_operand:SI 2 "general_operand" "rmni"))
5669           (const_int 0)))
5670    (set (match_operand:DI 0 "register_operand" "=r")
5671         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5672   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5673    && ix86_binary_operator_ok (PLUS, SImode, operands)
5674    /* Current assemblers are broken and do not allow @GOTOFF in
5675       ought but a memory context.  */
5676    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5677 {
5678   switch (get_attr_type (insn))
5679     {
5680     case TYPE_INCDEC:
5681       if (operands[2] == const1_rtx)
5682         return "inc{l}\t%k0";
5683       else
5684         {
5685           gcc_assert (operands[2] == constm1_rtx);
5686           return "dec{l}\t%k0";
5687         }
5688
5689     default:
5690       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5691          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5692       if (CONST_INT_P (operands[2])
5693           && (INTVAL (operands[2]) == 128
5694               || (INTVAL (operands[2]) < 0
5695                   && INTVAL (operands[2]) != -128)))
5696         {
5697           operands[2] = GEN_INT (-INTVAL (operands[2]));
5698           return "sub{l}\t{%2, %k0|%k0, %2}";
5699         }
5700       return "add{l}\t{%2, %k0|%k0, %2}";
5701     }
5702 }
5703   [(set (attr "type")
5704      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5705         (const_string "incdec")
5706         (const_string "alu")))
5707    (set_attr "mode" "SI")])
5708
5709 (define_insn "*addsi_3"
5710   [(set (reg FLAGS_REG)
5711         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5712                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5713    (clobber (match_scratch:SI 0 "=r"))]
5714   "ix86_match_ccmode (insn, CCZmode)
5715    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5716    /* Current assemblers are broken and do not allow @GOTOFF in
5717       ought but a memory context.  */
5718    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5719 {
5720   switch (get_attr_type (insn))
5721     {
5722     case TYPE_INCDEC:
5723       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5724       if (operands[2] == const1_rtx)
5725         return "inc{l}\t%0";
5726       else
5727         {
5728           gcc_assert (operands[2] == constm1_rtx);
5729           return "dec{l}\t%0";
5730         }
5731
5732     default:
5733       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5734       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5735          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5736       if (CONST_INT_P (operands[2])
5737           && (INTVAL (operands[2]) == 128
5738               || (INTVAL (operands[2]) < 0
5739                   && INTVAL (operands[2]) != -128)))
5740         {
5741           operands[2] = GEN_INT (-INTVAL (operands[2]));
5742           return "sub{l}\t{%2, %0|%0, %2}";
5743         }
5744       return "add{l}\t{%2, %0|%0, %2}";
5745     }
5746 }
5747   [(set (attr "type")
5748      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5749         (const_string "incdec")
5750         (const_string "alu")))
5751    (set_attr "mode" "SI")])
5752
5753 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5754 (define_insn "*addsi_3_zext"
5755   [(set (reg FLAGS_REG)
5756         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5757                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
5758    (set (match_operand:DI 0 "register_operand" "=r")
5759         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5760   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5761    && ix86_binary_operator_ok (PLUS, SImode, operands)
5762    /* Current assemblers are broken and do not allow @GOTOFF in
5763       ought but a memory context.  */
5764    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5765 {
5766   switch (get_attr_type (insn))
5767     {
5768     case TYPE_INCDEC:
5769       if (operands[2] == const1_rtx)
5770         return "inc{l}\t%k0";
5771       else
5772         {
5773           gcc_assert (operands[2] == constm1_rtx);
5774           return "dec{l}\t%k0";
5775         }
5776
5777     default:
5778       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5779          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5780       if (CONST_INT_P (operands[2])
5781           && (INTVAL (operands[2]) == 128
5782               || (INTVAL (operands[2]) < 0
5783                   && INTVAL (operands[2]) != -128)))
5784         {
5785           operands[2] = GEN_INT (-INTVAL (operands[2]));
5786           return "sub{l}\t{%2, %k0|%k0, %2}";
5787         }
5788       return "add{l}\t{%2, %k0|%k0, %2}";
5789     }
5790 }
5791   [(set (attr "type")
5792      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5793         (const_string "incdec")
5794         (const_string "alu")))
5795    (set_attr "mode" "SI")])
5796
5797 ; For comparisons against 1, -1 and 128, we may generate better code
5798 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5799 ; is matched then.  We can't accept general immediate, because for
5800 ; case of overflows,  the result is messed up.
5801 ; This pattern also don't hold of 0x80000000, since the value overflows
5802 ; when negated.
5803 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5804 ; only for comparisons not depending on it.
5805 (define_insn "*addsi_4"
5806   [(set (reg FLAGS_REG)
5807         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5808                  (match_operand:SI 2 "const_int_operand" "n")))
5809    (clobber (match_scratch:SI 0 "=rm"))]
5810   "ix86_match_ccmode (insn, CCGCmode)
5811    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5812 {
5813   switch (get_attr_type (insn))
5814     {
5815     case TYPE_INCDEC:
5816       if (operands[2] == constm1_rtx)
5817         return "inc{l}\t%0";
5818       else
5819         {
5820           gcc_assert (operands[2] == const1_rtx);
5821           return "dec{l}\t%0";
5822         }
5823
5824     default:
5825       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5826       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5827          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5828       if ((INTVAL (operands[2]) == -128
5829            || (INTVAL (operands[2]) > 0
5830                && INTVAL (operands[2]) != 128)))
5831         return "sub{l}\t{%2, %0|%0, %2}";
5832       operands[2] = GEN_INT (-INTVAL (operands[2]));
5833       return "add{l}\t{%2, %0|%0, %2}";
5834     }
5835 }
5836   [(set (attr "type")
5837      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5838         (const_string "incdec")
5839         (const_string "alu")))
5840    (set_attr "mode" "SI")])
5841
5842 (define_insn "*addsi_5"
5843   [(set (reg FLAGS_REG)
5844         (compare
5845           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5846                    (match_operand:SI 2 "general_operand" "rmni"))
5847           (const_int 0)))
5848    (clobber (match_scratch:SI 0 "=r"))]
5849   "ix86_match_ccmode (insn, CCGOCmode)
5850    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5851    /* Current assemblers are broken and do not allow @GOTOFF in
5852       ought but a memory context.  */
5853    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5854 {
5855   switch (get_attr_type (insn))
5856     {
5857     case TYPE_INCDEC:
5858       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5859       if (operands[2] == const1_rtx)
5860         return "inc{l}\t%0";
5861       else
5862         {
5863           gcc_assert (operands[2] == constm1_rtx);
5864           return "dec{l}\t%0";
5865         }
5866
5867     default:
5868       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5869       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5870          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5871       if (CONST_INT_P (operands[2])
5872           && (INTVAL (operands[2]) == 128
5873               || (INTVAL (operands[2]) < 0
5874                   && INTVAL (operands[2]) != -128)))
5875         {
5876           operands[2] = GEN_INT (-INTVAL (operands[2]));
5877           return "sub{l}\t{%2, %0|%0, %2}";
5878         }
5879       return "add{l}\t{%2, %0|%0, %2}";
5880     }
5881 }
5882   [(set (attr "type")
5883      (if_then_else (match_operand:SI 2 "incdec_operand" "")
5884         (const_string "incdec")
5885         (const_string "alu")))
5886    (set_attr "mode" "SI")])
5887
5888 (define_expand "addhi3"
5889   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5890                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5891                             (match_operand:HI 2 "general_operand" "")))
5892               (clobber (reg:CC FLAGS_REG))])]
5893   "TARGET_HIMODE_MATH"
5894   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5895
5896 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5897 ;; type optimizations enabled by define-splits.  This is not important
5898 ;; for PII, and in fact harmful because of partial register stalls.
5899
5900 (define_insn "*addhi_1_lea"
5901   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5902         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5903                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5904    (clobber (reg:CC FLAGS_REG))]
5905   "!TARGET_PARTIAL_REG_STALL
5906    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5907 {
5908   switch (get_attr_type (insn))
5909     {
5910     case TYPE_LEA:
5911       return "#";
5912     case TYPE_INCDEC:
5913       if (operands[2] == const1_rtx)
5914         return "inc{w}\t%0";
5915       else
5916         {
5917           gcc_assert (operands[2] == constm1_rtx);
5918           return "dec{w}\t%0";
5919         }
5920
5921     default:
5922       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5923          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5924       if (CONST_INT_P (operands[2])
5925           && (INTVAL (operands[2]) == 128
5926               || (INTVAL (operands[2]) < 0
5927                   && INTVAL (operands[2]) != -128)))
5928         {
5929           operands[2] = GEN_INT (-INTVAL (operands[2]));
5930           return "sub{w}\t{%2, %0|%0, %2}";
5931         }
5932       return "add{w}\t{%2, %0|%0, %2}";
5933     }
5934 }
5935   [(set (attr "type")
5936      (if_then_else (eq_attr "alternative" "2")
5937         (const_string "lea")
5938         (if_then_else (match_operand:HI 2 "incdec_operand" "")
5939            (const_string "incdec")
5940            (const_string "alu"))))
5941    (set_attr "mode" "HI,HI,SI")])
5942
5943 (define_insn "*addhi_1"
5944   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5945         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5946                  (match_operand:HI 2 "general_operand" "ri,rm")))
5947    (clobber (reg:CC FLAGS_REG))]
5948   "TARGET_PARTIAL_REG_STALL
5949    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5950 {
5951   switch (get_attr_type (insn))
5952     {
5953     case TYPE_INCDEC:
5954       if (operands[2] == const1_rtx)
5955         return "inc{w}\t%0";
5956       else
5957         {
5958           gcc_assert (operands[2] == constm1_rtx);
5959           return "dec{w}\t%0";
5960         }
5961
5962     default:
5963       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5964          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5965       if (CONST_INT_P (operands[2])
5966           && (INTVAL (operands[2]) == 128
5967               || (INTVAL (operands[2]) < 0
5968                   && INTVAL (operands[2]) != -128)))
5969         {
5970           operands[2] = GEN_INT (-INTVAL (operands[2]));
5971           return "sub{w}\t{%2, %0|%0, %2}";
5972         }
5973       return "add{w}\t{%2, %0|%0, %2}";
5974     }
5975 }
5976   [(set (attr "type")
5977      (if_then_else (match_operand:HI 2 "incdec_operand" "")
5978         (const_string "incdec")
5979         (const_string "alu")))
5980    (set_attr "mode" "HI")])
5981
5982 (define_insn "*addhi_2"
5983   [(set (reg FLAGS_REG)
5984         (compare
5985           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5986                    (match_operand:HI 2 "general_operand" "rmni,rni"))
5987           (const_int 0)))
5988    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5989         (plus:HI (match_dup 1) (match_dup 2)))]
5990   "ix86_match_ccmode (insn, CCGOCmode)
5991    && ix86_binary_operator_ok (PLUS, HImode, operands)"
5992 {
5993   switch (get_attr_type (insn))
5994     {
5995     case TYPE_INCDEC:
5996       if (operands[2] == const1_rtx)
5997         return "inc{w}\t%0";
5998       else
5999         {
6000           gcc_assert (operands[2] == constm1_rtx);
6001           return "dec{w}\t%0";
6002         }
6003
6004     default:
6005       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6006          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6007       if (CONST_INT_P (operands[2])
6008           && (INTVAL (operands[2]) == 128
6009               || (INTVAL (operands[2]) < 0
6010                   && INTVAL (operands[2]) != -128)))
6011         {
6012           operands[2] = GEN_INT (-INTVAL (operands[2]));
6013           return "sub{w}\t{%2, %0|%0, %2}";
6014         }
6015       return "add{w}\t{%2, %0|%0, %2}";
6016     }
6017 }
6018   [(set (attr "type")
6019      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6020         (const_string "incdec")
6021         (const_string "alu")))
6022    (set_attr "mode" "HI")])
6023
6024 (define_insn "*addhi_3"
6025   [(set (reg FLAGS_REG)
6026         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6027                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6028    (clobber (match_scratch:HI 0 "=r"))]
6029   "ix86_match_ccmode (insn, CCZmode)
6030    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6031 {
6032   switch (get_attr_type (insn))
6033     {
6034     case TYPE_INCDEC:
6035       if (operands[2] == const1_rtx)
6036         return "inc{w}\t%0";
6037       else
6038         {
6039           gcc_assert (operands[2] == constm1_rtx);
6040           return "dec{w}\t%0";
6041         }
6042
6043     default:
6044       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6045          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6046       if (CONST_INT_P (operands[2])
6047           && (INTVAL (operands[2]) == 128
6048               || (INTVAL (operands[2]) < 0
6049                   && INTVAL (operands[2]) != -128)))
6050         {
6051           operands[2] = GEN_INT (-INTVAL (operands[2]));
6052           return "sub{w}\t{%2, %0|%0, %2}";
6053         }
6054       return "add{w}\t{%2, %0|%0, %2}";
6055     }
6056 }
6057   [(set (attr "type")
6058      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6059         (const_string "incdec")
6060         (const_string "alu")))
6061    (set_attr "mode" "HI")])
6062
6063 ; See comments above addsi_4 for details.
6064 (define_insn "*addhi_4"
6065   [(set (reg FLAGS_REG)
6066         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6067                  (match_operand:HI 2 "const_int_operand" "n")))
6068    (clobber (match_scratch:HI 0 "=rm"))]
6069   "ix86_match_ccmode (insn, CCGCmode)
6070    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6071 {
6072   switch (get_attr_type (insn))
6073     {
6074     case TYPE_INCDEC:
6075       if (operands[2] == constm1_rtx)
6076         return "inc{w}\t%0";
6077       else
6078         {
6079           gcc_assert (operands[2] == const1_rtx);
6080           return "dec{w}\t%0";
6081         }
6082
6083     default:
6084       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6085       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6086          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6087       if ((INTVAL (operands[2]) == -128
6088            || (INTVAL (operands[2]) > 0
6089                && INTVAL (operands[2]) != 128)))
6090         return "sub{w}\t{%2, %0|%0, %2}";
6091       operands[2] = GEN_INT (-INTVAL (operands[2]));
6092       return "add{w}\t{%2, %0|%0, %2}";
6093     }
6094 }
6095   [(set (attr "type")
6096      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6097         (const_string "incdec")
6098         (const_string "alu")))
6099    (set_attr "mode" "SI")])
6100
6101
6102 (define_insn "*addhi_5"
6103   [(set (reg FLAGS_REG)
6104         (compare
6105           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6106                    (match_operand:HI 2 "general_operand" "rmni"))
6107           (const_int 0)))
6108    (clobber (match_scratch:HI 0 "=r"))]
6109   "ix86_match_ccmode (insn, CCGOCmode)
6110    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6111 {
6112   switch (get_attr_type (insn))
6113     {
6114     case TYPE_INCDEC:
6115       if (operands[2] == const1_rtx)
6116         return "inc{w}\t%0";
6117       else
6118         {
6119           gcc_assert (operands[2] == constm1_rtx);
6120           return "dec{w}\t%0";
6121         }
6122
6123     default:
6124       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6125          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6126       if (CONST_INT_P (operands[2])
6127           && (INTVAL (operands[2]) == 128
6128               || (INTVAL (operands[2]) < 0
6129                   && INTVAL (operands[2]) != -128)))
6130         {
6131           operands[2] = GEN_INT (-INTVAL (operands[2]));
6132           return "sub{w}\t{%2, %0|%0, %2}";
6133         }
6134       return "add{w}\t{%2, %0|%0, %2}";
6135     }
6136 }
6137   [(set (attr "type")
6138      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6139         (const_string "incdec")
6140         (const_string "alu")))
6141    (set_attr "mode" "HI")])
6142
6143 (define_expand "addqi3"
6144   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6145                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6146                             (match_operand:QI 2 "general_operand" "")))
6147               (clobber (reg:CC FLAGS_REG))])]
6148   "TARGET_QIMODE_MATH"
6149   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6150
6151 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6152 (define_insn "*addqi_1_lea"
6153   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6154         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6155                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6156    (clobber (reg:CC FLAGS_REG))]
6157   "!TARGET_PARTIAL_REG_STALL
6158    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6159 {
6160   int widen = (which_alternative == 2);
6161   switch (get_attr_type (insn))
6162     {
6163     case TYPE_LEA:
6164       return "#";
6165     case TYPE_INCDEC:
6166       if (operands[2] == const1_rtx)
6167         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6168       else
6169         {
6170           gcc_assert (operands[2] == constm1_rtx);
6171           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6172         }
6173
6174     default:
6175       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6176          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6177       if (CONST_INT_P (operands[2])
6178           && (INTVAL (operands[2]) == 128
6179               || (INTVAL (operands[2]) < 0
6180                   && INTVAL (operands[2]) != -128)))
6181         {
6182           operands[2] = GEN_INT (-INTVAL (operands[2]));
6183           if (widen)
6184             return "sub{l}\t{%2, %k0|%k0, %2}";
6185           else
6186             return "sub{b}\t{%2, %0|%0, %2}";
6187         }
6188       if (widen)
6189         return "add{l}\t{%k2, %k0|%k0, %k2}";
6190       else
6191         return "add{b}\t{%2, %0|%0, %2}";
6192     }
6193 }
6194   [(set (attr "type")
6195      (if_then_else (eq_attr "alternative" "3")
6196         (const_string "lea")
6197         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6198            (const_string "incdec")
6199            (const_string "alu"))))
6200    (set_attr "mode" "QI,QI,SI,SI")])
6201
6202 (define_insn "*addqi_1"
6203   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6204         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6205                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6206    (clobber (reg:CC FLAGS_REG))]
6207   "TARGET_PARTIAL_REG_STALL
6208    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6209 {
6210   int widen = (which_alternative == 2);
6211   switch (get_attr_type (insn))
6212     {
6213     case TYPE_INCDEC:
6214       if (operands[2] == const1_rtx)
6215         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6216       else
6217         {
6218           gcc_assert (operands[2] == constm1_rtx);
6219           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6220         }
6221
6222     default:
6223       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6224          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6225       if (CONST_INT_P (operands[2])
6226           && (INTVAL (operands[2]) == 128
6227               || (INTVAL (operands[2]) < 0
6228                   && INTVAL (operands[2]) != -128)))
6229         {
6230           operands[2] = GEN_INT (-INTVAL (operands[2]));
6231           if (widen)
6232             return "sub{l}\t{%2, %k0|%k0, %2}";
6233           else
6234             return "sub{b}\t{%2, %0|%0, %2}";
6235         }
6236       if (widen)
6237         return "add{l}\t{%k2, %k0|%k0, %k2}";
6238       else
6239         return "add{b}\t{%2, %0|%0, %2}";
6240     }
6241 }
6242   [(set (attr "type")
6243      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6244         (const_string "incdec")
6245         (const_string "alu")))
6246    (set_attr "mode" "QI,QI,SI")])
6247
6248 (define_insn "*addqi_1_slp"
6249   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6250         (plus:QI (match_dup 0)
6251                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6252    (clobber (reg:CC FLAGS_REG))]
6253   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6254    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6255 {
6256   switch (get_attr_type (insn))
6257     {
6258     case TYPE_INCDEC:
6259       if (operands[1] == const1_rtx)
6260         return "inc{b}\t%0";
6261       else
6262         {
6263           gcc_assert (operands[1] == constm1_rtx);
6264           return "dec{b}\t%0";
6265         }
6266
6267     default:
6268       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6269       if (CONST_INT_P (operands[1])
6270           && INTVAL (operands[1]) < 0)
6271         {
6272           operands[1] = GEN_INT (-INTVAL (operands[1]));
6273           return "sub{b}\t{%1, %0|%0, %1}";
6274         }
6275       return "add{b}\t{%1, %0|%0, %1}";
6276     }
6277 }
6278   [(set (attr "type")
6279      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6280         (const_string "incdec")
6281         (const_string "alu1")))
6282    (set (attr "memory")
6283      (if_then_else (match_operand 1 "memory_operand" "")
6284         (const_string "load")
6285         (const_string "none")))
6286    (set_attr "mode" "QI")])
6287
6288 (define_insn "*addqi_2"
6289   [(set (reg FLAGS_REG)
6290         (compare
6291           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6292                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6293           (const_int 0)))
6294    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6295         (plus:QI (match_dup 1) (match_dup 2)))]
6296   "ix86_match_ccmode (insn, CCGOCmode)
6297    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6298 {
6299   switch (get_attr_type (insn))
6300     {
6301     case TYPE_INCDEC:
6302       if (operands[2] == const1_rtx)
6303         return "inc{b}\t%0";
6304       else
6305         {
6306           gcc_assert (operands[2] == constm1_rtx
6307                       || (CONST_INT_P (operands[2])
6308                           && INTVAL (operands[2]) == 255));
6309           return "dec{b}\t%0";
6310         }
6311
6312     default:
6313       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6314       if (CONST_INT_P (operands[2])
6315           && INTVAL (operands[2]) < 0)
6316         {
6317           operands[2] = GEN_INT (-INTVAL (operands[2]));
6318           return "sub{b}\t{%2, %0|%0, %2}";
6319         }
6320       return "add{b}\t{%2, %0|%0, %2}";
6321     }
6322 }
6323   [(set (attr "type")
6324      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6325         (const_string "incdec")
6326         (const_string "alu")))
6327    (set_attr "mode" "QI")])
6328
6329 (define_insn "*addqi_3"
6330   [(set (reg FLAGS_REG)
6331         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6332                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
6333    (clobber (match_scratch:QI 0 "=q"))]
6334   "ix86_match_ccmode (insn, CCZmode)
6335    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6336 {
6337   switch (get_attr_type (insn))
6338     {
6339     case TYPE_INCDEC:
6340       if (operands[2] == const1_rtx)
6341         return "inc{b}\t%0";
6342       else
6343         {
6344           gcc_assert (operands[2] == constm1_rtx
6345                       || (CONST_INT_P (operands[2])
6346                           && INTVAL (operands[2]) == 255));
6347           return "dec{b}\t%0";
6348         }
6349
6350     default:
6351       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6352       if (CONST_INT_P (operands[2])
6353           && INTVAL (operands[2]) < 0)
6354         {
6355           operands[2] = GEN_INT (-INTVAL (operands[2]));
6356           return "sub{b}\t{%2, %0|%0, %2}";
6357         }
6358       return "add{b}\t{%2, %0|%0, %2}";
6359     }
6360 }
6361   [(set (attr "type")
6362      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6363         (const_string "incdec")
6364         (const_string "alu")))
6365    (set_attr "mode" "QI")])
6366
6367 ; See comments above addsi_4 for details.
6368 (define_insn "*addqi_4"
6369   [(set (reg FLAGS_REG)
6370         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6371                  (match_operand:QI 2 "const_int_operand" "n")))
6372    (clobber (match_scratch:QI 0 "=qm"))]
6373   "ix86_match_ccmode (insn, CCGCmode)
6374    && (INTVAL (operands[2]) & 0xff) != 0x80"
6375 {
6376   switch (get_attr_type (insn))
6377     {
6378     case TYPE_INCDEC:
6379       if (operands[2] == constm1_rtx
6380           || (CONST_INT_P (operands[2])
6381               && INTVAL (operands[2]) == 255))
6382         return "inc{b}\t%0";
6383       else
6384         {
6385           gcc_assert (operands[2] == const1_rtx);
6386           return "dec{b}\t%0";
6387         }
6388
6389     default:
6390       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6391       if (INTVAL (operands[2]) < 0)
6392         {
6393           operands[2] = GEN_INT (-INTVAL (operands[2]));
6394           return "add{b}\t{%2, %0|%0, %2}";
6395         }
6396       return "sub{b}\t{%2, %0|%0, %2}";
6397     }
6398 }
6399   [(set (attr "type")
6400      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6401         (const_string "incdec")
6402         (const_string "alu")))
6403    (set_attr "mode" "QI")])
6404
6405
6406 (define_insn "*addqi_5"
6407   [(set (reg FLAGS_REG)
6408         (compare
6409           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6410                    (match_operand:QI 2 "general_operand" "qmni"))
6411           (const_int 0)))
6412    (clobber (match_scratch:QI 0 "=q"))]
6413   "ix86_match_ccmode (insn, CCGOCmode)
6414    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6415 {
6416   switch (get_attr_type (insn))
6417     {
6418     case TYPE_INCDEC:
6419       if (operands[2] == const1_rtx)
6420         return "inc{b}\t%0";
6421       else
6422         {
6423           gcc_assert (operands[2] == constm1_rtx
6424                       || (CONST_INT_P (operands[2])
6425                           && INTVAL (operands[2]) == 255));
6426           return "dec{b}\t%0";
6427         }
6428
6429     default:
6430       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6431       if (CONST_INT_P (operands[2])
6432           && INTVAL (operands[2]) < 0)
6433         {
6434           operands[2] = GEN_INT (-INTVAL (operands[2]));
6435           return "sub{b}\t{%2, %0|%0, %2}";
6436         }
6437       return "add{b}\t{%2, %0|%0, %2}";
6438     }
6439 }
6440   [(set (attr "type")
6441      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6442         (const_string "incdec")
6443         (const_string "alu")))
6444    (set_attr "mode" "QI")])
6445
6446
6447 (define_insn "addqi_ext_1"
6448   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6449                          (const_int 8)
6450                          (const_int 8))
6451         (plus:SI
6452           (zero_extract:SI
6453             (match_operand 1 "ext_register_operand" "0")
6454             (const_int 8)
6455             (const_int 8))
6456           (match_operand:QI 2 "general_operand" "Qmn")))
6457    (clobber (reg:CC FLAGS_REG))]
6458   "!TARGET_64BIT"
6459 {
6460   switch (get_attr_type (insn))
6461     {
6462     case TYPE_INCDEC:
6463       if (operands[2] == const1_rtx)
6464         return "inc{b}\t%h0";
6465       else
6466         {
6467           gcc_assert (operands[2] == constm1_rtx
6468                       || (CONST_INT_P (operands[2])
6469                           && INTVAL (operands[2]) == 255));
6470           return "dec{b}\t%h0";
6471         }
6472
6473     default:
6474       return "add{b}\t{%2, %h0|%h0, %2}";
6475     }
6476 }
6477   [(set (attr "type")
6478      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6479         (const_string "incdec")
6480         (const_string "alu")))
6481    (set_attr "mode" "QI")])
6482
6483 (define_insn "*addqi_ext_1_rex64"
6484   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6485                          (const_int 8)
6486                          (const_int 8))
6487         (plus:SI
6488           (zero_extract:SI
6489             (match_operand 1 "ext_register_operand" "0")
6490             (const_int 8)
6491             (const_int 8))
6492           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6493    (clobber (reg:CC FLAGS_REG))]
6494   "TARGET_64BIT"
6495 {
6496   switch (get_attr_type (insn))
6497     {
6498     case TYPE_INCDEC:
6499       if (operands[2] == const1_rtx)
6500         return "inc{b}\t%h0";
6501       else
6502         {
6503           gcc_assert (operands[2] == constm1_rtx
6504                       || (CONST_INT_P (operands[2])
6505                           && INTVAL (operands[2]) == 255));
6506           return "dec{b}\t%h0";
6507         }
6508
6509     default:
6510       return "add{b}\t{%2, %h0|%h0, %2}";
6511     }
6512 }
6513   [(set (attr "type")
6514      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6515         (const_string "incdec")
6516         (const_string "alu")))
6517    (set_attr "mode" "QI")])
6518
6519 (define_insn "*addqi_ext_2"
6520   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6521                          (const_int 8)
6522                          (const_int 8))
6523         (plus:SI
6524           (zero_extract:SI
6525             (match_operand 1 "ext_register_operand" "%0")
6526             (const_int 8)
6527             (const_int 8))
6528           (zero_extract:SI
6529             (match_operand 2 "ext_register_operand" "Q")
6530             (const_int 8)
6531             (const_int 8))))
6532    (clobber (reg:CC FLAGS_REG))]
6533   ""
6534   "add{b}\t{%h2, %h0|%h0, %h2}"
6535   [(set_attr "type" "alu")
6536    (set_attr "mode" "QI")])
6537
6538 ;; The patterns that match these are at the end of this file.
6539
6540 (define_expand "addxf3"
6541   [(set (match_operand:XF 0 "register_operand" "")
6542         (plus:XF (match_operand:XF 1 "register_operand" "")
6543                  (match_operand:XF 2 "register_operand" "")))]
6544   "TARGET_80387"
6545   "")
6546
6547 (define_expand "adddf3"
6548   [(set (match_operand:DF 0 "register_operand" "")
6549         (plus:DF (match_operand:DF 1 "register_operand" "")
6550                  (match_operand:DF 2 "nonimmediate_operand" "")))]
6551   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6552   "")
6553
6554 (define_expand "addsf3"
6555   [(set (match_operand:SF 0 "register_operand" "")
6556         (plus:SF (match_operand:SF 1 "register_operand" "")
6557                  (match_operand:SF 2 "nonimmediate_operand" "")))]
6558   "TARGET_80387 || TARGET_SSE_MATH"
6559   "")
6560 \f
6561 ;; Subtract instructions
6562
6563 ;; %%% splits for subditi3
6564
6565 (define_expand "subti3"
6566   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6567                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6568                              (match_operand:TI 2 "x86_64_general_operand" "")))
6569               (clobber (reg:CC FLAGS_REG))])]
6570   "TARGET_64BIT"
6571   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6572
6573 (define_insn "*subti3_1"
6574   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6575         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6576                   (match_operand:TI 2 "general_operand" "roiF,riF")))
6577    (clobber (reg:CC FLAGS_REG))]
6578   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6579   "#")
6580
6581 (define_split
6582   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6583         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6584                   (match_operand:TI 2 "general_operand" "")))
6585    (clobber (reg:CC FLAGS_REG))]
6586   "TARGET_64BIT && reload_completed"
6587   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6588               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6589    (parallel [(set (match_dup 3)
6590                    (minus:DI (match_dup 4)
6591                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6592                                       (match_dup 5))))
6593               (clobber (reg:CC FLAGS_REG))])]
6594   "split_ti (operands+0, 1, operands+0, operands+3);
6595    split_ti (operands+1, 1, operands+1, operands+4);
6596    split_ti (operands+2, 1, operands+2, operands+5);")
6597
6598 ;; %%% splits for subsidi3
6599
6600 (define_expand "subdi3"
6601   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6602                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6603                              (match_operand:DI 2 "x86_64_general_operand" "")))
6604               (clobber (reg:CC FLAGS_REG))])]
6605   ""
6606   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6607
6608 (define_insn "*subdi3_1"
6609   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6610         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6611                   (match_operand:DI 2 "general_operand" "roiF,riF")))
6612    (clobber (reg:CC FLAGS_REG))]
6613   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6614   "#")
6615
6616 (define_split
6617   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6618         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6619                   (match_operand:DI 2 "general_operand" "")))
6620    (clobber (reg:CC FLAGS_REG))]
6621   "!TARGET_64BIT && reload_completed"
6622   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6623               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6624    (parallel [(set (match_dup 3)
6625                    (minus:SI (match_dup 4)
6626                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6627                                       (match_dup 5))))
6628               (clobber (reg:CC FLAGS_REG))])]
6629   "split_di (operands+0, 1, operands+0, operands+3);
6630    split_di (operands+1, 1, operands+1, operands+4);
6631    split_di (operands+2, 1, operands+2, operands+5);")
6632
6633 (define_insn "subdi3_carry_rex64"
6634   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6635           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6636             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6637                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6638    (clobber (reg:CC FLAGS_REG))]
6639   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6640   "sbb{q}\t{%2, %0|%0, %2}"
6641   [(set_attr "type" "alu")
6642    (set_attr "pent_pair" "pu")
6643    (set_attr "mode" "DI")])
6644
6645 (define_insn "*subdi_1_rex64"
6646   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6647         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6648                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6649    (clobber (reg:CC FLAGS_REG))]
6650   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6651   "sub{q}\t{%2, %0|%0, %2}"
6652   [(set_attr "type" "alu")
6653    (set_attr "mode" "DI")])
6654
6655 (define_insn "*subdi_2_rex64"
6656   [(set (reg FLAGS_REG)
6657         (compare
6658           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6659                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6660           (const_int 0)))
6661    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6662         (minus:DI (match_dup 1) (match_dup 2)))]
6663   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6664    && ix86_binary_operator_ok (MINUS, DImode, operands)"
6665   "sub{q}\t{%2, %0|%0, %2}"
6666   [(set_attr "type" "alu")
6667    (set_attr "mode" "DI")])
6668
6669 (define_insn "*subdi_3_rex63"
6670   [(set (reg FLAGS_REG)
6671         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6672                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6673    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6674         (minus:DI (match_dup 1) (match_dup 2)))]
6675   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6676    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6677   "sub{q}\t{%2, %0|%0, %2}"
6678   [(set_attr "type" "alu")
6679    (set_attr "mode" "DI")])
6680
6681 (define_insn "subqi3_carry"
6682   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6683           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6684             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6685                (match_operand:QI 2 "general_operand" "qi,qm"))))
6686    (clobber (reg:CC FLAGS_REG))]
6687   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6688   "sbb{b}\t{%2, %0|%0, %2}"
6689   [(set_attr "type" "alu")
6690    (set_attr "pent_pair" "pu")
6691    (set_attr "mode" "QI")])
6692
6693 (define_insn "subhi3_carry"
6694   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6695           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6696             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6697                (match_operand:HI 2 "general_operand" "ri,rm"))))
6698    (clobber (reg:CC FLAGS_REG))]
6699   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6700   "sbb{w}\t{%2, %0|%0, %2}"
6701   [(set_attr "type" "alu")
6702    (set_attr "pent_pair" "pu")
6703    (set_attr "mode" "HI")])
6704
6705 (define_insn "subsi3_carry"
6706   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6707           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6708             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6709                (match_operand:SI 2 "general_operand" "ri,rm"))))
6710    (clobber (reg:CC FLAGS_REG))]
6711   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6712   "sbb{l}\t{%2, %0|%0, %2}"
6713   [(set_attr "type" "alu")
6714    (set_attr "pent_pair" "pu")
6715    (set_attr "mode" "SI")])
6716
6717 (define_insn "subsi3_carry_zext"
6718   [(set (match_operand:DI 0 "register_operand" "=rm,r")
6719           (zero_extend:DI
6720             (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6721               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6722                  (match_operand:SI 2 "general_operand" "ri,rm")))))
6723    (clobber (reg:CC FLAGS_REG))]
6724   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6725   "sbb{l}\t{%2, %k0|%k0, %2}"
6726   [(set_attr "type" "alu")
6727    (set_attr "pent_pair" "pu")
6728    (set_attr "mode" "SI")])
6729
6730 (define_expand "subsi3"
6731   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6732                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6733                              (match_operand:SI 2 "general_operand" "")))
6734               (clobber (reg:CC FLAGS_REG))])]
6735   ""
6736   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6737
6738 (define_insn "*subsi_1"
6739   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6740         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6741                   (match_operand:SI 2 "general_operand" "ri,rm")))
6742    (clobber (reg:CC FLAGS_REG))]
6743   "ix86_binary_operator_ok (MINUS, SImode, operands)"
6744   "sub{l}\t{%2, %0|%0, %2}"
6745   [(set_attr "type" "alu")
6746    (set_attr "mode" "SI")])
6747
6748 (define_insn "*subsi_1_zext"
6749   [(set (match_operand:DI 0 "register_operand" "=r")
6750         (zero_extend:DI
6751           (minus:SI (match_operand:SI 1 "register_operand" "0")
6752                     (match_operand:SI 2 "general_operand" "rim"))))
6753    (clobber (reg:CC FLAGS_REG))]
6754   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6755   "sub{l}\t{%2, %k0|%k0, %2}"
6756   [(set_attr "type" "alu")
6757    (set_attr "mode" "SI")])
6758
6759 (define_insn "*subsi_2"
6760   [(set (reg FLAGS_REG)
6761         (compare
6762           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6763                     (match_operand:SI 2 "general_operand" "ri,rm"))
6764           (const_int 0)))
6765    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6766         (minus:SI (match_dup 1) (match_dup 2)))]
6767   "ix86_match_ccmode (insn, CCGOCmode)
6768    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6769   "sub{l}\t{%2, %0|%0, %2}"
6770   [(set_attr "type" "alu")
6771    (set_attr "mode" "SI")])
6772
6773 (define_insn "*subsi_2_zext"
6774   [(set (reg FLAGS_REG)
6775         (compare
6776           (minus:SI (match_operand:SI 1 "register_operand" "0")
6777                     (match_operand:SI 2 "general_operand" "rim"))
6778           (const_int 0)))
6779    (set (match_operand:DI 0 "register_operand" "=r")
6780         (zero_extend:DI
6781           (minus:SI (match_dup 1)
6782                     (match_dup 2))))]
6783   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6784    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6785   "sub{l}\t{%2, %k0|%k0, %2}"
6786   [(set_attr "type" "alu")
6787    (set_attr "mode" "SI")])
6788
6789 (define_insn "*subsi_3"
6790   [(set (reg FLAGS_REG)
6791         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6792                  (match_operand:SI 2 "general_operand" "ri,rm")))
6793    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6794         (minus:SI (match_dup 1) (match_dup 2)))]
6795   "ix86_match_ccmode (insn, CCmode)
6796    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6797   "sub{l}\t{%2, %0|%0, %2}"
6798   [(set_attr "type" "alu")
6799    (set_attr "mode" "SI")])
6800
6801 (define_insn "*subsi_3_zext"
6802   [(set (reg FLAGS_REG)
6803         (compare (match_operand:SI 1 "register_operand" "0")
6804                  (match_operand:SI 2 "general_operand" "rim")))
6805    (set (match_operand:DI 0 "register_operand" "=r")
6806         (zero_extend:DI
6807           (minus:SI (match_dup 1)
6808                     (match_dup 2))))]
6809   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6810    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6811   "sub{l}\t{%2, %1|%1, %2}"
6812   [(set_attr "type" "alu")
6813    (set_attr "mode" "DI")])
6814
6815 (define_expand "subhi3"
6816   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6817                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6818                              (match_operand:HI 2 "general_operand" "")))
6819               (clobber (reg:CC FLAGS_REG))])]
6820   "TARGET_HIMODE_MATH"
6821   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6822
6823 (define_insn "*subhi_1"
6824   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6825         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6826                   (match_operand:HI 2 "general_operand" "ri,rm")))
6827    (clobber (reg:CC FLAGS_REG))]
6828   "ix86_binary_operator_ok (MINUS, HImode, operands)"
6829   "sub{w}\t{%2, %0|%0, %2}"
6830   [(set_attr "type" "alu")
6831    (set_attr "mode" "HI")])
6832
6833 (define_insn "*subhi_2"
6834   [(set (reg FLAGS_REG)
6835         (compare
6836           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6837                     (match_operand:HI 2 "general_operand" "ri,rm"))
6838           (const_int 0)))
6839    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6840         (minus:HI (match_dup 1) (match_dup 2)))]
6841   "ix86_match_ccmode (insn, CCGOCmode)
6842    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6843   "sub{w}\t{%2, %0|%0, %2}"
6844   [(set_attr "type" "alu")
6845    (set_attr "mode" "HI")])
6846
6847 (define_insn "*subhi_3"
6848   [(set (reg FLAGS_REG)
6849         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6850                  (match_operand:HI 2 "general_operand" "ri,rm")))
6851    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6852         (minus:HI (match_dup 1) (match_dup 2)))]
6853   "ix86_match_ccmode (insn, CCmode)
6854    && ix86_binary_operator_ok (MINUS, HImode, operands)"
6855   "sub{w}\t{%2, %0|%0, %2}"
6856   [(set_attr "type" "alu")
6857    (set_attr "mode" "HI")])
6858
6859 (define_expand "subqi3"
6860   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6861                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6862                              (match_operand:QI 2 "general_operand" "")))
6863               (clobber (reg:CC FLAGS_REG))])]
6864   "TARGET_QIMODE_MATH"
6865   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6866
6867 (define_insn "*subqi_1"
6868   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6869         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6870                   (match_operand:QI 2 "general_operand" "qn,qmn")))
6871    (clobber (reg:CC FLAGS_REG))]
6872   "ix86_binary_operator_ok (MINUS, QImode, operands)"
6873   "sub{b}\t{%2, %0|%0, %2}"
6874   [(set_attr "type" "alu")
6875    (set_attr "mode" "QI")])
6876
6877 (define_insn "*subqi_1_slp"
6878   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6879         (minus:QI (match_dup 0)
6880                   (match_operand:QI 1 "general_operand" "qn,qmn")))
6881    (clobber (reg:CC FLAGS_REG))]
6882   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6883    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6884   "sub{b}\t{%1, %0|%0, %1}"
6885   [(set_attr "type" "alu1")
6886    (set_attr "mode" "QI")])
6887
6888 (define_insn "*subqi_2"
6889   [(set (reg FLAGS_REG)
6890         (compare
6891           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6892                     (match_operand:QI 2 "general_operand" "qi,qm"))
6893           (const_int 0)))
6894    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6895         (minus:HI (match_dup 1) (match_dup 2)))]
6896   "ix86_match_ccmode (insn, CCGOCmode)
6897    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6898   "sub{b}\t{%2, %0|%0, %2}"
6899   [(set_attr "type" "alu")
6900    (set_attr "mode" "QI")])
6901
6902 (define_insn "*subqi_3"
6903   [(set (reg FLAGS_REG)
6904         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6905                  (match_operand:QI 2 "general_operand" "qi,qm")))
6906    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6907         (minus:HI (match_dup 1) (match_dup 2)))]
6908   "ix86_match_ccmode (insn, CCmode)
6909    && ix86_binary_operator_ok (MINUS, QImode, operands)"
6910   "sub{b}\t{%2, %0|%0, %2}"
6911   [(set_attr "type" "alu")
6912    (set_attr "mode" "QI")])
6913
6914 ;; The patterns that match these are at the end of this file.
6915
6916 (define_expand "subxf3"
6917   [(set (match_operand:XF 0 "register_operand" "")
6918         (minus:XF (match_operand:XF 1 "register_operand" "")
6919                   (match_operand:XF 2 "register_operand" "")))]
6920   "TARGET_80387"
6921   "")
6922
6923 (define_expand "subdf3"
6924   [(set (match_operand:DF 0 "register_operand" "")
6925         (minus:DF (match_operand:DF 1 "register_operand" "")
6926                   (match_operand:DF 2 "nonimmediate_operand" "")))]
6927   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6928   "")
6929
6930 (define_expand "subsf3"
6931   [(set (match_operand:SF 0 "register_operand" "")
6932         (minus:SF (match_operand:SF 1 "register_operand" "")
6933                   (match_operand:SF 2 "nonimmediate_operand" "")))]
6934   "TARGET_80387 || TARGET_SSE_MATH"
6935   "")
6936 \f
6937 ;; Multiply instructions
6938
6939 (define_expand "muldi3"
6940   [(parallel [(set (match_operand:DI 0 "register_operand" "")
6941                    (mult:DI (match_operand:DI 1 "register_operand" "")
6942                             (match_operand:DI 2 "x86_64_general_operand" "")))
6943               (clobber (reg:CC FLAGS_REG))])]
6944   "TARGET_64BIT"
6945   "")
6946
6947 ;; On AMDFAM10 
6948 ;; IMUL reg64, reg64, imm8      Direct
6949 ;; IMUL reg64, mem64, imm8      VectorPath
6950 ;; IMUL reg64, reg64, imm32     Direct
6951 ;; IMUL reg64, mem64, imm32     VectorPath 
6952 ;; IMUL reg64, reg64            Direct
6953 ;; IMUL reg64, mem64            Direct
6954
6955 (define_insn "*muldi3_1_rex64"
6956   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6957         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6958                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6959    (clobber (reg:CC FLAGS_REG))]
6960   "TARGET_64BIT
6961    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6962   "@
6963    imul{q}\t{%2, %1, %0|%0, %1, %2}
6964    imul{q}\t{%2, %1, %0|%0, %1, %2}
6965    imul{q}\t{%2, %0|%0, %2}"
6966   [(set_attr "type" "imul")
6967    (set_attr "prefix_0f" "0,0,1")
6968    (set (attr "athlon_decode")
6969         (cond [(eq_attr "cpu" "athlon")
6970                   (const_string "vector")
6971                (eq_attr "alternative" "1")
6972                   (const_string "vector")
6973                (and (eq_attr "alternative" "2")
6974                     (match_operand 1 "memory_operand" ""))
6975                   (const_string "vector")]
6976               (const_string "direct")))
6977    (set (attr "amdfam10_decode")
6978         (cond [(and (eq_attr "alternative" "0,1")
6979                     (match_operand 1 "memory_operand" ""))
6980                   (const_string "vector")]
6981               (const_string "direct")))       
6982    (set_attr "mode" "DI")])
6983
6984 (define_expand "mulsi3"
6985   [(parallel [(set (match_operand:SI 0 "register_operand" "")
6986                    (mult:SI (match_operand:SI 1 "register_operand" "")
6987                             (match_operand:SI 2 "general_operand" "")))
6988               (clobber (reg:CC FLAGS_REG))])]
6989   ""
6990   "")
6991
6992 ;; On AMDFAM10 
6993 ;; IMUL reg32, reg32, imm8      Direct
6994 ;; IMUL reg32, mem32, imm8      VectorPath
6995 ;; IMUL reg32, reg32, imm32     Direct
6996 ;; IMUL reg32, mem32, imm32     VectorPath
6997 ;; IMUL reg32, reg32            Direct
6998 ;; IMUL reg32, mem32            Direct
6999
7000 (define_insn "*mulsi3_1"
7001   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7002         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7003                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7004    (clobber (reg:CC FLAGS_REG))]
7005   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7006   "@
7007    imul{l}\t{%2, %1, %0|%0, %1, %2}
7008    imul{l}\t{%2, %1, %0|%0, %1, %2}
7009    imul{l}\t{%2, %0|%0, %2}"
7010   [(set_attr "type" "imul")
7011    (set_attr "prefix_0f" "0,0,1")
7012    (set (attr "athlon_decode")
7013         (cond [(eq_attr "cpu" "athlon")
7014                   (const_string "vector")
7015                (eq_attr "alternative" "1")
7016                   (const_string "vector")
7017                (and (eq_attr "alternative" "2")
7018                     (match_operand 1 "memory_operand" ""))
7019                   (const_string "vector")]
7020               (const_string "direct")))
7021    (set (attr "amdfam10_decode")
7022         (cond [(and (eq_attr "alternative" "0,1")
7023                     (match_operand 1 "memory_operand" ""))
7024                   (const_string "vector")]
7025               (const_string "direct")))       
7026    (set_attr "mode" "SI")])
7027
7028 (define_insn "*mulsi3_1_zext"
7029   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7030         (zero_extend:DI
7031           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7032                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7033    (clobber (reg:CC FLAGS_REG))]
7034   "TARGET_64BIT
7035    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7036   "@
7037    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7038    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7039    imul{l}\t{%2, %k0|%k0, %2}"
7040   [(set_attr "type" "imul")
7041    (set_attr "prefix_0f" "0,0,1")
7042    (set (attr "athlon_decode")
7043         (cond [(eq_attr "cpu" "athlon")
7044                   (const_string "vector")
7045                (eq_attr "alternative" "1")
7046                   (const_string "vector")
7047                (and (eq_attr "alternative" "2")
7048                     (match_operand 1 "memory_operand" ""))
7049                   (const_string "vector")]
7050               (const_string "direct")))
7051    (set (attr "amdfam10_decode")
7052         (cond [(and (eq_attr "alternative" "0,1")
7053                     (match_operand 1 "memory_operand" ""))
7054                   (const_string "vector")]
7055               (const_string "direct")))       
7056    (set_attr "mode" "SI")])
7057
7058 (define_expand "mulhi3"
7059   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7060                    (mult:HI (match_operand:HI 1 "register_operand" "")
7061                             (match_operand:HI 2 "general_operand" "")))
7062               (clobber (reg:CC FLAGS_REG))])]
7063   "TARGET_HIMODE_MATH"
7064   "")
7065
7066 ;; On AMDFAM10
7067 ;; IMUL reg16, reg16, imm8      VectorPath
7068 ;; IMUL reg16, mem16, imm8      VectorPath
7069 ;; IMUL reg16, reg16, imm16     VectorPath
7070 ;; IMUL reg16, mem16, imm16     VectorPath
7071 ;; IMUL reg16, reg16            Direct
7072 ;; IMUL reg16, mem16            Direct
7073 (define_insn "*mulhi3_1"
7074   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7075         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7076                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7077    (clobber (reg:CC FLAGS_REG))]
7078   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7079   "@
7080    imul{w}\t{%2, %1, %0|%0, %1, %2}
7081    imul{w}\t{%2, %1, %0|%0, %1, %2}
7082    imul{w}\t{%2, %0|%0, %2}"
7083   [(set_attr "type" "imul")
7084    (set_attr "prefix_0f" "0,0,1")
7085    (set (attr "athlon_decode")
7086         (cond [(eq_attr "cpu" "athlon")
7087                   (const_string "vector")
7088                (eq_attr "alternative" "1,2")
7089                   (const_string "vector")]
7090               (const_string "direct")))
7091    (set (attr "amdfam10_decode")
7092         (cond [(eq_attr "alternative" "0,1")
7093                   (const_string "vector")]
7094               (const_string "direct")))
7095    (set_attr "mode" "HI")])
7096
7097 (define_expand "mulqi3"
7098   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7099                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7100                             (match_operand:QI 2 "register_operand" "")))
7101               (clobber (reg:CC FLAGS_REG))])]
7102   "TARGET_QIMODE_MATH"
7103   "")
7104
7105 ;;On AMDFAM10
7106 ;; MUL reg8     Direct
7107 ;; MUL mem8     Direct
7108
7109 (define_insn "*mulqi3_1"
7110   [(set (match_operand:QI 0 "register_operand" "=a")
7111         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7112                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7113    (clobber (reg:CC FLAGS_REG))]
7114   "TARGET_QIMODE_MATH
7115    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7116   "mul{b}\t%2"
7117   [(set_attr "type" "imul")
7118    (set_attr "length_immediate" "0")
7119    (set (attr "athlon_decode")
7120      (if_then_else (eq_attr "cpu" "athlon")
7121         (const_string "vector")
7122         (const_string "direct")))
7123    (set_attr "amdfam10_decode" "direct")        
7124    (set_attr "mode" "QI")])
7125
7126 (define_expand "umulqihi3"
7127   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7128                    (mult:HI (zero_extend:HI
7129                               (match_operand:QI 1 "nonimmediate_operand" ""))
7130                             (zero_extend:HI
7131                               (match_operand:QI 2 "register_operand" ""))))
7132               (clobber (reg:CC FLAGS_REG))])]
7133   "TARGET_QIMODE_MATH"
7134   "")
7135
7136 (define_insn "*umulqihi3_1"
7137   [(set (match_operand:HI 0 "register_operand" "=a")
7138         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7139                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7140    (clobber (reg:CC FLAGS_REG))]
7141   "TARGET_QIMODE_MATH
7142    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7143   "mul{b}\t%2"
7144   [(set_attr "type" "imul")
7145    (set_attr "length_immediate" "0")
7146    (set (attr "athlon_decode")
7147      (if_then_else (eq_attr "cpu" "athlon")
7148         (const_string "vector")
7149         (const_string "direct")))
7150    (set_attr "amdfam10_decode" "direct")        
7151    (set_attr "mode" "QI")])
7152
7153 (define_expand "mulqihi3"
7154   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7155                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7156                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7157               (clobber (reg:CC FLAGS_REG))])]
7158   "TARGET_QIMODE_MATH"
7159   "")
7160
7161 (define_insn "*mulqihi3_insn"
7162   [(set (match_operand:HI 0 "register_operand" "=a")
7163         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7164                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7165    (clobber (reg:CC FLAGS_REG))]
7166   "TARGET_QIMODE_MATH
7167    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7168   "imul{b}\t%2"
7169   [(set_attr "type" "imul")
7170    (set_attr "length_immediate" "0")
7171    (set (attr "athlon_decode")
7172      (if_then_else (eq_attr "cpu" "athlon")
7173         (const_string "vector")
7174         (const_string "direct")))
7175    (set_attr "amdfam10_decode" "direct")        
7176    (set_attr "mode" "QI")])
7177
7178 (define_expand "umulditi3"
7179   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7180                    (mult:TI (zero_extend:TI
7181                               (match_operand:DI 1 "nonimmediate_operand" ""))
7182                             (zero_extend:TI
7183                               (match_operand:DI 2 "register_operand" ""))))
7184               (clobber (reg:CC FLAGS_REG))])]
7185   "TARGET_64BIT"
7186   "")
7187
7188 (define_insn "*umulditi3_insn"
7189   [(set (match_operand:TI 0 "register_operand" "=A")
7190         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7191                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7192    (clobber (reg:CC FLAGS_REG))]
7193   "TARGET_64BIT
7194    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7195   "mul{q}\t%2"
7196   [(set_attr "type" "imul")
7197    (set_attr "length_immediate" "0")
7198    (set (attr "athlon_decode")
7199      (if_then_else (eq_attr "cpu" "athlon")
7200         (const_string "vector")
7201         (const_string "double")))
7202    (set_attr "amdfam10_decode" "double")        
7203    (set_attr "mode" "DI")])
7204
7205 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7206 (define_expand "umulsidi3"
7207   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7208                    (mult:DI (zero_extend:DI
7209                               (match_operand:SI 1 "nonimmediate_operand" ""))
7210                             (zero_extend:DI
7211                               (match_operand:SI 2 "register_operand" ""))))
7212               (clobber (reg:CC FLAGS_REG))])]
7213   "!TARGET_64BIT"
7214   "")
7215
7216 (define_insn "*umulsidi3_insn"
7217   [(set (match_operand:DI 0 "register_operand" "=A")
7218         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7219                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7220    (clobber (reg:CC FLAGS_REG))]
7221   "!TARGET_64BIT
7222    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7223   "mul{l}\t%2"
7224   [(set_attr "type" "imul")
7225    (set_attr "length_immediate" "0")
7226    (set (attr "athlon_decode")
7227      (if_then_else (eq_attr "cpu" "athlon")
7228         (const_string "vector")
7229         (const_string "double")))
7230    (set_attr "amdfam10_decode" "double")        
7231    (set_attr "mode" "SI")])
7232
7233 (define_expand "mulditi3"
7234   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7235                    (mult:TI (sign_extend:TI
7236                               (match_operand:DI 1 "nonimmediate_operand" ""))
7237                             (sign_extend:TI
7238                               (match_operand:DI 2 "register_operand" ""))))
7239               (clobber (reg:CC FLAGS_REG))])]
7240   "TARGET_64BIT"
7241   "")
7242
7243 (define_insn "*mulditi3_insn"
7244   [(set (match_operand:TI 0 "register_operand" "=A")
7245         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7246                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7247    (clobber (reg:CC FLAGS_REG))]
7248   "TARGET_64BIT
7249    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7250   "imul{q}\t%2"
7251   [(set_attr "type" "imul")
7252    (set_attr "length_immediate" "0")
7253    (set (attr "athlon_decode")
7254      (if_then_else (eq_attr "cpu" "athlon")
7255         (const_string "vector")
7256         (const_string "double")))
7257    (set_attr "amdfam10_decode" "double")
7258    (set_attr "mode" "DI")])
7259
7260 (define_expand "mulsidi3"
7261   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7262                    (mult:DI (sign_extend:DI
7263                               (match_operand:SI 1 "nonimmediate_operand" ""))
7264                             (sign_extend:DI
7265                               (match_operand:SI 2 "register_operand" ""))))
7266               (clobber (reg:CC FLAGS_REG))])]
7267   "!TARGET_64BIT"
7268   "")
7269
7270 (define_insn "*mulsidi3_insn"
7271   [(set (match_operand:DI 0 "register_operand" "=A")
7272         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7273                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7274    (clobber (reg:CC FLAGS_REG))]
7275   "!TARGET_64BIT
7276    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7277   "imul{l}\t%2"
7278   [(set_attr "type" "imul")
7279    (set_attr "length_immediate" "0")
7280    (set (attr "athlon_decode")
7281      (if_then_else (eq_attr "cpu" "athlon")
7282         (const_string "vector")
7283         (const_string "double")))
7284    (set_attr "amdfam10_decode" "double")        
7285    (set_attr "mode" "SI")])
7286
7287 (define_expand "umuldi3_highpart"
7288   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7289                    (truncate:DI
7290                      (lshiftrt:TI
7291                        (mult:TI (zero_extend:TI
7292                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7293                                 (zero_extend:TI
7294                                   (match_operand:DI 2 "register_operand" "")))
7295                        (const_int 64))))
7296               (clobber (match_scratch:DI 3 ""))
7297               (clobber (reg:CC FLAGS_REG))])]
7298   "TARGET_64BIT"
7299   "")
7300
7301 (define_insn "*umuldi3_highpart_rex64"
7302   [(set (match_operand:DI 0 "register_operand" "=d")
7303         (truncate:DI
7304           (lshiftrt:TI
7305             (mult:TI (zero_extend:TI
7306                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7307                      (zero_extend:TI
7308                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7309             (const_int 64))))
7310    (clobber (match_scratch:DI 3 "=1"))
7311    (clobber (reg:CC FLAGS_REG))]
7312   "TARGET_64BIT
7313    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7314   "mul{q}\t%2"
7315   [(set_attr "type" "imul")
7316    (set_attr "length_immediate" "0")
7317    (set (attr "athlon_decode")
7318      (if_then_else (eq_attr "cpu" "athlon")
7319         (const_string "vector")
7320         (const_string "double")))
7321    (set_attr "amdfam10_decode" "double")        
7322    (set_attr "mode" "DI")])
7323
7324 (define_expand "umulsi3_highpart"
7325   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7326                    (truncate:SI
7327                      (lshiftrt:DI
7328                        (mult:DI (zero_extend:DI
7329                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7330                                 (zero_extend:DI
7331                                   (match_operand:SI 2 "register_operand" "")))
7332                        (const_int 32))))
7333               (clobber (match_scratch:SI 3 ""))
7334               (clobber (reg:CC FLAGS_REG))])]
7335   ""
7336   "")
7337
7338 (define_insn "*umulsi3_highpart_insn"
7339   [(set (match_operand:SI 0 "register_operand" "=d")
7340         (truncate:SI
7341           (lshiftrt:DI
7342             (mult:DI (zero_extend:DI
7343                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7344                      (zero_extend:DI
7345                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7346             (const_int 32))))
7347    (clobber (match_scratch:SI 3 "=1"))
7348    (clobber (reg:CC FLAGS_REG))]
7349   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7350   "mul{l}\t%2"
7351   [(set_attr "type" "imul")
7352    (set_attr "length_immediate" "0")
7353    (set (attr "athlon_decode")
7354      (if_then_else (eq_attr "cpu" "athlon")
7355         (const_string "vector")
7356         (const_string "double")))
7357    (set_attr "amdfam10_decode" "double")
7358    (set_attr "mode" "SI")])
7359
7360 (define_insn "*umulsi3_highpart_zext"
7361   [(set (match_operand:DI 0 "register_operand" "=d")
7362         (zero_extend:DI (truncate:SI
7363           (lshiftrt:DI
7364             (mult:DI (zero_extend:DI
7365                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7366                      (zero_extend:DI
7367                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7368             (const_int 32)))))
7369    (clobber (match_scratch:SI 3 "=1"))
7370    (clobber (reg:CC FLAGS_REG))]
7371   "TARGET_64BIT
7372    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7373   "mul{l}\t%2"
7374   [(set_attr "type" "imul")
7375    (set_attr "length_immediate" "0")
7376    (set (attr "athlon_decode")
7377      (if_then_else (eq_attr "cpu" "athlon")
7378         (const_string "vector")
7379         (const_string "double")))
7380    (set_attr "amdfam10_decode" "double")
7381    (set_attr "mode" "SI")])
7382
7383 (define_expand "smuldi3_highpart"
7384   [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7385                    (truncate:DI
7386                      (lshiftrt:TI
7387                        (mult:TI (sign_extend:TI
7388                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7389                                 (sign_extend:TI
7390                                   (match_operand:DI 2 "register_operand" "")))
7391                        (const_int 64))))
7392               (clobber (match_scratch:DI 3 ""))
7393               (clobber (reg:CC FLAGS_REG))])]
7394   "TARGET_64BIT"
7395   "")
7396
7397 (define_insn "*smuldi3_highpart_rex64"
7398   [(set (match_operand:DI 0 "register_operand" "=d")
7399         (truncate:DI
7400           (lshiftrt:TI
7401             (mult:TI (sign_extend:TI
7402                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7403                      (sign_extend:TI
7404                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7405             (const_int 64))))
7406    (clobber (match_scratch:DI 3 "=1"))
7407    (clobber (reg:CC FLAGS_REG))]
7408   "TARGET_64BIT
7409    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7410   "imul{q}\t%2"
7411   [(set_attr "type" "imul")
7412    (set (attr "athlon_decode")
7413      (if_then_else (eq_attr "cpu" "athlon")
7414         (const_string "vector")
7415         (const_string "double")))
7416    (set_attr "amdfam10_decode" "double")
7417    (set_attr "mode" "DI")])
7418
7419 (define_expand "smulsi3_highpart"
7420   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7421                    (truncate:SI
7422                      (lshiftrt:DI
7423                        (mult:DI (sign_extend:DI
7424                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7425                                 (sign_extend:DI
7426                                   (match_operand:SI 2 "register_operand" "")))
7427                        (const_int 32))))
7428               (clobber (match_scratch:SI 3 ""))
7429               (clobber (reg:CC FLAGS_REG))])]
7430   ""
7431   "")
7432
7433 (define_insn "*smulsi3_highpart_insn"
7434   [(set (match_operand:SI 0 "register_operand" "=d")
7435         (truncate:SI
7436           (lshiftrt:DI
7437             (mult:DI (sign_extend:DI
7438                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7439                      (sign_extend:DI
7440                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7441             (const_int 32))))
7442    (clobber (match_scratch:SI 3 "=1"))
7443    (clobber (reg:CC FLAGS_REG))]
7444   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7445   "imul{l}\t%2"
7446   [(set_attr "type" "imul")
7447    (set (attr "athlon_decode")
7448      (if_then_else (eq_attr "cpu" "athlon")
7449         (const_string "vector")
7450         (const_string "double")))
7451    (set_attr "amdfam10_decode" "double")
7452    (set_attr "mode" "SI")])
7453
7454 (define_insn "*smulsi3_highpart_zext"
7455   [(set (match_operand:DI 0 "register_operand" "=d")
7456         (zero_extend:DI (truncate:SI
7457           (lshiftrt:DI
7458             (mult:DI (sign_extend:DI
7459                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7460                      (sign_extend:DI
7461                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7462             (const_int 32)))))
7463    (clobber (match_scratch:SI 3 "=1"))
7464    (clobber (reg:CC FLAGS_REG))]
7465   "TARGET_64BIT
7466    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7467   "imul{l}\t%2"
7468   [(set_attr "type" "imul")
7469    (set (attr "athlon_decode")
7470      (if_then_else (eq_attr "cpu" "athlon")
7471         (const_string "vector")
7472         (const_string "double")))
7473    (set_attr "amdfam10_decode" "double")
7474    (set_attr "mode" "SI")])
7475
7476 ;; The patterns that match these are at the end of this file.
7477
7478 (define_expand "mulxf3"
7479   [(set (match_operand:XF 0 "register_operand" "")
7480         (mult:XF (match_operand:XF 1 "register_operand" "")
7481                  (match_operand:XF 2 "register_operand" "")))]
7482   "TARGET_80387"
7483   "")
7484
7485 (define_expand "muldf3"
7486   [(set (match_operand:DF 0 "register_operand" "")
7487         (mult:DF (match_operand:DF 1 "register_operand" "")
7488                  (match_operand:DF 2 "nonimmediate_operand" "")))]
7489   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7490   "")
7491
7492 (define_expand "mulsf3"
7493   [(set (match_operand:SF 0 "register_operand" "")
7494         (mult:SF (match_operand:SF 1 "register_operand" "")
7495                  (match_operand:SF 2 "nonimmediate_operand" "")))]
7496   "TARGET_80387 || TARGET_SSE_MATH"
7497   "")
7498 \f
7499 ;; Divide instructions
7500
7501 (define_insn "divqi3"
7502   [(set (match_operand:QI 0 "register_operand" "=a")
7503         (div:QI (match_operand:HI 1 "register_operand" "0")
7504                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7505    (clobber (reg:CC FLAGS_REG))]
7506   "TARGET_QIMODE_MATH"
7507   "idiv{b}\t%2"
7508   [(set_attr "type" "idiv")
7509    (set_attr "mode" "QI")])
7510
7511 (define_insn "udivqi3"
7512   [(set (match_operand:QI 0 "register_operand" "=a")
7513         (udiv:QI (match_operand:HI 1 "register_operand" "0")
7514                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7515    (clobber (reg:CC FLAGS_REG))]
7516   "TARGET_QIMODE_MATH"
7517   "div{b}\t%2"
7518   [(set_attr "type" "idiv")
7519    (set_attr "mode" "QI")])
7520
7521 ;; The patterns that match these are at the end of this file.
7522
7523 (define_expand "divxf3"
7524   [(set (match_operand:XF 0 "register_operand" "")
7525         (div:XF (match_operand:XF 1 "register_operand" "")
7526                 (match_operand:XF 2 "register_operand" "")))]
7527   "TARGET_80387"
7528   "")
7529
7530 (define_expand "divdf3"
7531   [(set (match_operand:DF 0 "register_operand" "")
7532         (div:DF (match_operand:DF 1 "register_operand" "")
7533                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7534    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7535    "")
7536
7537 (define_expand "divsf3"
7538   [(set (match_operand:SF 0 "register_operand" "")
7539         (div:SF (match_operand:SF 1 "register_operand" "")
7540                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7541   "TARGET_80387 || TARGET_SSE_MATH"
7542   "")
7543 \f
7544 ;; Remainder instructions.
7545
7546 (define_expand "divmoddi4"
7547   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7548                    (div:DI (match_operand:DI 1 "register_operand" "")
7549                            (match_operand:DI 2 "nonimmediate_operand" "")))
7550               (set (match_operand:DI 3 "register_operand" "")
7551                    (mod:DI (match_dup 1) (match_dup 2)))
7552               (clobber (reg:CC FLAGS_REG))])]
7553   "TARGET_64BIT"
7554   "")
7555
7556 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7557 ;; Penalize eax case slightly because it results in worse scheduling
7558 ;; of code.
7559 (define_insn "*divmoddi4_nocltd_rex64"
7560   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7561         (div:DI (match_operand:DI 2 "register_operand" "1,0")
7562                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7563    (set (match_operand:DI 1 "register_operand" "=&d,&d")
7564         (mod:DI (match_dup 2) (match_dup 3)))
7565    (clobber (reg:CC FLAGS_REG))]
7566   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7567   "#"
7568   [(set_attr "type" "multi")])
7569
7570 (define_insn "*divmoddi4_cltd_rex64"
7571   [(set (match_operand:DI 0 "register_operand" "=a")
7572         (div:DI (match_operand:DI 2 "register_operand" "a")
7573                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7574    (set (match_operand:DI 1 "register_operand" "=&d")
7575         (mod:DI (match_dup 2) (match_dup 3)))
7576    (clobber (reg:CC FLAGS_REG))]
7577   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7578   "#"
7579   [(set_attr "type" "multi")])
7580
7581 (define_insn "*divmoddi_noext_rex64"
7582   [(set (match_operand:DI 0 "register_operand" "=a")
7583         (div:DI (match_operand:DI 1 "register_operand" "0")
7584                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7585    (set (match_operand:DI 3 "register_operand" "=d")
7586         (mod:DI (match_dup 1) (match_dup 2)))
7587    (use (match_operand:DI 4 "register_operand" "3"))
7588    (clobber (reg:CC FLAGS_REG))]
7589   "TARGET_64BIT"
7590   "idiv{q}\t%2"
7591   [(set_attr "type" "idiv")
7592    (set_attr "mode" "DI")])
7593
7594 (define_split
7595   [(set (match_operand:DI 0 "register_operand" "")
7596         (div:DI (match_operand:DI 1 "register_operand" "")
7597                 (match_operand:DI 2 "nonimmediate_operand" "")))
7598    (set (match_operand:DI 3 "register_operand" "")
7599         (mod:DI (match_dup 1) (match_dup 2)))
7600    (clobber (reg:CC FLAGS_REG))]
7601   "TARGET_64BIT && reload_completed"
7602   [(parallel [(set (match_dup 3)
7603                    (ashiftrt:DI (match_dup 4) (const_int 63)))
7604               (clobber (reg:CC FLAGS_REG))])
7605    (parallel [(set (match_dup 0)
7606                    (div:DI (reg:DI 0) (match_dup 2)))
7607               (set (match_dup 3)
7608                    (mod:DI (reg:DI 0) (match_dup 2)))
7609               (use (match_dup 3))
7610               (clobber (reg:CC FLAGS_REG))])]
7611 {
7612   /* Avoid use of cltd in favor of a mov+shift.  */
7613   if (!TARGET_USE_CLTD && !optimize_size)
7614     {
7615       if (true_regnum (operands[1]))
7616         emit_move_insn (operands[0], operands[1]);
7617       else
7618         emit_move_insn (operands[3], operands[1]);
7619       operands[4] = operands[3];
7620     }
7621   else
7622     {
7623       gcc_assert (!true_regnum (operands[1]));
7624       operands[4] = operands[1];
7625     }
7626 })
7627
7628
7629 (define_expand "divmodsi4"
7630   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7631                    (div:SI (match_operand:SI 1 "register_operand" "")
7632                            (match_operand:SI 2 "nonimmediate_operand" "")))
7633               (set (match_operand:SI 3 "register_operand" "")
7634                    (mod:SI (match_dup 1) (match_dup 2)))
7635               (clobber (reg:CC FLAGS_REG))])]
7636   ""
7637   "")
7638
7639 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7640 ;; Penalize eax case slightly because it results in worse scheduling
7641 ;; of code.
7642 (define_insn "*divmodsi4_nocltd"
7643   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7644         (div:SI (match_operand:SI 2 "register_operand" "1,0")
7645                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7646    (set (match_operand:SI 1 "register_operand" "=&d,&d")
7647         (mod:SI (match_dup 2) (match_dup 3)))
7648    (clobber (reg:CC FLAGS_REG))]
7649   "!optimize_size && !TARGET_USE_CLTD"
7650   "#"
7651   [(set_attr "type" "multi")])
7652
7653 (define_insn "*divmodsi4_cltd"
7654   [(set (match_operand:SI 0 "register_operand" "=a")
7655         (div:SI (match_operand:SI 2 "register_operand" "a")
7656                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7657    (set (match_operand:SI 1 "register_operand" "=&d")
7658         (mod:SI (match_dup 2) (match_dup 3)))
7659    (clobber (reg:CC FLAGS_REG))]
7660   "optimize_size || TARGET_USE_CLTD"
7661   "#"
7662   [(set_attr "type" "multi")])
7663
7664 (define_insn "*divmodsi_noext"
7665   [(set (match_operand:SI 0 "register_operand" "=a")
7666         (div:SI (match_operand:SI 1 "register_operand" "0")
7667                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7668    (set (match_operand:SI 3 "register_operand" "=d")
7669         (mod:SI (match_dup 1) (match_dup 2)))
7670    (use (match_operand:SI 4 "register_operand" "3"))
7671    (clobber (reg:CC FLAGS_REG))]
7672   ""
7673   "idiv{l}\t%2"
7674   [(set_attr "type" "idiv")
7675    (set_attr "mode" "SI")])
7676
7677 (define_split
7678   [(set (match_operand:SI 0 "register_operand" "")
7679         (div:SI (match_operand:SI 1 "register_operand" "")
7680                 (match_operand:SI 2 "nonimmediate_operand" "")))
7681    (set (match_operand:SI 3 "register_operand" "")
7682         (mod:SI (match_dup 1) (match_dup 2)))
7683    (clobber (reg:CC FLAGS_REG))]
7684   "reload_completed"
7685   [(parallel [(set (match_dup 3)
7686                    (ashiftrt:SI (match_dup 4) (const_int 31)))
7687               (clobber (reg:CC FLAGS_REG))])
7688    (parallel [(set (match_dup 0)
7689                    (div:SI (reg:SI 0) (match_dup 2)))
7690               (set (match_dup 3)
7691                    (mod:SI (reg:SI 0) (match_dup 2)))
7692               (use (match_dup 3))
7693               (clobber (reg:CC FLAGS_REG))])]
7694 {
7695   /* Avoid use of cltd in favor of a mov+shift.  */
7696   if (!TARGET_USE_CLTD && !optimize_size)
7697     {
7698       if (true_regnum (operands[1]))
7699         emit_move_insn (operands[0], operands[1]);
7700       else
7701         emit_move_insn (operands[3], operands[1]);
7702       operands[4] = operands[3];
7703     }
7704   else
7705     {
7706       gcc_assert (!true_regnum (operands[1]));
7707       operands[4] = operands[1];
7708     }
7709 })
7710 ;; %%% Split me.
7711 (define_insn "divmodhi4"
7712   [(set (match_operand:HI 0 "register_operand" "=a")
7713         (div:HI (match_operand:HI 1 "register_operand" "0")
7714                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7715    (set (match_operand:HI 3 "register_operand" "=&d")
7716         (mod:HI (match_dup 1) (match_dup 2)))
7717    (clobber (reg:CC FLAGS_REG))]
7718   "TARGET_HIMODE_MATH"
7719   "cwtd\;idiv{w}\t%2"
7720   [(set_attr "type" "multi")
7721    (set_attr "length_immediate" "0")
7722    (set_attr "mode" "SI")])
7723
7724 (define_insn "udivmoddi4"
7725   [(set (match_operand:DI 0 "register_operand" "=a")
7726         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7727                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7728    (set (match_operand:DI 3 "register_operand" "=&d")
7729         (umod:DI (match_dup 1) (match_dup 2)))
7730    (clobber (reg:CC FLAGS_REG))]
7731   "TARGET_64BIT"
7732   "xor{q}\t%3, %3\;div{q}\t%2"
7733   [(set_attr "type" "multi")
7734    (set_attr "length_immediate" "0")
7735    (set_attr "mode" "DI")])
7736
7737 (define_insn "*udivmoddi4_noext"
7738   [(set (match_operand:DI 0 "register_operand" "=a")
7739         (udiv:DI (match_operand:DI 1 "register_operand" "0")
7740                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
7741    (set (match_operand:DI 3 "register_operand" "=d")
7742         (umod:DI (match_dup 1) (match_dup 2)))
7743    (use (match_dup 3))
7744    (clobber (reg:CC FLAGS_REG))]
7745   "TARGET_64BIT"
7746   "div{q}\t%2"
7747   [(set_attr "type" "idiv")
7748    (set_attr "mode" "DI")])
7749
7750 (define_split
7751   [(set (match_operand:DI 0 "register_operand" "")
7752         (udiv:DI (match_operand:DI 1 "register_operand" "")
7753                  (match_operand:DI 2 "nonimmediate_operand" "")))
7754    (set (match_operand:DI 3 "register_operand" "")
7755         (umod:DI (match_dup 1) (match_dup 2)))
7756    (clobber (reg:CC FLAGS_REG))]
7757   "TARGET_64BIT && reload_completed"
7758   [(set (match_dup 3) (const_int 0))
7759    (parallel [(set (match_dup 0)
7760                    (udiv:DI (match_dup 1) (match_dup 2)))
7761               (set (match_dup 3)
7762                    (umod:DI (match_dup 1) (match_dup 2)))
7763               (use (match_dup 3))
7764               (clobber (reg:CC FLAGS_REG))])]
7765   "")
7766
7767 (define_insn "udivmodsi4"
7768   [(set (match_operand:SI 0 "register_operand" "=a")
7769         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7770                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7771    (set (match_operand:SI 3 "register_operand" "=&d")
7772         (umod:SI (match_dup 1) (match_dup 2)))
7773    (clobber (reg:CC FLAGS_REG))]
7774   ""
7775   "xor{l}\t%3, %3\;div{l}\t%2"
7776   [(set_attr "type" "multi")
7777    (set_attr "length_immediate" "0")
7778    (set_attr "mode" "SI")])
7779
7780 (define_insn "*udivmodsi4_noext"
7781   [(set (match_operand:SI 0 "register_operand" "=a")
7782         (udiv:SI (match_operand:SI 1 "register_operand" "0")
7783                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
7784    (set (match_operand:SI 3 "register_operand" "=d")
7785         (umod:SI (match_dup 1) (match_dup 2)))
7786    (use (match_dup 3))
7787    (clobber (reg:CC FLAGS_REG))]
7788   ""
7789   "div{l}\t%2"
7790   [(set_attr "type" "idiv")
7791    (set_attr "mode" "SI")])
7792
7793 (define_split
7794   [(set (match_operand:SI 0 "register_operand" "")
7795         (udiv:SI (match_operand:SI 1 "register_operand" "")
7796                  (match_operand:SI 2 "nonimmediate_operand" "")))
7797    (set (match_operand:SI 3 "register_operand" "")
7798         (umod:SI (match_dup 1) (match_dup 2)))
7799    (clobber (reg:CC FLAGS_REG))]
7800   "reload_completed"
7801   [(set (match_dup 3) (const_int 0))
7802    (parallel [(set (match_dup 0)
7803                    (udiv:SI (match_dup 1) (match_dup 2)))
7804               (set (match_dup 3)
7805                    (umod:SI (match_dup 1) (match_dup 2)))
7806               (use (match_dup 3))
7807               (clobber (reg:CC FLAGS_REG))])]
7808   "")
7809
7810 (define_expand "udivmodhi4"
7811   [(set (match_dup 4) (const_int 0))
7812    (parallel [(set (match_operand:HI 0 "register_operand" "")
7813                    (udiv:HI (match_operand:HI 1 "register_operand" "")
7814                             (match_operand:HI 2 "nonimmediate_operand" "")))
7815               (set (match_operand:HI 3 "register_operand" "")
7816                    (umod:HI (match_dup 1) (match_dup 2)))
7817               (use (match_dup 4))
7818               (clobber (reg:CC FLAGS_REG))])]
7819   "TARGET_HIMODE_MATH"
7820   "operands[4] = gen_reg_rtx (HImode);")
7821
7822 (define_insn "*udivmodhi_noext"
7823   [(set (match_operand:HI 0 "register_operand" "=a")
7824         (udiv:HI (match_operand:HI 1 "register_operand" "0")
7825                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
7826    (set (match_operand:HI 3 "register_operand" "=d")
7827         (umod:HI (match_dup 1) (match_dup 2)))
7828    (use (match_operand:HI 4 "register_operand" "3"))
7829    (clobber (reg:CC FLAGS_REG))]
7830   ""
7831   "div{w}\t%2"
7832   [(set_attr "type" "idiv")
7833    (set_attr "mode" "HI")])
7834
7835 ;; We cannot use div/idiv for double division, because it causes
7836 ;; "division by zero" on the overflow and that's not what we expect
7837 ;; from truncate.  Because true (non truncating) double division is
7838 ;; never generated, we can't create this insn anyway.
7839 ;
7840 ;(define_insn ""
7841 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7842 ;       (truncate:SI
7843 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7844 ;                  (zero_extend:DI
7845 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7846 ;   (set (match_operand:SI 3 "register_operand" "=d")
7847 ;       (truncate:SI
7848 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7849 ;   (clobber (reg:CC FLAGS_REG))]
7850 ;  ""
7851 ;  "div{l}\t{%2, %0|%0, %2}"
7852 ;  [(set_attr "type" "idiv")])
7853 \f
7854 ;;- Logical AND instructions
7855
7856 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7857 ;; Note that this excludes ah.
7858
7859 (define_insn "*testdi_1_rex64"
7860   [(set (reg FLAGS_REG)
7861         (compare
7862           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7863                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7864           (const_int 0)))]
7865   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7866    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7867   "@
7868    test{l}\t{%k1, %k0|%k0, %k1}
7869    test{l}\t{%k1, %k0|%k0, %k1}
7870    test{q}\t{%1, %0|%0, %1}
7871    test{q}\t{%1, %0|%0, %1}
7872    test{q}\t{%1, %0|%0, %1}"
7873   [(set_attr "type" "test")
7874    (set_attr "modrm" "0,1,0,1,1")
7875    (set_attr "mode" "SI,SI,DI,DI,DI")
7876    (set_attr "pent_pair" "uv,np,uv,np,uv")])
7877
7878 (define_insn "testsi_1"
7879   [(set (reg FLAGS_REG)
7880         (compare
7881           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7882                   (match_operand:SI 1 "general_operand" "in,in,rin"))
7883           (const_int 0)))]
7884   "ix86_match_ccmode (insn, CCNOmode)
7885    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7886   "test{l}\t{%1, %0|%0, %1}"
7887   [(set_attr "type" "test")
7888    (set_attr "modrm" "0,1,1")
7889    (set_attr "mode" "SI")
7890    (set_attr "pent_pair" "uv,np,uv")])
7891
7892 (define_expand "testsi_ccno_1"
7893   [(set (reg:CCNO FLAGS_REG)
7894         (compare:CCNO
7895           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7896                   (match_operand:SI 1 "nonmemory_operand" ""))
7897           (const_int 0)))]
7898   ""
7899   "")
7900
7901 (define_insn "*testhi_1"
7902   [(set (reg FLAGS_REG)
7903         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7904                          (match_operand:HI 1 "general_operand" "n,n,rn"))
7905                  (const_int 0)))]
7906   "ix86_match_ccmode (insn, CCNOmode)
7907    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7908   "test{w}\t{%1, %0|%0, %1}"
7909   [(set_attr "type" "test")
7910    (set_attr "modrm" "0,1,1")
7911    (set_attr "mode" "HI")
7912    (set_attr "pent_pair" "uv,np,uv")])
7913
7914 (define_expand "testqi_ccz_1"
7915   [(set (reg:CCZ FLAGS_REG)
7916         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7917                              (match_operand:QI 1 "nonmemory_operand" ""))
7918                  (const_int 0)))]
7919   ""
7920   "")
7921
7922 (define_insn "*testqi_1_maybe_si"
7923   [(set (reg FLAGS_REG)
7924         (compare
7925           (and:QI
7926             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7927             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7928           (const_int 0)))]
7929    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7930     && ix86_match_ccmode (insn,
7931                          CONST_INT_P (operands[1])
7932                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7933 {
7934   if (which_alternative == 3)
7935     {
7936       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7937         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7938       return "test{l}\t{%1, %k0|%k0, %1}";
7939     }
7940   return "test{b}\t{%1, %0|%0, %1}";
7941 }
7942   [(set_attr "type" "test")
7943    (set_attr "modrm" "0,1,1,1")
7944    (set_attr "mode" "QI,QI,QI,SI")
7945    (set_attr "pent_pair" "uv,np,uv,np")])
7946
7947 (define_insn "*testqi_1"
7948   [(set (reg FLAGS_REG)
7949         (compare
7950           (and:QI
7951             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7952             (match_operand:QI 1 "general_operand" "n,n,qn"))
7953           (const_int 0)))]
7954   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7955    && ix86_match_ccmode (insn, CCNOmode)"
7956   "test{b}\t{%1, %0|%0, %1}"
7957   [(set_attr "type" "test")
7958    (set_attr "modrm" "0,1,1")
7959    (set_attr "mode" "QI")
7960    (set_attr "pent_pair" "uv,np,uv")])
7961
7962 (define_expand "testqi_ext_ccno_0"
7963   [(set (reg:CCNO FLAGS_REG)
7964         (compare:CCNO
7965           (and:SI
7966             (zero_extract:SI
7967               (match_operand 0 "ext_register_operand" "")
7968               (const_int 8)
7969               (const_int 8))
7970             (match_operand 1 "const_int_operand" ""))
7971           (const_int 0)))]
7972   ""
7973   "")
7974
7975 (define_insn "*testqi_ext_0"
7976   [(set (reg FLAGS_REG)
7977         (compare
7978           (and:SI
7979             (zero_extract:SI
7980               (match_operand 0 "ext_register_operand" "Q")
7981               (const_int 8)
7982               (const_int 8))
7983             (match_operand 1 "const_int_operand" "n"))
7984           (const_int 0)))]
7985   "ix86_match_ccmode (insn, CCNOmode)"
7986   "test{b}\t{%1, %h0|%h0, %1}"
7987   [(set_attr "type" "test")
7988    (set_attr "mode" "QI")
7989    (set_attr "length_immediate" "1")
7990    (set_attr "pent_pair" "np")])
7991
7992 (define_insn "*testqi_ext_1"
7993   [(set (reg FLAGS_REG)
7994         (compare
7995           (and:SI
7996             (zero_extract:SI
7997               (match_operand 0 "ext_register_operand" "Q")
7998               (const_int 8)
7999               (const_int 8))
8000             (zero_extend:SI
8001               (match_operand:QI 1 "general_operand" "Qm")))
8002           (const_int 0)))]
8003   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8004    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8005   "test{b}\t{%1, %h0|%h0, %1}"
8006   [(set_attr "type" "test")
8007    (set_attr "mode" "QI")])
8008
8009 (define_insn "*testqi_ext_1_rex64"
8010   [(set (reg FLAGS_REG)
8011         (compare
8012           (and:SI
8013             (zero_extract:SI
8014               (match_operand 0 "ext_register_operand" "Q")
8015               (const_int 8)
8016               (const_int 8))
8017             (zero_extend:SI
8018               (match_operand:QI 1 "register_operand" "Q")))
8019           (const_int 0)))]
8020   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8021   "test{b}\t{%1, %h0|%h0, %1}"
8022   [(set_attr "type" "test")
8023    (set_attr "mode" "QI")])
8024
8025 (define_insn "*testqi_ext_2"
8026   [(set (reg FLAGS_REG)
8027         (compare
8028           (and:SI
8029             (zero_extract:SI
8030               (match_operand 0 "ext_register_operand" "Q")
8031               (const_int 8)
8032               (const_int 8))
8033             (zero_extract:SI
8034               (match_operand 1 "ext_register_operand" "Q")
8035               (const_int 8)
8036               (const_int 8)))
8037           (const_int 0)))]
8038   "ix86_match_ccmode (insn, CCNOmode)"
8039   "test{b}\t{%h1, %h0|%h0, %h1}"
8040   [(set_attr "type" "test")
8041    (set_attr "mode" "QI")])
8042
8043 ;; Combine likes to form bit extractions for some tests.  Humor it.
8044 (define_insn "*testqi_ext_3"
8045   [(set (reg FLAGS_REG)
8046         (compare (zero_extract:SI
8047                    (match_operand 0 "nonimmediate_operand" "rm")
8048                    (match_operand:SI 1 "const_int_operand" "")
8049                    (match_operand:SI 2 "const_int_operand" ""))
8050                  (const_int 0)))]
8051   "ix86_match_ccmode (insn, CCNOmode)
8052    && INTVAL (operands[1]) > 0
8053    && INTVAL (operands[2]) >= 0
8054    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8055    && (GET_MODE (operands[0]) == SImode
8056        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8057        || GET_MODE (operands[0]) == HImode
8058        || GET_MODE (operands[0]) == QImode)"
8059   "#")
8060
8061 (define_insn "*testqi_ext_3_rex64"
8062   [(set (reg FLAGS_REG)
8063         (compare (zero_extract:DI
8064                    (match_operand 0 "nonimmediate_operand" "rm")
8065                    (match_operand:DI 1 "const_int_operand" "")
8066                    (match_operand:DI 2 "const_int_operand" ""))
8067                  (const_int 0)))]
8068   "TARGET_64BIT
8069    && ix86_match_ccmode (insn, CCNOmode)
8070    && INTVAL (operands[1]) > 0
8071    && INTVAL (operands[2]) >= 0
8072    /* Ensure that resulting mask is zero or sign extended operand.  */
8073    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8074        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8075            && INTVAL (operands[1]) > 32))
8076    && (GET_MODE (operands[0]) == SImode
8077        || GET_MODE (operands[0]) == DImode
8078        || GET_MODE (operands[0]) == HImode
8079        || GET_MODE (operands[0]) == QImode)"
8080   "#")
8081
8082 (define_split
8083   [(set (match_operand 0 "flags_reg_operand" "")
8084         (match_operator 1 "compare_operator"
8085           [(zero_extract
8086              (match_operand 2 "nonimmediate_operand" "")
8087              (match_operand 3 "const_int_operand" "")
8088              (match_operand 4 "const_int_operand" ""))
8089            (const_int 0)]))]
8090   "ix86_match_ccmode (insn, CCNOmode)"
8091   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8092 {
8093   rtx val = operands[2];
8094   HOST_WIDE_INT len = INTVAL (operands[3]);
8095   HOST_WIDE_INT pos = INTVAL (operands[4]);
8096   HOST_WIDE_INT mask;
8097   enum machine_mode mode, submode;
8098
8099   mode = GET_MODE (val);
8100   if (MEM_P (val))
8101     {
8102       /* ??? Combine likes to put non-volatile mem extractions in QImode
8103          no matter the size of the test.  So find a mode that works.  */
8104       if (! MEM_VOLATILE_P (val))
8105         {
8106           mode = smallest_mode_for_size (pos + len, MODE_INT);
8107           val = adjust_address (val, mode, 0);
8108         }
8109     }
8110   else if (GET_CODE (val) == SUBREG
8111            && (submode = GET_MODE (SUBREG_REG (val)),
8112                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8113            && pos + len <= GET_MODE_BITSIZE (submode))
8114     {
8115       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8116       mode = submode;
8117       val = SUBREG_REG (val);
8118     }
8119   else if (mode == HImode && pos + len <= 8)
8120     {
8121       /* Small HImode tests can be converted to QImode.  */
8122       mode = QImode;
8123       val = gen_lowpart (QImode, val);
8124     }
8125
8126   if (len == HOST_BITS_PER_WIDE_INT)
8127     mask = -1;
8128   else
8129     mask = ((HOST_WIDE_INT)1 << len) - 1;
8130   mask <<= pos;
8131
8132   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8133 })
8134
8135 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8136 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8137 ;; this is relatively important trick.
8138 ;; Do the conversion only post-reload to avoid limiting of the register class
8139 ;; to QI regs.
8140 (define_split
8141   [(set (match_operand 0 "flags_reg_operand" "")
8142         (match_operator 1 "compare_operator"
8143           [(and (match_operand 2 "register_operand" "")
8144                 (match_operand 3 "const_int_operand" ""))
8145            (const_int 0)]))]
8146    "reload_completed
8147     && QI_REG_P (operands[2])
8148     && GET_MODE (operands[2]) != QImode
8149     && ((ix86_match_ccmode (insn, CCZmode)
8150          && !(INTVAL (operands[3]) & ~(255 << 8)))
8151         || (ix86_match_ccmode (insn, CCNOmode)
8152             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8153   [(set (match_dup 0)
8154         (match_op_dup 1
8155           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8156                    (match_dup 3))
8157            (const_int 0)]))]
8158   "operands[2] = gen_lowpart (SImode, operands[2]);
8159    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8160
8161 (define_split
8162   [(set (match_operand 0 "flags_reg_operand" "")
8163         (match_operator 1 "compare_operator"
8164           [(and (match_operand 2 "nonimmediate_operand" "")
8165                 (match_operand 3 "const_int_operand" ""))
8166            (const_int 0)]))]
8167    "reload_completed
8168     && GET_MODE (operands[2]) != QImode
8169     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8170     && ((ix86_match_ccmode (insn, CCZmode)
8171          && !(INTVAL (operands[3]) & ~255))
8172         || (ix86_match_ccmode (insn, CCNOmode)
8173             && !(INTVAL (operands[3]) & ~127)))"
8174   [(set (match_dup 0)
8175         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8176                          (const_int 0)]))]
8177   "operands[2] = gen_lowpart (QImode, operands[2]);
8178    operands[3] = gen_lowpart (QImode, operands[3]);")
8179
8180
8181 ;; %%% This used to optimize known byte-wide and operations to memory,
8182 ;; and sometimes to QImode registers.  If this is considered useful,
8183 ;; it should be done with splitters.
8184
8185 (define_expand "anddi3"
8186   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8187         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8188                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8189    (clobber (reg:CC FLAGS_REG))]
8190   "TARGET_64BIT"
8191   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8192
8193 (define_insn "*anddi_1_rex64"
8194   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8195         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8196                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8197    (clobber (reg:CC FLAGS_REG))]
8198   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8199 {
8200   switch (get_attr_type (insn))
8201     {
8202     case TYPE_IMOVX:
8203       {
8204         enum machine_mode mode;
8205
8206         gcc_assert (CONST_INT_P (operands[2]));
8207         if (INTVAL (operands[2]) == 0xff)
8208           mode = QImode;
8209         else
8210           {
8211             gcc_assert (INTVAL (operands[2]) == 0xffff);
8212             mode = HImode;
8213           }
8214
8215         operands[1] = gen_lowpart (mode, operands[1]);
8216         if (mode == QImode)
8217           return "movz{bq|x}\t{%1,%0|%0, %1}";
8218         else
8219           return "movz{wq|x}\t{%1,%0|%0, %1}";
8220       }
8221
8222     default:
8223       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8224       if (get_attr_mode (insn) == MODE_SI)
8225         return "and{l}\t{%k2, %k0|%k0, %k2}";
8226       else
8227         return "and{q}\t{%2, %0|%0, %2}";
8228     }
8229 }
8230   [(set_attr "type" "alu,alu,alu,imovx")
8231    (set_attr "length_immediate" "*,*,*,0")
8232    (set_attr "mode" "SI,DI,DI,DI")])
8233
8234 (define_insn "*anddi_2"
8235   [(set (reg FLAGS_REG)
8236         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8237                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8238                  (const_int 0)))
8239    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8240         (and:DI (match_dup 1) (match_dup 2)))]
8241   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8242    && ix86_binary_operator_ok (AND, DImode, operands)"
8243   "@
8244    and{l}\t{%k2, %k0|%k0, %k2}
8245    and{q}\t{%2, %0|%0, %2}
8246    and{q}\t{%2, %0|%0, %2}"
8247   [(set_attr "type" "alu")
8248    (set_attr "mode" "SI,DI,DI")])
8249
8250 (define_expand "andsi3"
8251   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8252         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8253                 (match_operand:SI 2 "general_operand" "")))
8254    (clobber (reg:CC FLAGS_REG))]
8255   ""
8256   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8257
8258 (define_insn "*andsi_1"
8259   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8260         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8261                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8262    (clobber (reg:CC FLAGS_REG))]
8263   "ix86_binary_operator_ok (AND, SImode, operands)"
8264 {
8265   switch (get_attr_type (insn))
8266     {
8267     case TYPE_IMOVX:
8268       {
8269         enum machine_mode mode;
8270
8271         gcc_assert (CONST_INT_P (operands[2]));
8272         if (INTVAL (operands[2]) == 0xff)
8273           mode = QImode;
8274         else
8275           {
8276             gcc_assert (INTVAL (operands[2]) == 0xffff);
8277             mode = HImode;
8278           }
8279
8280         operands[1] = gen_lowpart (mode, operands[1]);
8281         if (mode == QImode)
8282           return "movz{bl|x}\t{%1,%0|%0, %1}";
8283         else
8284           return "movz{wl|x}\t{%1,%0|%0, %1}";
8285       }
8286
8287     default:
8288       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8289       return "and{l}\t{%2, %0|%0, %2}";
8290     }
8291 }
8292   [(set_attr "type" "alu,alu,imovx")
8293    (set_attr "length_immediate" "*,*,0")
8294    (set_attr "mode" "SI")])
8295
8296 (define_split
8297   [(set (match_operand 0 "register_operand" "")
8298         (and (match_dup 0)
8299              (const_int -65536)))
8300    (clobber (reg:CC FLAGS_REG))]
8301   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8302   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8303   "operands[1] = gen_lowpart (HImode, operands[0]);")
8304
8305 (define_split
8306   [(set (match_operand 0 "ext_register_operand" "")
8307         (and (match_dup 0)
8308              (const_int -256)))
8309    (clobber (reg:CC FLAGS_REG))]
8310   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8311   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8312   "operands[1] = gen_lowpart (QImode, operands[0]);")
8313
8314 (define_split
8315   [(set (match_operand 0 "ext_register_operand" "")
8316         (and (match_dup 0)
8317              (const_int -65281)))
8318    (clobber (reg:CC FLAGS_REG))]
8319   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8320   [(parallel [(set (zero_extract:SI (match_dup 0)
8321                                     (const_int 8)
8322                                     (const_int 8))
8323                    (xor:SI
8324                      (zero_extract:SI (match_dup 0)
8325                                       (const_int 8)
8326                                       (const_int 8))
8327                      (zero_extract:SI (match_dup 0)
8328                                       (const_int 8)
8329                                       (const_int 8))))
8330               (clobber (reg:CC FLAGS_REG))])]
8331   "operands[0] = gen_lowpart (SImode, operands[0]);")
8332
8333 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8334 (define_insn "*andsi_1_zext"
8335   [(set (match_operand:DI 0 "register_operand" "=r")
8336         (zero_extend:DI
8337           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8338                   (match_operand:SI 2 "general_operand" "rim"))))
8339    (clobber (reg:CC FLAGS_REG))]
8340   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8341   "and{l}\t{%2, %k0|%k0, %2}"
8342   [(set_attr "type" "alu")
8343    (set_attr "mode" "SI")])
8344
8345 (define_insn "*andsi_2"
8346   [(set (reg FLAGS_REG)
8347         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8348                          (match_operand:SI 2 "general_operand" "rim,ri"))
8349                  (const_int 0)))
8350    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8351         (and:SI (match_dup 1) (match_dup 2)))]
8352   "ix86_match_ccmode (insn, CCNOmode)
8353    && ix86_binary_operator_ok (AND, SImode, operands)"
8354   "and{l}\t{%2, %0|%0, %2}"
8355   [(set_attr "type" "alu")
8356    (set_attr "mode" "SI")])
8357
8358 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8359 (define_insn "*andsi_2_zext"
8360   [(set (reg FLAGS_REG)
8361         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8362                          (match_operand:SI 2 "general_operand" "rim"))
8363                  (const_int 0)))
8364    (set (match_operand:DI 0 "register_operand" "=r")
8365         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8366   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8367    && ix86_binary_operator_ok (AND, SImode, operands)"
8368   "and{l}\t{%2, %k0|%k0, %2}"
8369   [(set_attr "type" "alu")
8370    (set_attr "mode" "SI")])
8371
8372 (define_expand "andhi3"
8373   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8374         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8375                 (match_operand:HI 2 "general_operand" "")))
8376    (clobber (reg:CC FLAGS_REG))]
8377   "TARGET_HIMODE_MATH"
8378   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8379
8380 (define_insn "*andhi_1"
8381   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8382         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8383                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8384    (clobber (reg:CC FLAGS_REG))]
8385   "ix86_binary_operator_ok (AND, HImode, operands)"
8386 {
8387   switch (get_attr_type (insn))
8388     {
8389     case TYPE_IMOVX:
8390       gcc_assert (CONST_INT_P (operands[2]));
8391       gcc_assert (INTVAL (operands[2]) == 0xff);
8392       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8393
8394     default:
8395       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8396
8397       return "and{w}\t{%2, %0|%0, %2}";
8398     }
8399 }
8400   [(set_attr "type" "alu,alu,imovx")
8401    (set_attr "length_immediate" "*,*,0")
8402    (set_attr "mode" "HI,HI,SI")])
8403
8404 (define_insn "*andhi_2"
8405   [(set (reg FLAGS_REG)
8406         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8407                          (match_operand:HI 2 "general_operand" "rim,ri"))
8408                  (const_int 0)))
8409    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8410         (and:HI (match_dup 1) (match_dup 2)))]
8411   "ix86_match_ccmode (insn, CCNOmode)
8412    && ix86_binary_operator_ok (AND, HImode, operands)"
8413   "and{w}\t{%2, %0|%0, %2}"
8414   [(set_attr "type" "alu")
8415    (set_attr "mode" "HI")])
8416
8417 (define_expand "andqi3"
8418   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8419         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8420                 (match_operand:QI 2 "general_operand" "")))
8421    (clobber (reg:CC FLAGS_REG))]
8422   "TARGET_QIMODE_MATH"
8423   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8424
8425 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8426 (define_insn "*andqi_1"
8427   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8428         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8429                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8430    (clobber (reg:CC FLAGS_REG))]
8431   "ix86_binary_operator_ok (AND, QImode, operands)"
8432   "@
8433    and{b}\t{%2, %0|%0, %2}
8434    and{b}\t{%2, %0|%0, %2}
8435    and{l}\t{%k2, %k0|%k0, %k2}"
8436   [(set_attr "type" "alu")
8437    (set_attr "mode" "QI,QI,SI")])
8438
8439 (define_insn "*andqi_1_slp"
8440   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8441         (and:QI (match_dup 0)
8442                 (match_operand:QI 1 "general_operand" "qi,qmi")))
8443    (clobber (reg:CC FLAGS_REG))]
8444   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8445    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8446   "and{b}\t{%1, %0|%0, %1}"
8447   [(set_attr "type" "alu1")
8448    (set_attr "mode" "QI")])
8449
8450 (define_insn "*andqi_2_maybe_si"
8451   [(set (reg FLAGS_REG)
8452         (compare (and:QI
8453                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8454                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
8455                  (const_int 0)))
8456    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8457         (and:QI (match_dup 1) (match_dup 2)))]
8458   "ix86_binary_operator_ok (AND, QImode, operands)
8459    && ix86_match_ccmode (insn,
8460                          CONST_INT_P (operands[2])
8461                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8462 {
8463   if (which_alternative == 2)
8464     {
8465       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8466         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8467       return "and{l}\t{%2, %k0|%k0, %2}";
8468     }
8469   return "and{b}\t{%2, %0|%0, %2}";
8470 }
8471   [(set_attr "type" "alu")
8472    (set_attr "mode" "QI,QI,SI")])
8473
8474 (define_insn "*andqi_2"
8475   [(set (reg FLAGS_REG)
8476         (compare (and:QI
8477                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8478                    (match_operand:QI 2 "general_operand" "qim,qi"))
8479                  (const_int 0)))
8480    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8481         (and:QI (match_dup 1) (match_dup 2)))]
8482   "ix86_match_ccmode (insn, CCNOmode)
8483    && ix86_binary_operator_ok (AND, QImode, operands)"
8484   "and{b}\t{%2, %0|%0, %2}"
8485   [(set_attr "type" "alu")
8486    (set_attr "mode" "QI")])
8487
8488 (define_insn "*andqi_2_slp"
8489   [(set (reg FLAGS_REG)
8490         (compare (and:QI
8491                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8492                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8493                  (const_int 0)))
8494    (set (strict_low_part (match_dup 0))
8495         (and:QI (match_dup 0) (match_dup 1)))]
8496   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8497    && ix86_match_ccmode (insn, CCNOmode)
8498    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8499   "and{b}\t{%1, %0|%0, %1}"
8500   [(set_attr "type" "alu1")
8501    (set_attr "mode" "QI")])
8502
8503 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8504 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8505 ;; for a QImode operand, which of course failed.
8506
8507 (define_insn "andqi_ext_0"
8508   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8509                          (const_int 8)
8510                          (const_int 8))
8511         (and:SI
8512           (zero_extract:SI
8513             (match_operand 1 "ext_register_operand" "0")
8514             (const_int 8)
8515             (const_int 8))
8516           (match_operand 2 "const_int_operand" "n")))
8517    (clobber (reg:CC FLAGS_REG))]
8518   ""
8519   "and{b}\t{%2, %h0|%h0, %2}"
8520   [(set_attr "type" "alu")
8521    (set_attr "length_immediate" "1")
8522    (set_attr "mode" "QI")])
8523
8524 ;; Generated by peephole translating test to and.  This shows up
8525 ;; often in fp comparisons.
8526
8527 (define_insn "*andqi_ext_0_cc"
8528   [(set (reg FLAGS_REG)
8529         (compare
8530           (and:SI
8531             (zero_extract:SI
8532               (match_operand 1 "ext_register_operand" "0")
8533               (const_int 8)
8534               (const_int 8))
8535             (match_operand 2 "const_int_operand" "n"))
8536           (const_int 0)))
8537    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8538                          (const_int 8)
8539                          (const_int 8))
8540         (and:SI
8541           (zero_extract:SI
8542             (match_dup 1)
8543             (const_int 8)
8544             (const_int 8))
8545           (match_dup 2)))]
8546   "ix86_match_ccmode (insn, CCNOmode)"
8547   "and{b}\t{%2, %h0|%h0, %2}"
8548   [(set_attr "type" "alu")
8549    (set_attr "length_immediate" "1")
8550    (set_attr "mode" "QI")])
8551
8552 (define_insn "*andqi_ext_1"
8553   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8554                          (const_int 8)
8555                          (const_int 8))
8556         (and:SI
8557           (zero_extract:SI
8558             (match_operand 1 "ext_register_operand" "0")
8559             (const_int 8)
8560             (const_int 8))
8561           (zero_extend:SI
8562             (match_operand:QI 2 "general_operand" "Qm"))))
8563    (clobber (reg:CC FLAGS_REG))]
8564   "!TARGET_64BIT"
8565   "and{b}\t{%2, %h0|%h0, %2}"
8566   [(set_attr "type" "alu")
8567    (set_attr "length_immediate" "0")
8568    (set_attr "mode" "QI")])
8569
8570 (define_insn "*andqi_ext_1_rex64"
8571   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8572                          (const_int 8)
8573                          (const_int 8))
8574         (and:SI
8575           (zero_extract:SI
8576             (match_operand 1 "ext_register_operand" "0")
8577             (const_int 8)
8578             (const_int 8))
8579           (zero_extend:SI
8580             (match_operand 2 "ext_register_operand" "Q"))))
8581    (clobber (reg:CC FLAGS_REG))]
8582   "TARGET_64BIT"
8583   "and{b}\t{%2, %h0|%h0, %2}"
8584   [(set_attr "type" "alu")
8585    (set_attr "length_immediate" "0")
8586    (set_attr "mode" "QI")])
8587
8588 (define_insn "*andqi_ext_2"
8589   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8590                          (const_int 8)
8591                          (const_int 8))
8592         (and:SI
8593           (zero_extract:SI
8594             (match_operand 1 "ext_register_operand" "%0")
8595             (const_int 8)
8596             (const_int 8))
8597           (zero_extract:SI
8598             (match_operand 2 "ext_register_operand" "Q")
8599             (const_int 8)
8600             (const_int 8))))
8601    (clobber (reg:CC FLAGS_REG))]
8602   ""
8603   "and{b}\t{%h2, %h0|%h0, %h2}"
8604   [(set_attr "type" "alu")
8605    (set_attr "length_immediate" "0")
8606    (set_attr "mode" "QI")])
8607
8608 ;; Convert wide AND instructions with immediate operand to shorter QImode
8609 ;; equivalents when possible.
8610 ;; Don't do the splitting with memory operands, since it introduces risk
8611 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8612 ;; for size, but that can (should?) be handled by generic code instead.
8613 (define_split
8614   [(set (match_operand 0 "register_operand" "")
8615         (and (match_operand 1 "register_operand" "")
8616              (match_operand 2 "const_int_operand" "")))
8617    (clobber (reg:CC FLAGS_REG))]
8618    "reload_completed
8619     && QI_REG_P (operands[0])
8620     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8621     && !(~INTVAL (operands[2]) & ~(255 << 8))
8622     && GET_MODE (operands[0]) != QImode"
8623   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8624                    (and:SI (zero_extract:SI (match_dup 1)
8625                                             (const_int 8) (const_int 8))
8626                            (match_dup 2)))
8627               (clobber (reg:CC FLAGS_REG))])]
8628   "operands[0] = gen_lowpart (SImode, operands[0]);
8629    operands[1] = gen_lowpart (SImode, operands[1]);
8630    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8631
8632 ;; Since AND can be encoded with sign extended immediate, this is only
8633 ;; profitable when 7th bit is not set.
8634 (define_split
8635   [(set (match_operand 0 "register_operand" "")
8636         (and (match_operand 1 "general_operand" "")
8637              (match_operand 2 "const_int_operand" "")))
8638    (clobber (reg:CC FLAGS_REG))]
8639    "reload_completed
8640     && ANY_QI_REG_P (operands[0])
8641     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8642     && !(~INTVAL (operands[2]) & ~255)
8643     && !(INTVAL (operands[2]) & 128)
8644     && GET_MODE (operands[0]) != QImode"
8645   [(parallel [(set (strict_low_part (match_dup 0))
8646                    (and:QI (match_dup 1)
8647                            (match_dup 2)))
8648               (clobber (reg:CC FLAGS_REG))])]
8649   "operands[0] = gen_lowpart (QImode, operands[0]);
8650    operands[1] = gen_lowpart (QImode, operands[1]);
8651    operands[2] = gen_lowpart (QImode, operands[2]);")
8652 \f
8653 ;; Logical inclusive OR instructions
8654
8655 ;; %%% This used to optimize known byte-wide and operations to memory.
8656 ;; If this is considered useful, it should be done with splitters.
8657
8658 (define_expand "iordi3"
8659   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8660         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8661                 (match_operand:DI 2 "x86_64_general_operand" "")))
8662    (clobber (reg:CC FLAGS_REG))]
8663   "TARGET_64BIT"
8664   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8665
8666 (define_insn "*iordi_1_rex64"
8667   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8668         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8669                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8670    (clobber (reg:CC FLAGS_REG))]
8671   "TARGET_64BIT
8672    && ix86_binary_operator_ok (IOR, DImode, operands)"
8673   "or{q}\t{%2, %0|%0, %2}"
8674   [(set_attr "type" "alu")
8675    (set_attr "mode" "DI")])
8676
8677 (define_insn "*iordi_2_rex64"
8678   [(set (reg FLAGS_REG)
8679         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8680                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8681                  (const_int 0)))
8682    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8683         (ior:DI (match_dup 1) (match_dup 2)))]
8684   "TARGET_64BIT
8685    && ix86_match_ccmode (insn, CCNOmode)
8686    && ix86_binary_operator_ok (IOR, DImode, operands)"
8687   "or{q}\t{%2, %0|%0, %2}"
8688   [(set_attr "type" "alu")
8689    (set_attr "mode" "DI")])
8690
8691 (define_insn "*iordi_3_rex64"
8692   [(set (reg FLAGS_REG)
8693         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8694                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
8695                  (const_int 0)))
8696    (clobber (match_scratch:DI 0 "=r"))]
8697   "TARGET_64BIT
8698    && ix86_match_ccmode (insn, CCNOmode)
8699    && ix86_binary_operator_ok (IOR, DImode, operands)"
8700   "or{q}\t{%2, %0|%0, %2}"
8701   [(set_attr "type" "alu")
8702    (set_attr "mode" "DI")])
8703
8704
8705 (define_expand "iorsi3"
8706   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8707         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8708                 (match_operand:SI 2 "general_operand" "")))
8709    (clobber (reg:CC FLAGS_REG))]
8710   ""
8711   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8712
8713 (define_insn "*iorsi_1"
8714   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8715         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8716                 (match_operand:SI 2 "general_operand" "ri,rmi")))
8717    (clobber (reg:CC FLAGS_REG))]
8718   "ix86_binary_operator_ok (IOR, SImode, operands)"
8719   "or{l}\t{%2, %0|%0, %2}"
8720   [(set_attr "type" "alu")
8721    (set_attr "mode" "SI")])
8722
8723 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8724 (define_insn "*iorsi_1_zext"
8725   [(set (match_operand:DI 0 "register_operand" "=rm")
8726         (zero_extend:DI
8727           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8728                   (match_operand:SI 2 "general_operand" "rim"))))
8729    (clobber (reg:CC FLAGS_REG))]
8730   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8731   "or{l}\t{%2, %k0|%k0, %2}"
8732   [(set_attr "type" "alu")
8733    (set_attr "mode" "SI")])
8734
8735 (define_insn "*iorsi_1_zext_imm"
8736   [(set (match_operand:DI 0 "register_operand" "=rm")
8737         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8738                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8739    (clobber (reg:CC FLAGS_REG))]
8740   "TARGET_64BIT"
8741   "or{l}\t{%2, %k0|%k0, %2}"
8742   [(set_attr "type" "alu")
8743    (set_attr "mode" "SI")])
8744
8745 (define_insn "*iorsi_2"
8746   [(set (reg FLAGS_REG)
8747         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8748                          (match_operand:SI 2 "general_operand" "rim,ri"))
8749                  (const_int 0)))
8750    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8751         (ior:SI (match_dup 1) (match_dup 2)))]
8752   "ix86_match_ccmode (insn, CCNOmode)
8753    && ix86_binary_operator_ok (IOR, SImode, operands)"
8754   "or{l}\t{%2, %0|%0, %2}"
8755   [(set_attr "type" "alu")
8756    (set_attr "mode" "SI")])
8757
8758 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8759 ;; ??? Special case for immediate operand is missing - it is tricky.
8760 (define_insn "*iorsi_2_zext"
8761   [(set (reg FLAGS_REG)
8762         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8763                          (match_operand:SI 2 "general_operand" "rim"))
8764                  (const_int 0)))
8765    (set (match_operand:DI 0 "register_operand" "=r")
8766         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8767   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8768    && ix86_binary_operator_ok (IOR, SImode, operands)"
8769   "or{l}\t{%2, %k0|%k0, %2}"
8770   [(set_attr "type" "alu")
8771    (set_attr "mode" "SI")])
8772
8773 (define_insn "*iorsi_2_zext_imm"
8774   [(set (reg FLAGS_REG)
8775         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8776                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8777                  (const_int 0)))
8778    (set (match_operand:DI 0 "register_operand" "=r")
8779         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8780   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8781    && ix86_binary_operator_ok (IOR, SImode, operands)"
8782   "or{l}\t{%2, %k0|%k0, %2}"
8783   [(set_attr "type" "alu")
8784    (set_attr "mode" "SI")])
8785
8786 (define_insn "*iorsi_3"
8787   [(set (reg FLAGS_REG)
8788         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8789                          (match_operand:SI 2 "general_operand" "rim"))
8790                  (const_int 0)))
8791    (clobber (match_scratch:SI 0 "=r"))]
8792   "ix86_match_ccmode (insn, CCNOmode)
8793    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8794   "or{l}\t{%2, %0|%0, %2}"
8795   [(set_attr "type" "alu")
8796    (set_attr "mode" "SI")])
8797
8798 (define_expand "iorhi3"
8799   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8800         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8801                 (match_operand:HI 2 "general_operand" "")))
8802    (clobber (reg:CC FLAGS_REG))]
8803   "TARGET_HIMODE_MATH"
8804   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8805
8806 (define_insn "*iorhi_1"
8807   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8808         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8809                 (match_operand:HI 2 "general_operand" "rmi,ri")))
8810    (clobber (reg:CC FLAGS_REG))]
8811   "ix86_binary_operator_ok (IOR, HImode, operands)"
8812   "or{w}\t{%2, %0|%0, %2}"
8813   [(set_attr "type" "alu")
8814    (set_attr "mode" "HI")])
8815
8816 (define_insn "*iorhi_2"
8817   [(set (reg FLAGS_REG)
8818         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8819                          (match_operand:HI 2 "general_operand" "rim,ri"))
8820                  (const_int 0)))
8821    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8822         (ior:HI (match_dup 1) (match_dup 2)))]
8823   "ix86_match_ccmode (insn, CCNOmode)
8824    && ix86_binary_operator_ok (IOR, HImode, operands)"
8825   "or{w}\t{%2, %0|%0, %2}"
8826   [(set_attr "type" "alu")
8827    (set_attr "mode" "HI")])
8828
8829 (define_insn "*iorhi_3"
8830   [(set (reg FLAGS_REG)
8831         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8832                          (match_operand:HI 2 "general_operand" "rim"))
8833                  (const_int 0)))
8834    (clobber (match_scratch:HI 0 "=r"))]
8835   "ix86_match_ccmode (insn, CCNOmode)
8836    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8837   "or{w}\t{%2, %0|%0, %2}"
8838   [(set_attr "type" "alu")
8839    (set_attr "mode" "HI")])
8840
8841 (define_expand "iorqi3"
8842   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8843         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8844                 (match_operand:QI 2 "general_operand" "")))
8845    (clobber (reg:CC FLAGS_REG))]
8846   "TARGET_QIMODE_MATH"
8847   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8848
8849 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8850 (define_insn "*iorqi_1"
8851   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8852         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8853                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8854    (clobber (reg:CC FLAGS_REG))]
8855   "ix86_binary_operator_ok (IOR, QImode, operands)"
8856   "@
8857    or{b}\t{%2, %0|%0, %2}
8858    or{b}\t{%2, %0|%0, %2}
8859    or{l}\t{%k2, %k0|%k0, %k2}"
8860   [(set_attr "type" "alu")
8861    (set_attr "mode" "QI,QI,SI")])
8862
8863 (define_insn "*iorqi_1_slp"
8864   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8865         (ior:QI (match_dup 0)
8866                 (match_operand:QI 1 "general_operand" "qmi,qi")))
8867    (clobber (reg:CC FLAGS_REG))]
8868   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8869    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8870   "or{b}\t{%1, %0|%0, %1}"
8871   [(set_attr "type" "alu1")
8872    (set_attr "mode" "QI")])
8873
8874 (define_insn "*iorqi_2"
8875   [(set (reg FLAGS_REG)
8876         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8877                          (match_operand:QI 2 "general_operand" "qim,qi"))
8878                  (const_int 0)))
8879    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8880         (ior:QI (match_dup 1) (match_dup 2)))]
8881   "ix86_match_ccmode (insn, CCNOmode)
8882    && ix86_binary_operator_ok (IOR, QImode, operands)"
8883   "or{b}\t{%2, %0|%0, %2}"
8884   [(set_attr "type" "alu")
8885    (set_attr "mode" "QI")])
8886
8887 (define_insn "*iorqi_2_slp"
8888   [(set (reg FLAGS_REG)
8889         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8890                          (match_operand:QI 1 "general_operand" "qim,qi"))
8891                  (const_int 0)))
8892    (set (strict_low_part (match_dup 0))
8893         (ior:QI (match_dup 0) (match_dup 1)))]
8894   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8895    && ix86_match_ccmode (insn, CCNOmode)
8896    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8897   "or{b}\t{%1, %0|%0, %1}"
8898   [(set_attr "type" "alu1")
8899    (set_attr "mode" "QI")])
8900
8901 (define_insn "*iorqi_3"
8902   [(set (reg FLAGS_REG)
8903         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8904                          (match_operand:QI 2 "general_operand" "qim"))
8905                  (const_int 0)))
8906    (clobber (match_scratch:QI 0 "=q"))]
8907   "ix86_match_ccmode (insn, CCNOmode)
8908    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8909   "or{b}\t{%2, %0|%0, %2}"
8910   [(set_attr "type" "alu")
8911    (set_attr "mode" "QI")])
8912
8913 (define_insn "iorqi_ext_0"
8914   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8915                          (const_int 8)
8916                          (const_int 8))
8917         (ior:SI
8918           (zero_extract:SI
8919             (match_operand 1 "ext_register_operand" "0")
8920             (const_int 8)
8921             (const_int 8))
8922           (match_operand 2 "const_int_operand" "n")))
8923    (clobber (reg:CC FLAGS_REG))]
8924   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8925   "or{b}\t{%2, %h0|%h0, %2}"
8926   [(set_attr "type" "alu")
8927    (set_attr "length_immediate" "1")
8928    (set_attr "mode" "QI")])
8929
8930 (define_insn "*iorqi_ext_1"
8931   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8932                          (const_int 8)
8933                          (const_int 8))
8934         (ior:SI
8935           (zero_extract:SI
8936             (match_operand 1 "ext_register_operand" "0")
8937             (const_int 8)
8938             (const_int 8))
8939           (zero_extend:SI
8940             (match_operand:QI 2 "general_operand" "Qm"))))
8941    (clobber (reg:CC FLAGS_REG))]
8942   "!TARGET_64BIT
8943    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8944   "or{b}\t{%2, %h0|%h0, %2}"
8945   [(set_attr "type" "alu")
8946    (set_attr "length_immediate" "0")
8947    (set_attr "mode" "QI")])
8948
8949 (define_insn "*iorqi_ext_1_rex64"
8950   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8951                          (const_int 8)
8952                          (const_int 8))
8953         (ior:SI
8954           (zero_extract:SI
8955             (match_operand 1 "ext_register_operand" "0")
8956             (const_int 8)
8957             (const_int 8))
8958           (zero_extend:SI
8959             (match_operand 2 "ext_register_operand" "Q"))))
8960    (clobber (reg:CC FLAGS_REG))]
8961   "TARGET_64BIT
8962    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8963   "or{b}\t{%2, %h0|%h0, %2}"
8964   [(set_attr "type" "alu")
8965    (set_attr "length_immediate" "0")
8966    (set_attr "mode" "QI")])
8967
8968 (define_insn "*iorqi_ext_2"
8969   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8970                          (const_int 8)
8971                          (const_int 8))
8972         (ior:SI
8973           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8974                            (const_int 8)
8975                            (const_int 8))
8976           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8977                            (const_int 8)
8978                            (const_int 8))))
8979    (clobber (reg:CC FLAGS_REG))]
8980   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8981   "ior{b}\t{%h2, %h0|%h0, %h2}"
8982   [(set_attr "type" "alu")
8983    (set_attr "length_immediate" "0")
8984    (set_attr "mode" "QI")])
8985
8986 (define_split
8987   [(set (match_operand 0 "register_operand" "")
8988         (ior (match_operand 1 "register_operand" "")
8989              (match_operand 2 "const_int_operand" "")))
8990    (clobber (reg:CC FLAGS_REG))]
8991    "reload_completed
8992     && QI_REG_P (operands[0])
8993     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8994     && !(INTVAL (operands[2]) & ~(255 << 8))
8995     && GET_MODE (operands[0]) != QImode"
8996   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8997                    (ior:SI (zero_extract:SI (match_dup 1)
8998                                             (const_int 8) (const_int 8))
8999                            (match_dup 2)))
9000               (clobber (reg:CC FLAGS_REG))])]
9001   "operands[0] = gen_lowpart (SImode, operands[0]);
9002    operands[1] = gen_lowpart (SImode, operands[1]);
9003    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9004
9005 ;; Since OR can be encoded with sign extended immediate, this is only
9006 ;; profitable when 7th bit is set.
9007 (define_split
9008   [(set (match_operand 0 "register_operand" "")
9009         (ior (match_operand 1 "general_operand" "")
9010              (match_operand 2 "const_int_operand" "")))
9011    (clobber (reg:CC FLAGS_REG))]
9012    "reload_completed
9013     && ANY_QI_REG_P (operands[0])
9014     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9015     && !(INTVAL (operands[2]) & ~255)
9016     && (INTVAL (operands[2]) & 128)
9017     && GET_MODE (operands[0]) != QImode"
9018   [(parallel [(set (strict_low_part (match_dup 0))
9019                    (ior:QI (match_dup 1)
9020                            (match_dup 2)))
9021               (clobber (reg:CC FLAGS_REG))])]
9022   "operands[0] = gen_lowpart (QImode, operands[0]);
9023    operands[1] = gen_lowpart (QImode, operands[1]);
9024    operands[2] = gen_lowpart (QImode, operands[2]);")
9025 \f
9026 ;; Logical XOR instructions
9027
9028 ;; %%% This used to optimize known byte-wide and operations to memory.
9029 ;; If this is considered useful, it should be done with splitters.
9030
9031 (define_expand "xordi3"
9032   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9033         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9034                 (match_operand:DI 2 "x86_64_general_operand" "")))
9035    (clobber (reg:CC FLAGS_REG))]
9036   "TARGET_64BIT"
9037   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9038
9039 (define_insn "*xordi_1_rex64"
9040   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9041         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9042                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9043    (clobber (reg:CC FLAGS_REG))]
9044   "TARGET_64BIT
9045    && ix86_binary_operator_ok (XOR, DImode, operands)"
9046   "@
9047    xor{q}\t{%2, %0|%0, %2}
9048    xor{q}\t{%2, %0|%0, %2}"
9049   [(set_attr "type" "alu")
9050    (set_attr "mode" "DI,DI")])
9051
9052 (define_insn "*xordi_2_rex64"
9053   [(set (reg FLAGS_REG)
9054         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9055                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9056                  (const_int 0)))
9057    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9058         (xor:DI (match_dup 1) (match_dup 2)))]
9059   "TARGET_64BIT
9060    && ix86_match_ccmode (insn, CCNOmode)
9061    && ix86_binary_operator_ok (XOR, DImode, operands)"
9062   "@
9063    xor{q}\t{%2, %0|%0, %2}
9064    xor{q}\t{%2, %0|%0, %2}"
9065   [(set_attr "type" "alu")
9066    (set_attr "mode" "DI,DI")])
9067
9068 (define_insn "*xordi_3_rex64"
9069   [(set (reg FLAGS_REG)
9070         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9071                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9072                  (const_int 0)))
9073    (clobber (match_scratch:DI 0 "=r"))]
9074   "TARGET_64BIT
9075    && ix86_match_ccmode (insn, CCNOmode)
9076    && ix86_binary_operator_ok (XOR, DImode, operands)"
9077   "xor{q}\t{%2, %0|%0, %2}"
9078   [(set_attr "type" "alu")
9079    (set_attr "mode" "DI")])
9080
9081 (define_expand "xorsi3"
9082   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9083         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9084                 (match_operand:SI 2 "general_operand" "")))
9085    (clobber (reg:CC FLAGS_REG))]
9086   ""
9087   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9088
9089 (define_insn "*xorsi_1"
9090   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9091         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9092                 (match_operand:SI 2 "general_operand" "ri,rm")))
9093    (clobber (reg:CC FLAGS_REG))]
9094   "ix86_binary_operator_ok (XOR, SImode, operands)"
9095   "xor{l}\t{%2, %0|%0, %2}"
9096   [(set_attr "type" "alu")
9097    (set_attr "mode" "SI")])
9098
9099 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9100 ;; Add speccase for immediates
9101 (define_insn "*xorsi_1_zext"
9102   [(set (match_operand:DI 0 "register_operand" "=r")
9103         (zero_extend:DI
9104           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9105                   (match_operand:SI 2 "general_operand" "rim"))))
9106    (clobber (reg:CC FLAGS_REG))]
9107   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9108   "xor{l}\t{%2, %k0|%k0, %2}"
9109   [(set_attr "type" "alu")
9110    (set_attr "mode" "SI")])
9111
9112 (define_insn "*xorsi_1_zext_imm"
9113   [(set (match_operand:DI 0 "register_operand" "=r")
9114         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9115                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9116    (clobber (reg:CC FLAGS_REG))]
9117   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9118   "xor{l}\t{%2, %k0|%k0, %2}"
9119   [(set_attr "type" "alu")
9120    (set_attr "mode" "SI")])
9121
9122 (define_insn "*xorsi_2"
9123   [(set (reg FLAGS_REG)
9124         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9125                          (match_operand:SI 2 "general_operand" "rim,ri"))
9126                  (const_int 0)))
9127    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9128         (xor:SI (match_dup 1) (match_dup 2)))]
9129   "ix86_match_ccmode (insn, CCNOmode)
9130    && ix86_binary_operator_ok (XOR, SImode, operands)"
9131   "xor{l}\t{%2, %0|%0, %2}"
9132   [(set_attr "type" "alu")
9133    (set_attr "mode" "SI")])
9134
9135 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9136 ;; ??? Special case for immediate operand is missing - it is tricky.
9137 (define_insn "*xorsi_2_zext"
9138   [(set (reg FLAGS_REG)
9139         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9140                          (match_operand:SI 2 "general_operand" "rim"))
9141                  (const_int 0)))
9142    (set (match_operand:DI 0 "register_operand" "=r")
9143         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9144   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9145    && ix86_binary_operator_ok (XOR, SImode, operands)"
9146   "xor{l}\t{%2, %k0|%k0, %2}"
9147   [(set_attr "type" "alu")
9148    (set_attr "mode" "SI")])
9149
9150 (define_insn "*xorsi_2_zext_imm"
9151   [(set (reg FLAGS_REG)
9152         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9153                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9154                  (const_int 0)))
9155    (set (match_operand:DI 0 "register_operand" "=r")
9156         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9157   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9158    && ix86_binary_operator_ok (XOR, SImode, operands)"
9159   "xor{l}\t{%2, %k0|%k0, %2}"
9160   [(set_attr "type" "alu")
9161    (set_attr "mode" "SI")])
9162
9163 (define_insn "*xorsi_3"
9164   [(set (reg FLAGS_REG)
9165         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9166                          (match_operand:SI 2 "general_operand" "rim"))
9167                  (const_int 0)))
9168    (clobber (match_scratch:SI 0 "=r"))]
9169   "ix86_match_ccmode (insn, CCNOmode)
9170    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9171   "xor{l}\t{%2, %0|%0, %2}"
9172   [(set_attr "type" "alu")
9173    (set_attr "mode" "SI")])
9174
9175 (define_expand "xorhi3"
9176   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9177         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9178                 (match_operand:HI 2 "general_operand" "")))
9179    (clobber (reg:CC FLAGS_REG))]
9180   "TARGET_HIMODE_MATH"
9181   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9182
9183 (define_insn "*xorhi_1"
9184   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9185         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9186                 (match_operand:HI 2 "general_operand" "rmi,ri")))
9187    (clobber (reg:CC FLAGS_REG))]
9188   "ix86_binary_operator_ok (XOR, HImode, operands)"
9189   "xor{w}\t{%2, %0|%0, %2}"
9190   [(set_attr "type" "alu")
9191    (set_attr "mode" "HI")])
9192
9193 (define_insn "*xorhi_2"
9194   [(set (reg FLAGS_REG)
9195         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9196                          (match_operand:HI 2 "general_operand" "rim,ri"))
9197                  (const_int 0)))
9198    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9199         (xor:HI (match_dup 1) (match_dup 2)))]
9200   "ix86_match_ccmode (insn, CCNOmode)
9201    && ix86_binary_operator_ok (XOR, HImode, operands)"
9202   "xor{w}\t{%2, %0|%0, %2}"
9203   [(set_attr "type" "alu")
9204    (set_attr "mode" "HI")])
9205
9206 (define_insn "*xorhi_3"
9207   [(set (reg FLAGS_REG)
9208         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9209                          (match_operand:HI 2 "general_operand" "rim"))
9210                  (const_int 0)))
9211    (clobber (match_scratch:HI 0 "=r"))]
9212   "ix86_match_ccmode (insn, CCNOmode)
9213    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9214   "xor{w}\t{%2, %0|%0, %2}"
9215   [(set_attr "type" "alu")
9216    (set_attr "mode" "HI")])
9217
9218 (define_expand "xorqi3"
9219   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9220         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9221                 (match_operand:QI 2 "general_operand" "")))
9222    (clobber (reg:CC FLAGS_REG))]
9223   "TARGET_QIMODE_MATH"
9224   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9225
9226 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9227 (define_insn "*xorqi_1"
9228   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9229         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9230                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9231    (clobber (reg:CC FLAGS_REG))]
9232   "ix86_binary_operator_ok (XOR, QImode, operands)"
9233   "@
9234    xor{b}\t{%2, %0|%0, %2}
9235    xor{b}\t{%2, %0|%0, %2}
9236    xor{l}\t{%k2, %k0|%k0, %k2}"
9237   [(set_attr "type" "alu")
9238    (set_attr "mode" "QI,QI,SI")])
9239
9240 (define_insn "*xorqi_1_slp"
9241   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9242         (xor:QI (match_dup 0)
9243                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9244    (clobber (reg:CC FLAGS_REG))]
9245   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9246    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9247   "xor{b}\t{%1, %0|%0, %1}"
9248   [(set_attr "type" "alu1")
9249    (set_attr "mode" "QI")])
9250
9251 (define_insn "xorqi_ext_0"
9252   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9253                          (const_int 8)
9254                          (const_int 8))
9255         (xor:SI
9256           (zero_extract:SI
9257             (match_operand 1 "ext_register_operand" "0")
9258             (const_int 8)
9259             (const_int 8))
9260           (match_operand 2 "const_int_operand" "n")))
9261    (clobber (reg:CC FLAGS_REG))]
9262   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9263   "xor{b}\t{%2, %h0|%h0, %2}"
9264   [(set_attr "type" "alu")
9265    (set_attr "length_immediate" "1")
9266    (set_attr "mode" "QI")])
9267
9268 (define_insn "*xorqi_ext_1"
9269   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9270                          (const_int 8)
9271                          (const_int 8))
9272         (xor:SI
9273           (zero_extract:SI
9274             (match_operand 1 "ext_register_operand" "0")
9275             (const_int 8)
9276             (const_int 8))
9277           (zero_extend:SI
9278             (match_operand:QI 2 "general_operand" "Qm"))))
9279    (clobber (reg:CC FLAGS_REG))]
9280   "!TARGET_64BIT
9281    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9282   "xor{b}\t{%2, %h0|%h0, %2}"
9283   [(set_attr "type" "alu")
9284    (set_attr "length_immediate" "0")
9285    (set_attr "mode" "QI")])
9286
9287 (define_insn "*xorqi_ext_1_rex64"
9288   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9289                          (const_int 8)
9290                          (const_int 8))
9291         (xor:SI
9292           (zero_extract:SI
9293             (match_operand 1 "ext_register_operand" "0")
9294             (const_int 8)
9295             (const_int 8))
9296           (zero_extend:SI
9297             (match_operand 2 "ext_register_operand" "Q"))))
9298    (clobber (reg:CC FLAGS_REG))]
9299   "TARGET_64BIT
9300    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9301   "xor{b}\t{%2, %h0|%h0, %2}"
9302   [(set_attr "type" "alu")
9303    (set_attr "length_immediate" "0")
9304    (set_attr "mode" "QI")])
9305
9306 (define_insn "*xorqi_ext_2"
9307   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9308                          (const_int 8)
9309                          (const_int 8))
9310         (xor:SI
9311           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9312                            (const_int 8)
9313                            (const_int 8))
9314           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9315                            (const_int 8)
9316                            (const_int 8))))
9317    (clobber (reg:CC FLAGS_REG))]
9318   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9319   "xor{b}\t{%h2, %h0|%h0, %h2}"
9320   [(set_attr "type" "alu")
9321    (set_attr "length_immediate" "0")
9322    (set_attr "mode" "QI")])
9323
9324 (define_insn "*xorqi_cc_1"
9325   [(set (reg FLAGS_REG)
9326         (compare
9327           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9328                   (match_operand:QI 2 "general_operand" "qim,qi"))
9329           (const_int 0)))
9330    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9331         (xor:QI (match_dup 1) (match_dup 2)))]
9332   "ix86_match_ccmode (insn, CCNOmode)
9333    && ix86_binary_operator_ok (XOR, QImode, operands)"
9334   "xor{b}\t{%2, %0|%0, %2}"
9335   [(set_attr "type" "alu")
9336    (set_attr "mode" "QI")])
9337
9338 (define_insn "*xorqi_2_slp"
9339   [(set (reg FLAGS_REG)
9340         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9341                          (match_operand:QI 1 "general_operand" "qim,qi"))
9342                  (const_int 0)))
9343    (set (strict_low_part (match_dup 0))
9344         (xor:QI (match_dup 0) (match_dup 1)))]
9345   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9346    && ix86_match_ccmode (insn, CCNOmode)
9347    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9348   "xor{b}\t{%1, %0|%0, %1}"
9349   [(set_attr "type" "alu1")
9350    (set_attr "mode" "QI")])
9351
9352 (define_insn "*xorqi_cc_2"
9353   [(set (reg FLAGS_REG)
9354         (compare
9355           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9356                   (match_operand:QI 2 "general_operand" "qim"))
9357           (const_int 0)))
9358    (clobber (match_scratch:QI 0 "=q"))]
9359   "ix86_match_ccmode (insn, CCNOmode)
9360    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9361   "xor{b}\t{%2, %0|%0, %2}"
9362   [(set_attr "type" "alu")
9363    (set_attr "mode" "QI")])
9364
9365 (define_insn "*xorqi_cc_ext_1"
9366   [(set (reg FLAGS_REG)
9367         (compare
9368           (xor:SI
9369             (zero_extract:SI
9370               (match_operand 1 "ext_register_operand" "0")
9371               (const_int 8)
9372               (const_int 8))
9373             (match_operand:QI 2 "general_operand" "qmn"))
9374           (const_int 0)))
9375    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9376                          (const_int 8)
9377                          (const_int 8))
9378         (xor:SI
9379           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9380           (match_dup 2)))]
9381   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9382   "xor{b}\t{%2, %h0|%h0, %2}"
9383   [(set_attr "type" "alu")
9384    (set_attr "mode" "QI")])
9385
9386 (define_insn "*xorqi_cc_ext_1_rex64"
9387   [(set (reg FLAGS_REG)
9388         (compare
9389           (xor:SI
9390             (zero_extract:SI
9391               (match_operand 1 "ext_register_operand" "0")
9392               (const_int 8)
9393               (const_int 8))
9394             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9395           (const_int 0)))
9396    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9397                          (const_int 8)
9398                          (const_int 8))
9399         (xor:SI
9400           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9401           (match_dup 2)))]
9402   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9403   "xor{b}\t{%2, %h0|%h0, %2}"
9404   [(set_attr "type" "alu")
9405    (set_attr "mode" "QI")])
9406
9407 (define_expand "xorqi_cc_ext_1"
9408   [(parallel [
9409      (set (reg:CCNO FLAGS_REG)
9410           (compare:CCNO
9411             (xor:SI
9412               (zero_extract:SI
9413                 (match_operand 1 "ext_register_operand" "")
9414                 (const_int 8)
9415                 (const_int 8))
9416               (match_operand:QI 2 "general_operand" ""))
9417             (const_int 0)))
9418      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9419                            (const_int 8)
9420                            (const_int 8))
9421           (xor:SI
9422             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9423             (match_dup 2)))])]
9424   ""
9425   "")
9426
9427 (define_split
9428   [(set (match_operand 0 "register_operand" "")
9429         (xor (match_operand 1 "register_operand" "")
9430              (match_operand 2 "const_int_operand" "")))
9431    (clobber (reg:CC FLAGS_REG))]
9432    "reload_completed
9433     && QI_REG_P (operands[0])
9434     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9435     && !(INTVAL (operands[2]) & ~(255 << 8))
9436     && GET_MODE (operands[0]) != QImode"
9437   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9438                    (xor:SI (zero_extract:SI (match_dup 1)
9439                                             (const_int 8) (const_int 8))
9440                            (match_dup 2)))
9441               (clobber (reg:CC FLAGS_REG))])]
9442   "operands[0] = gen_lowpart (SImode, operands[0]);
9443    operands[1] = gen_lowpart (SImode, operands[1]);
9444    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9445
9446 ;; Since XOR can be encoded with sign extended immediate, this is only
9447 ;; profitable when 7th bit is set.
9448 (define_split
9449   [(set (match_operand 0 "register_operand" "")
9450         (xor (match_operand 1 "general_operand" "")
9451              (match_operand 2 "const_int_operand" "")))
9452    (clobber (reg:CC FLAGS_REG))]
9453    "reload_completed
9454     && ANY_QI_REG_P (operands[0])
9455     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9456     && !(INTVAL (operands[2]) & ~255)
9457     && (INTVAL (operands[2]) & 128)
9458     && GET_MODE (operands[0]) != QImode"
9459   [(parallel [(set (strict_low_part (match_dup 0))
9460                    (xor:QI (match_dup 1)
9461                            (match_dup 2)))
9462               (clobber (reg:CC FLAGS_REG))])]
9463   "operands[0] = gen_lowpart (QImode, operands[0]);
9464    operands[1] = gen_lowpart (QImode, operands[1]);
9465    operands[2] = gen_lowpart (QImode, operands[2]);")
9466 \f
9467 ;; Negation instructions
9468
9469 (define_expand "negti2"
9470   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9471                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9472               (clobber (reg:CC FLAGS_REG))])]
9473   "TARGET_64BIT"
9474   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9475
9476 (define_insn "*negti2_1"
9477   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9478         (neg:TI (match_operand:TI 1 "general_operand" "0")))
9479    (clobber (reg:CC FLAGS_REG))]
9480   "TARGET_64BIT
9481    && ix86_unary_operator_ok (NEG, TImode, operands)"
9482   "#")
9483
9484 (define_split
9485   [(set (match_operand:TI 0 "nonimmediate_operand" "")
9486         (neg:TI (match_operand:TI 1 "general_operand" "")))
9487    (clobber (reg:CC FLAGS_REG))]
9488   "TARGET_64BIT && reload_completed"
9489   [(parallel
9490     [(set (reg:CCZ FLAGS_REG)
9491           (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9492      (set (match_dup 0) (neg:DI (match_dup 2)))])
9493    (parallel
9494     [(set (match_dup 1)
9495           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9496                             (match_dup 3))
9497                    (const_int 0)))
9498      (clobber (reg:CC FLAGS_REG))])
9499    (parallel
9500     [(set (match_dup 1)
9501           (neg:DI (match_dup 1)))
9502      (clobber (reg:CC FLAGS_REG))])]
9503   "split_ti (operands+1, 1, operands+2, operands+3);
9504    split_ti (operands+0, 1, operands+0, operands+1);")
9505
9506 (define_expand "negdi2"
9507   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9508                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9509               (clobber (reg:CC FLAGS_REG))])]
9510   ""
9511   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9512
9513 (define_insn "*negdi2_1"
9514   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9515         (neg:DI (match_operand:DI 1 "general_operand" "0")))
9516    (clobber (reg:CC FLAGS_REG))]
9517   "!TARGET_64BIT
9518    && ix86_unary_operator_ok (NEG, DImode, operands)"
9519   "#")
9520
9521 (define_split
9522   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9523         (neg:DI (match_operand:DI 1 "general_operand" "")))
9524    (clobber (reg:CC FLAGS_REG))]
9525   "!TARGET_64BIT && reload_completed"
9526   [(parallel
9527     [(set (reg:CCZ FLAGS_REG)
9528           (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9529      (set (match_dup 0) (neg:SI (match_dup 2)))])
9530    (parallel
9531     [(set (match_dup 1)
9532           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9533                             (match_dup 3))
9534                    (const_int 0)))
9535      (clobber (reg:CC FLAGS_REG))])
9536    (parallel
9537     [(set (match_dup 1)
9538           (neg:SI (match_dup 1)))
9539      (clobber (reg:CC FLAGS_REG))])]
9540   "split_di (operands+1, 1, operands+2, operands+3);
9541    split_di (operands+0, 1, operands+0, operands+1);")
9542
9543 (define_insn "*negdi2_1_rex64"
9544   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9545         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9546    (clobber (reg:CC FLAGS_REG))]
9547   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9548   "neg{q}\t%0"
9549   [(set_attr "type" "negnot")
9550    (set_attr "mode" "DI")])
9551
9552 ;; The problem with neg is that it does not perform (compare x 0),
9553 ;; it really performs (compare 0 x), which leaves us with the zero
9554 ;; flag being the only useful item.
9555
9556 (define_insn "*negdi2_cmpz_rex64"
9557   [(set (reg:CCZ FLAGS_REG)
9558         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9559                      (const_int 0)))
9560    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9561         (neg:DI (match_dup 1)))]
9562   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9563   "neg{q}\t%0"
9564   [(set_attr "type" "negnot")
9565    (set_attr "mode" "DI")])
9566
9567
9568 (define_expand "negsi2"
9569   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9570                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9571               (clobber (reg:CC FLAGS_REG))])]
9572   ""
9573   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9574
9575 (define_insn "*negsi2_1"
9576   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9577         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9578    (clobber (reg:CC FLAGS_REG))]
9579   "ix86_unary_operator_ok (NEG, SImode, operands)"
9580   "neg{l}\t%0"
9581   [(set_attr "type" "negnot")
9582    (set_attr "mode" "SI")])
9583
9584 ;; Combine is quite creative about this pattern.
9585 (define_insn "*negsi2_1_zext"
9586   [(set (match_operand:DI 0 "register_operand" "=r")
9587         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9588                                         (const_int 32)))
9589                      (const_int 32)))
9590    (clobber (reg:CC FLAGS_REG))]
9591   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9592   "neg{l}\t%k0"
9593   [(set_attr "type" "negnot")
9594    (set_attr "mode" "SI")])
9595
9596 ;; The problem with neg is that it does not perform (compare x 0),
9597 ;; it really performs (compare 0 x), which leaves us with the zero
9598 ;; flag being the only useful item.
9599
9600 (define_insn "*negsi2_cmpz"
9601   [(set (reg:CCZ FLAGS_REG)
9602         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9603                      (const_int 0)))
9604    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9605         (neg:SI (match_dup 1)))]
9606   "ix86_unary_operator_ok (NEG, SImode, operands)"
9607   "neg{l}\t%0"
9608   [(set_attr "type" "negnot")
9609    (set_attr "mode" "SI")])
9610
9611 (define_insn "*negsi2_cmpz_zext"
9612   [(set (reg:CCZ FLAGS_REG)
9613         (compare:CCZ (lshiftrt:DI
9614                        (neg:DI (ashift:DI
9615                                  (match_operand:DI 1 "register_operand" "0")
9616                                  (const_int 32)))
9617                        (const_int 32))
9618                      (const_int 0)))
9619    (set (match_operand:DI 0 "register_operand" "=r")
9620         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9621                                         (const_int 32)))
9622                      (const_int 32)))]
9623   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9624   "neg{l}\t%k0"
9625   [(set_attr "type" "negnot")
9626    (set_attr "mode" "SI")])
9627
9628 (define_expand "neghi2"
9629   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9630                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9631               (clobber (reg:CC FLAGS_REG))])]
9632   "TARGET_HIMODE_MATH"
9633   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9634
9635 (define_insn "*neghi2_1"
9636   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9637         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9638    (clobber (reg:CC FLAGS_REG))]
9639   "ix86_unary_operator_ok (NEG, HImode, operands)"
9640   "neg{w}\t%0"
9641   [(set_attr "type" "negnot")
9642    (set_attr "mode" "HI")])
9643
9644 (define_insn "*neghi2_cmpz"
9645   [(set (reg:CCZ FLAGS_REG)
9646         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9647                      (const_int 0)))
9648    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9649         (neg:HI (match_dup 1)))]
9650   "ix86_unary_operator_ok (NEG, HImode, operands)"
9651   "neg{w}\t%0"
9652   [(set_attr "type" "negnot")
9653    (set_attr "mode" "HI")])
9654
9655 (define_expand "negqi2"
9656   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9657                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9658               (clobber (reg:CC FLAGS_REG))])]
9659   "TARGET_QIMODE_MATH"
9660   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9661
9662 (define_insn "*negqi2_1"
9663   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9664         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9665    (clobber (reg:CC FLAGS_REG))]
9666   "ix86_unary_operator_ok (NEG, QImode, operands)"
9667   "neg{b}\t%0"
9668   [(set_attr "type" "negnot")
9669    (set_attr "mode" "QI")])
9670
9671 (define_insn "*negqi2_cmpz"
9672   [(set (reg:CCZ FLAGS_REG)
9673         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9674                      (const_int 0)))
9675    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9676         (neg:QI (match_dup 1)))]
9677   "ix86_unary_operator_ok (NEG, QImode, operands)"
9678   "neg{b}\t%0"
9679   [(set_attr "type" "negnot")
9680    (set_attr "mode" "QI")])
9681
9682 ;; Changing of sign for FP values is doable using integer unit too.
9683
9684 (define_expand "negsf2"
9685   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9686         (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9687   "TARGET_80387 || TARGET_SSE_MATH"
9688   "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9689
9690 (define_expand "abssf2"
9691   [(set (match_operand:SF 0 "nonimmediate_operand" "")
9692         (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9693   "TARGET_80387 || TARGET_SSE_MATH"
9694   "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9695
9696 (define_insn "*absnegsf2_mixed"
9697   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x  ,x,f,rm")
9698         (match_operator:SF 3 "absneg_operator"
9699           [(match_operand:SF 1 "nonimmediate_operand" "0   ,x,0,0 ")]))
9700    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm  ,0,X,X "))
9701    (clobber (reg:CC FLAGS_REG))]
9702   "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9703    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9704   "#")
9705
9706 (define_insn "*absnegsf2_sse"
9707   [(set (match_operand:SF 0 "nonimmediate_operand"    "=x,x,rm")
9708         (match_operator:SF 3 "absneg_operator"
9709           [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9710    (use (match_operand:V4SF 2 "nonimmediate_operand"  "xm,0,X"))
9711    (clobber (reg:CC FLAGS_REG))]
9712   "TARGET_SSE_MATH
9713    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9714   "#")
9715
9716 (define_insn "*absnegsf2_i387"
9717   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9718         (match_operator:SF 3 "absneg_operator"
9719           [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9720    (use (match_operand 2 "" ""))
9721    (clobber (reg:CC FLAGS_REG))]
9722   "TARGET_80387 && !TARGET_SSE_MATH
9723    && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9724   "#")
9725
9726 (define_expand "copysignsf3"
9727   [(match_operand:SF 0 "register_operand" "")
9728    (match_operand:SF 1 "nonmemory_operand" "")
9729    (match_operand:SF 2 "register_operand" "")]
9730   "TARGET_SSE_MATH"
9731 {
9732   ix86_expand_copysign (operands);
9733   DONE;
9734 })
9735
9736 (define_insn_and_split "copysignsf3_const"
9737   [(set (match_operand:SF 0 "register_operand"          "=x")
9738         (unspec:SF
9739           [(match_operand:V4SF 1 "vector_move_operand"  "xmC")
9740            (match_operand:SF 2 "register_operand"       "0")
9741            (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9742           UNSPEC_COPYSIGN))]
9743   "TARGET_SSE_MATH"
9744   "#"
9745   "&& reload_completed"
9746   [(const_int 0)]
9747 {
9748   ix86_split_copysign_const (operands);
9749   DONE;
9750 })
9751
9752 (define_insn "copysignsf3_var"
9753   [(set (match_operand:SF 0 "register_operand"          "=x, x, x, x,x")
9754         (unspec:SF
9755           [(match_operand:SF 2 "register_operand"       " x, 0, 0, x,x")
9756            (match_operand:SF 3 "register_operand"       " 1, 1, x, 1,x")
9757            (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9758            (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9759           UNSPEC_COPYSIGN))
9760    (clobber (match_scratch:V4SF 1                       "=x, x, x, x,x"))]
9761   "TARGET_SSE_MATH"
9762   "#")
9763
9764 (define_split
9765   [(set (match_operand:SF 0 "register_operand" "")
9766         (unspec:SF
9767           [(match_operand:SF 2 "register_operand" "")
9768            (match_operand:SF 3 "register_operand" "")
9769            (match_operand:V4SF 4 "" "")
9770            (match_operand:V4SF 5 "" "")]
9771           UNSPEC_COPYSIGN))
9772    (clobber (match_scratch:V4SF 1 ""))]
9773   "TARGET_SSE_MATH && reload_completed"
9774   [(const_int 0)]
9775 {
9776   ix86_split_copysign_var (operands);
9777   DONE;
9778 })
9779
9780 (define_expand "negdf2"
9781   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9782         (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9783   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9784   "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9785
9786 (define_expand "absdf2"
9787   [(set (match_operand:DF 0 "nonimmediate_operand" "")
9788         (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9789   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9790   "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9791
9792 (define_insn "*absnegdf2_mixed"
9793   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,f,rm")
9794         (match_operator:DF 3 "absneg_operator"
9795           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9796    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X,X"))
9797    (clobber (reg:CC FLAGS_REG))]
9798   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9799    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9800   "#")
9801
9802 (define_insn "*absnegdf2_sse"
9803   [(set (match_operand:DF 0 "nonimmediate_operand"    "=Y,Y,rm")
9804         (match_operator:DF 3 "absneg_operator"
9805           [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9806    (use (match_operand:V2DF 2 "nonimmediate_operand"  "Ym,0,X "))
9807    (clobber (reg:CC FLAGS_REG))]
9808   "TARGET_SSE2 && TARGET_SSE_MATH
9809    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9810   "#")
9811
9812 (define_insn "*absnegdf2_i387"
9813   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9814         (match_operator:DF 3 "absneg_operator"
9815           [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9816    (use (match_operand 2 "" ""))
9817    (clobber (reg:CC FLAGS_REG))]
9818   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9819    && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9820   "#")
9821
9822 (define_expand "copysigndf3"
9823   [(match_operand:DF 0 "register_operand" "")
9824    (match_operand:DF 1 "nonmemory_operand" "")
9825    (match_operand:DF 2 "register_operand" "")]
9826   "TARGET_SSE2 && TARGET_SSE_MATH"
9827 {
9828   ix86_expand_copysign (operands);
9829   DONE;
9830 })
9831
9832 (define_insn_and_split "copysigndf3_const"
9833   [(set (match_operand:DF 0 "register_operand"          "=x")
9834         (unspec:DF
9835           [(match_operand:V2DF 1 "vector_move_operand"  "xmC")
9836            (match_operand:DF 2 "register_operand"       "0")
9837            (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9838           UNSPEC_COPYSIGN))]
9839   "TARGET_SSE2 && TARGET_SSE_MATH"
9840   "#"
9841   "&& reload_completed"
9842   [(const_int 0)]
9843 {
9844   ix86_split_copysign_const (operands);
9845   DONE;
9846 })
9847
9848 (define_insn "copysigndf3_var"
9849   [(set (match_operand:DF 0 "register_operand"          "=x, x, x, x,x")
9850         (unspec:DF
9851           [(match_operand:DF 2 "register_operand"       " x, 0, 0, x,x")
9852            (match_operand:DF 3 "register_operand"       " 1, 1, x, 1,x")
9853            (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9854            (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9855           UNSPEC_COPYSIGN))
9856    (clobber (match_scratch:V2DF 1                       "=x, x, x, x,x"))]
9857   "TARGET_SSE2 && TARGET_SSE_MATH"
9858   "#")
9859
9860 (define_split
9861   [(set (match_operand:DF 0 "register_operand" "")
9862         (unspec:DF
9863           [(match_operand:DF 2 "register_operand" "")
9864            (match_operand:DF 3 "register_operand" "")
9865            (match_operand:V2DF 4 "" "")
9866            (match_operand:V2DF 5 "" "")]
9867           UNSPEC_COPYSIGN))
9868    (clobber (match_scratch:V2DF 1 ""))]
9869   "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9870   [(const_int 0)]
9871 {
9872   ix86_split_copysign_var (operands);
9873   DONE;
9874 })
9875
9876 (define_expand "negxf2"
9877   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9878         (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9879   "TARGET_80387"
9880   "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9881
9882 (define_expand "absxf2"
9883   [(set (match_operand:XF 0 "nonimmediate_operand" "")
9884         (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9885   "TARGET_80387"
9886   "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9887
9888 (define_insn "*absnegxf2_i387"
9889   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9890         (match_operator:XF 3 "absneg_operator"
9891           [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9892    (use (match_operand 2 "" ""))
9893    (clobber (reg:CC FLAGS_REG))]
9894   "TARGET_80387
9895    && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9896   "#")
9897
9898 ;; Splitters for fp abs and neg.
9899
9900 (define_split
9901   [(set (match_operand 0 "fp_register_operand" "")
9902         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9903    (use (match_operand 2 "" ""))
9904    (clobber (reg:CC FLAGS_REG))]
9905   "reload_completed"
9906   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9907
9908 (define_split
9909   [(set (match_operand 0 "register_operand" "")
9910         (match_operator 3 "absneg_operator"
9911           [(match_operand 1 "register_operand" "")]))
9912    (use (match_operand 2 "nonimmediate_operand" ""))
9913    (clobber (reg:CC FLAGS_REG))]
9914   "reload_completed && SSE_REG_P (operands[0])"
9915   [(set (match_dup 0) (match_dup 3))]
9916 {
9917   enum machine_mode mode = GET_MODE (operands[0]);
9918   enum machine_mode vmode = GET_MODE (operands[2]);
9919   rtx tmp;
9920
9921   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9922   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9923   if (operands_match_p (operands[0], operands[2]))
9924     {
9925       tmp = operands[1];
9926       operands[1] = operands[2];
9927       operands[2] = tmp;
9928     }
9929   if (GET_CODE (operands[3]) == ABS)
9930     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9931   else
9932     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9933   operands[3] = tmp;
9934 })
9935
9936 (define_split
9937   [(set (match_operand:SF 0 "register_operand" "")
9938         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9939    (use (match_operand:V4SF 2 "" ""))
9940    (clobber (reg:CC FLAGS_REG))]
9941   "reload_completed"
9942   [(parallel [(set (match_dup 0) (match_dup 1))
9943               (clobber (reg:CC FLAGS_REG))])]
9944 {
9945   rtx tmp;
9946   operands[0] = gen_lowpart (SImode, operands[0]);
9947   if (GET_CODE (operands[1]) == ABS)
9948     {
9949       tmp = gen_int_mode (0x7fffffff, SImode);
9950       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9951     }
9952   else
9953     {
9954       tmp = gen_int_mode (0x80000000, SImode);
9955       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9956     }
9957   operands[1] = tmp;
9958 })
9959
9960 (define_split
9961   [(set (match_operand:DF 0 "register_operand" "")
9962         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9963    (use (match_operand 2 "" ""))
9964    (clobber (reg:CC FLAGS_REG))]
9965   "reload_completed"
9966   [(parallel [(set (match_dup 0) (match_dup 1))
9967               (clobber (reg:CC FLAGS_REG))])]
9968 {
9969   rtx tmp;
9970   if (TARGET_64BIT)
9971     {
9972       tmp = gen_lowpart (DImode, operands[0]);
9973       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9974       operands[0] = tmp;
9975
9976       if (GET_CODE (operands[1]) == ABS)
9977         tmp = const0_rtx;
9978       else
9979         tmp = gen_rtx_NOT (DImode, tmp);
9980     }
9981   else
9982     {
9983       operands[0] = gen_highpart (SImode, operands[0]);
9984       if (GET_CODE (operands[1]) == ABS)
9985         {
9986           tmp = gen_int_mode (0x7fffffff, SImode);
9987           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9988         }
9989       else
9990         {
9991           tmp = gen_int_mode (0x80000000, SImode);
9992           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9993         }
9994     }
9995   operands[1] = tmp;
9996 })
9997
9998 (define_split
9999   [(set (match_operand:XF 0 "register_operand" "")
10000         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10001    (use (match_operand 2 "" ""))
10002    (clobber (reg:CC FLAGS_REG))]
10003   "reload_completed"
10004   [(parallel [(set (match_dup 0) (match_dup 1))
10005               (clobber (reg:CC FLAGS_REG))])]
10006 {
10007   rtx tmp;
10008   operands[0] = gen_rtx_REG (SImode,
10009                              true_regnum (operands[0])
10010                              + (TARGET_64BIT ? 1 : 2));
10011   if (GET_CODE (operands[1]) == ABS)
10012     {
10013       tmp = GEN_INT (0x7fff);
10014       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10015     }
10016   else
10017     {
10018       tmp = GEN_INT (0x8000);
10019       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10020     }
10021   operands[1] = tmp;
10022 })
10023
10024 (define_split
10025   [(set (match_operand 0 "memory_operand" "")
10026         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10027    (use (match_operand 2 "" ""))
10028    (clobber (reg:CC FLAGS_REG))]
10029   "reload_completed"
10030   [(parallel [(set (match_dup 0) (match_dup 1))
10031               (clobber (reg:CC FLAGS_REG))])]
10032 {
10033   enum machine_mode mode = GET_MODE (operands[0]);
10034   int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
10035   rtx tmp;
10036
10037   operands[0] = adjust_address (operands[0], QImode, size - 1);
10038   if (GET_CODE (operands[1]) == ABS)
10039     {
10040       tmp = gen_int_mode (0x7f, QImode);
10041       tmp = gen_rtx_AND (QImode, operands[0], tmp);
10042     }
10043   else
10044     {
10045       tmp = gen_int_mode (0x80, QImode);
10046       tmp = gen_rtx_XOR (QImode, operands[0], tmp);
10047     }
10048   operands[1] = tmp;
10049 })
10050
10051 ;; Conditionalize these after reload. If they match before reload, we
10052 ;; lose the clobber and ability to use integer instructions.
10053
10054 (define_insn "*negsf2_1"
10055   [(set (match_operand:SF 0 "register_operand" "=f")
10056         (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10057   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10058   "fchs"
10059   [(set_attr "type" "fsgn")
10060    (set_attr "mode" "SF")])
10061
10062 (define_insn "*negdf2_1"
10063   [(set (match_operand:DF 0 "register_operand" "=f")
10064         (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10065   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10066   "fchs"
10067   [(set_attr "type" "fsgn")
10068    (set_attr "mode" "DF")])
10069
10070 (define_insn "*negxf2_1"
10071   [(set (match_operand:XF 0 "register_operand" "=f")
10072         (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10073   "TARGET_80387"
10074   "fchs"
10075   [(set_attr "type" "fsgn")
10076    (set_attr "mode" "XF")])
10077
10078 (define_insn "*abssf2_1"
10079   [(set (match_operand:SF 0 "register_operand" "=f")
10080         (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10081   "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10082   "fabs"
10083   [(set_attr "type" "fsgn")
10084    (set_attr "mode" "SF")])
10085
10086 (define_insn "*absdf2_1"
10087   [(set (match_operand:DF 0 "register_operand" "=f")
10088         (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10089   "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10090   "fabs"
10091   [(set_attr "type" "fsgn")
10092    (set_attr "mode" "DF")])
10093
10094 (define_insn "*absxf2_1"
10095   [(set (match_operand:XF 0 "register_operand" "=f")
10096         (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10097   "TARGET_80387"
10098   "fabs"
10099   [(set_attr "type" "fsgn")
10100    (set_attr "mode" "DF")])
10101
10102 (define_insn "*negextendsfdf2"
10103   [(set (match_operand:DF 0 "register_operand" "=f")
10104         (neg:DF (float_extend:DF
10105                   (match_operand:SF 1 "register_operand" "0"))))]
10106   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10107   "fchs"
10108   [(set_attr "type" "fsgn")
10109    (set_attr "mode" "DF")])
10110
10111 (define_insn "*negextenddfxf2"
10112   [(set (match_operand:XF 0 "register_operand" "=f")
10113         (neg:XF (float_extend:XF
10114                   (match_operand:DF 1 "register_operand" "0"))))]
10115   "TARGET_80387"
10116   "fchs"
10117   [(set_attr "type" "fsgn")
10118    (set_attr "mode" "XF")])
10119
10120 (define_insn "*negextendsfxf2"
10121   [(set (match_operand:XF 0 "register_operand" "=f")
10122         (neg:XF (float_extend:XF
10123                   (match_operand:SF 1 "register_operand" "0"))))]
10124   "TARGET_80387"
10125   "fchs"
10126   [(set_attr "type" "fsgn")
10127    (set_attr "mode" "XF")])
10128
10129 (define_insn "*absextendsfdf2"
10130   [(set (match_operand:DF 0 "register_operand" "=f")
10131         (abs:DF (float_extend:DF
10132                   (match_operand:SF 1 "register_operand" "0"))))]
10133   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10134   "fabs"
10135   [(set_attr "type" "fsgn")
10136    (set_attr "mode" "DF")])
10137
10138 (define_insn "*absextenddfxf2"
10139   [(set (match_operand:XF 0 "register_operand" "=f")
10140         (abs:XF (float_extend:XF
10141           (match_operand:DF 1 "register_operand" "0"))))]
10142   "TARGET_80387"
10143   "fabs"
10144   [(set_attr "type" "fsgn")
10145    (set_attr "mode" "XF")])
10146
10147 (define_insn "*absextendsfxf2"
10148   [(set (match_operand:XF 0 "register_operand" "=f")
10149         (abs:XF (float_extend:XF
10150           (match_operand:SF 1 "register_operand" "0"))))]
10151   "TARGET_80387"
10152   "fabs"
10153   [(set_attr "type" "fsgn")
10154    (set_attr "mode" "XF")])
10155 \f
10156 ;; One complement instructions
10157
10158 (define_expand "one_cmpldi2"
10159   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10160         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10161   "TARGET_64BIT"
10162   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10163
10164 (define_insn "*one_cmpldi2_1_rex64"
10165   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10166         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10167   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10168   "not{q}\t%0"
10169   [(set_attr "type" "negnot")
10170    (set_attr "mode" "DI")])
10171
10172 (define_insn "*one_cmpldi2_2_rex64"
10173   [(set (reg FLAGS_REG)
10174         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10175                  (const_int 0)))
10176    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10177         (not:DI (match_dup 1)))]
10178   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10179    && ix86_unary_operator_ok (NOT, DImode, operands)"
10180   "#"
10181   [(set_attr "type" "alu1")
10182    (set_attr "mode" "DI")])
10183
10184 (define_split
10185   [(set (match_operand 0 "flags_reg_operand" "")
10186         (match_operator 2 "compare_operator"
10187           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10188            (const_int 0)]))
10189    (set (match_operand:DI 1 "nonimmediate_operand" "")
10190         (not:DI (match_dup 3)))]
10191   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10192   [(parallel [(set (match_dup 0)
10193                    (match_op_dup 2
10194                      [(xor:DI (match_dup 3) (const_int -1))
10195                       (const_int 0)]))
10196               (set (match_dup 1)
10197                    (xor:DI (match_dup 3) (const_int -1)))])]
10198   "")
10199
10200 (define_expand "one_cmplsi2"
10201   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10202         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10203   ""
10204   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10205
10206 (define_insn "*one_cmplsi2_1"
10207   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10208         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10209   "ix86_unary_operator_ok (NOT, SImode, operands)"
10210   "not{l}\t%0"
10211   [(set_attr "type" "negnot")
10212    (set_attr "mode" "SI")])
10213
10214 ;; ??? Currently never generated - xor is used instead.
10215 (define_insn "*one_cmplsi2_1_zext"
10216   [(set (match_operand:DI 0 "register_operand" "=r")
10217         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10218   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10219   "not{l}\t%k0"
10220   [(set_attr "type" "negnot")
10221    (set_attr "mode" "SI")])
10222
10223 (define_insn "*one_cmplsi2_2"
10224   [(set (reg FLAGS_REG)
10225         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10226                  (const_int 0)))
10227    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10228         (not:SI (match_dup 1)))]
10229   "ix86_match_ccmode (insn, CCNOmode)
10230    && ix86_unary_operator_ok (NOT, SImode, operands)"
10231   "#"
10232   [(set_attr "type" "alu1")
10233    (set_attr "mode" "SI")])
10234
10235 (define_split
10236   [(set (match_operand 0 "flags_reg_operand" "")
10237         (match_operator 2 "compare_operator"
10238           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10239            (const_int 0)]))
10240    (set (match_operand:SI 1 "nonimmediate_operand" "")
10241         (not:SI (match_dup 3)))]
10242   "ix86_match_ccmode (insn, CCNOmode)"
10243   [(parallel [(set (match_dup 0)
10244                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10245                                     (const_int 0)]))
10246               (set (match_dup 1)
10247                    (xor:SI (match_dup 3) (const_int -1)))])]
10248   "")
10249
10250 ;; ??? Currently never generated - xor is used instead.
10251 (define_insn "*one_cmplsi2_2_zext"
10252   [(set (reg FLAGS_REG)
10253         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10254                  (const_int 0)))
10255    (set (match_operand:DI 0 "register_operand" "=r")
10256         (zero_extend:DI (not:SI (match_dup 1))))]
10257   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10258    && ix86_unary_operator_ok (NOT, SImode, operands)"
10259   "#"
10260   [(set_attr "type" "alu1")
10261    (set_attr "mode" "SI")])
10262
10263 (define_split
10264   [(set (match_operand 0 "flags_reg_operand" "")
10265         (match_operator 2 "compare_operator"
10266           [(not:SI (match_operand:SI 3 "register_operand" ""))
10267            (const_int 0)]))
10268    (set (match_operand:DI 1 "register_operand" "")
10269         (zero_extend:DI (not:SI (match_dup 3))))]
10270   "ix86_match_ccmode (insn, CCNOmode)"
10271   [(parallel [(set (match_dup 0)
10272                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10273                                     (const_int 0)]))
10274               (set (match_dup 1)
10275                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10276   "")
10277
10278 (define_expand "one_cmplhi2"
10279   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10280         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10281   "TARGET_HIMODE_MATH"
10282   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10283
10284 (define_insn "*one_cmplhi2_1"
10285   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10286         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10287   "ix86_unary_operator_ok (NOT, HImode, operands)"
10288   "not{w}\t%0"
10289   [(set_attr "type" "negnot")
10290    (set_attr "mode" "HI")])
10291
10292 (define_insn "*one_cmplhi2_2"
10293   [(set (reg FLAGS_REG)
10294         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10295                  (const_int 0)))
10296    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10297         (not:HI (match_dup 1)))]
10298   "ix86_match_ccmode (insn, CCNOmode)
10299    && ix86_unary_operator_ok (NEG, HImode, operands)"
10300   "#"
10301   [(set_attr "type" "alu1")
10302    (set_attr "mode" "HI")])
10303
10304 (define_split
10305   [(set (match_operand 0 "flags_reg_operand" "")
10306         (match_operator 2 "compare_operator"
10307           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10308            (const_int 0)]))
10309    (set (match_operand:HI 1 "nonimmediate_operand" "")
10310         (not:HI (match_dup 3)))]
10311   "ix86_match_ccmode (insn, CCNOmode)"
10312   [(parallel [(set (match_dup 0)
10313                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10314                                     (const_int 0)]))
10315               (set (match_dup 1)
10316                    (xor:HI (match_dup 3) (const_int -1)))])]
10317   "")
10318
10319 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10320 (define_expand "one_cmplqi2"
10321   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10322         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10323   "TARGET_QIMODE_MATH"
10324   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10325
10326 (define_insn "*one_cmplqi2_1"
10327   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10328         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10329   "ix86_unary_operator_ok (NOT, QImode, operands)"
10330   "@
10331    not{b}\t%0
10332    not{l}\t%k0"
10333   [(set_attr "type" "negnot")
10334    (set_attr "mode" "QI,SI")])
10335
10336 (define_insn "*one_cmplqi2_2"
10337   [(set (reg FLAGS_REG)
10338         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10339                  (const_int 0)))
10340    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10341         (not:QI (match_dup 1)))]
10342   "ix86_match_ccmode (insn, CCNOmode)
10343    && ix86_unary_operator_ok (NOT, QImode, operands)"
10344   "#"
10345   [(set_attr "type" "alu1")
10346    (set_attr "mode" "QI")])
10347
10348 (define_split
10349   [(set (match_operand 0 "flags_reg_operand" "")
10350         (match_operator 2 "compare_operator"
10351           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10352            (const_int 0)]))
10353    (set (match_operand:QI 1 "nonimmediate_operand" "")
10354         (not:QI (match_dup 3)))]
10355   "ix86_match_ccmode (insn, CCNOmode)"
10356   [(parallel [(set (match_dup 0)
10357                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10358                                     (const_int 0)]))
10359               (set (match_dup 1)
10360                    (xor:QI (match_dup 3) (const_int -1)))])]
10361   "")
10362 \f
10363 ;; Arithmetic shift instructions
10364
10365 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10366 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10367 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10368 ;; from the assembler input.
10369 ;;
10370 ;; This instruction shifts the target reg/mem as usual, but instead of
10371 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10372 ;; is a left shift double, bits are taken from the high order bits of
10373 ;; reg, else if the insn is a shift right double, bits are taken from the
10374 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10375 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10376 ;;
10377 ;; Since sh[lr]d does not change the `reg' operand, that is done
10378 ;; separately, making all shifts emit pairs of shift double and normal
10379 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10380 ;; support a 63 bit shift, each shift where the count is in a reg expands
10381 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10382 ;;
10383 ;; If the shift count is a constant, we need never emit more than one
10384 ;; shift pair, instead using moves and sign extension for counts greater
10385 ;; than 31.
10386
10387 (define_expand "ashlti3"
10388   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10389                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10390                               (match_operand:QI 2 "nonmemory_operand" "")))
10391               (clobber (reg:CC FLAGS_REG))])]
10392   "TARGET_64BIT"
10393 {
10394   if (! immediate_operand (operands[2], QImode))
10395     {
10396       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10397       DONE;
10398     }
10399   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10400   DONE;
10401 })
10402
10403 (define_insn "ashlti3_1"
10404   [(set (match_operand:TI 0 "register_operand" "=r")
10405         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10406                    (match_operand:QI 2 "register_operand" "c")))
10407    (clobber (match_scratch:DI 3 "=&r"))
10408    (clobber (reg:CC FLAGS_REG))]
10409   "TARGET_64BIT"
10410   "#"
10411   [(set_attr "type" "multi")])
10412
10413 (define_insn "*ashlti3_2"
10414   [(set (match_operand:TI 0 "register_operand" "=r")
10415         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10416                    (match_operand:QI 2 "immediate_operand" "O")))
10417    (clobber (reg:CC FLAGS_REG))]
10418   "TARGET_64BIT"
10419   "#"
10420   [(set_attr "type" "multi")])
10421
10422 (define_split
10423   [(set (match_operand:TI 0 "register_operand" "")
10424         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10425                    (match_operand:QI 2 "register_operand" "")))
10426    (clobber (match_scratch:DI 3 ""))
10427    (clobber (reg:CC FLAGS_REG))]
10428   "TARGET_64BIT && reload_completed"
10429   [(const_int 0)]
10430   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10431
10432 (define_split
10433   [(set (match_operand:TI 0 "register_operand" "")
10434         (ashift:TI (match_operand:TI 1 "register_operand" "")
10435                    (match_operand:QI 2 "immediate_operand" "")))
10436    (clobber (reg:CC FLAGS_REG))]
10437   "TARGET_64BIT && reload_completed"
10438   [(const_int 0)]
10439   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10440
10441 (define_insn "x86_64_shld"
10442   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10443         (ior:DI (ashift:DI (match_dup 0)
10444                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10445                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10446                   (minus:QI (const_int 64) (match_dup 2)))))
10447    (clobber (reg:CC FLAGS_REG))]
10448   "TARGET_64BIT"
10449   "@
10450    shld{q}\t{%2, %1, %0|%0, %1, %2}
10451    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10452   [(set_attr "type" "ishift")
10453    (set_attr "prefix_0f" "1")
10454    (set_attr "mode" "DI")
10455    (set_attr "athlon_decode" "vector")
10456    (set_attr "amdfam10_decode" "vector")])   
10457
10458 (define_expand "x86_64_shift_adj"
10459   [(set (reg:CCZ FLAGS_REG)
10460         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10461                              (const_int 64))
10462                      (const_int 0)))
10463    (set (match_operand:DI 0 "register_operand" "")
10464         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10465                          (match_operand:DI 1 "register_operand" "")
10466                          (match_dup 0)))
10467    (set (match_dup 1)
10468         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10469                          (match_operand:DI 3 "register_operand" "r")
10470                          (match_dup 1)))]
10471   "TARGET_64BIT"
10472   "")
10473
10474 (define_expand "ashldi3"
10475   [(set (match_operand:DI 0 "shiftdi_operand" "")
10476         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10477                    (match_operand:QI 2 "nonmemory_operand" "")))]
10478   ""
10479   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10480
10481 (define_insn "*ashldi3_1_rex64"
10482   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10483         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10484                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10485    (clobber (reg:CC FLAGS_REG))]
10486   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10487 {
10488   switch (get_attr_type (insn))
10489     {
10490     case TYPE_ALU:
10491       gcc_assert (operands[2] == const1_rtx);
10492       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10493       return "add{q}\t{%0, %0|%0, %0}";
10494
10495     case TYPE_LEA:
10496       gcc_assert (CONST_INT_P (operands[2]));
10497       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10498       operands[1] = gen_rtx_MULT (DImode, operands[1],
10499                                   GEN_INT (1 << INTVAL (operands[2])));
10500       return "lea{q}\t{%a1, %0|%0, %a1}";
10501
10502     default:
10503       if (REG_P (operands[2]))
10504         return "sal{q}\t{%b2, %0|%0, %b2}";
10505       else if (operands[2] == const1_rtx
10506                && (TARGET_SHIFT1 || optimize_size))
10507         return "sal{q}\t%0";
10508       else
10509         return "sal{q}\t{%2, %0|%0, %2}";
10510     }
10511 }
10512   [(set (attr "type")
10513      (cond [(eq_attr "alternative" "1")
10514               (const_string "lea")
10515             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10516                           (const_int 0))
10517                       (match_operand 0 "register_operand" ""))
10518                  (match_operand 2 "const1_operand" ""))
10519               (const_string "alu")
10520            ]
10521            (const_string "ishift")))
10522    (set_attr "mode" "DI")])
10523
10524 ;; Convert lea to the lea pattern to avoid flags dependency.
10525 (define_split
10526   [(set (match_operand:DI 0 "register_operand" "")
10527         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10528                    (match_operand:QI 2 "immediate_operand" "")))
10529    (clobber (reg:CC FLAGS_REG))]
10530   "TARGET_64BIT && reload_completed
10531    && true_regnum (operands[0]) != true_regnum (operands[1])"
10532   [(set (match_dup 0)
10533         (mult:DI (match_dup 1)
10534                  (match_dup 2)))]
10535   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10536
10537 ;; This pattern can't accept a variable shift count, since shifts by
10538 ;; zero don't affect the flags.  We assume that shifts by constant
10539 ;; zero are optimized away.
10540 (define_insn "*ashldi3_cmp_rex64"
10541   [(set (reg FLAGS_REG)
10542         (compare
10543           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10544                      (match_operand:QI 2 "immediate_operand" "e"))
10545           (const_int 0)))
10546    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10547         (ashift:DI (match_dup 1) (match_dup 2)))]
10548   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10549    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10550    && (optimize_size
10551        || !TARGET_PARTIAL_FLAG_REG_STALL
10552        || (operands[2] == const1_rtx
10553            && (TARGET_SHIFT1
10554                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10555 {
10556   switch (get_attr_type (insn))
10557     {
10558     case TYPE_ALU:
10559       gcc_assert (operands[2] == const1_rtx);
10560       return "add{q}\t{%0, %0|%0, %0}";
10561
10562     default:
10563       if (REG_P (operands[2]))
10564         return "sal{q}\t{%b2, %0|%0, %b2}";
10565       else if (operands[2] == const1_rtx
10566                && (TARGET_SHIFT1 || optimize_size))
10567         return "sal{q}\t%0";
10568       else
10569         return "sal{q}\t{%2, %0|%0, %2}";
10570     }
10571 }
10572   [(set (attr "type")
10573      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10574                           (const_int 0))
10575                       (match_operand 0 "register_operand" ""))
10576                  (match_operand 2 "const1_operand" ""))
10577               (const_string "alu")
10578            ]
10579            (const_string "ishift")))
10580    (set_attr "mode" "DI")])
10581
10582 (define_insn "*ashldi3_cconly_rex64"
10583   [(set (reg FLAGS_REG)
10584         (compare
10585           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10586                      (match_operand:QI 2 "immediate_operand" "e"))
10587           (const_int 0)))
10588    (clobber (match_scratch:DI 0 "=r"))]
10589   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10590    && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10591    && (optimize_size
10592        || !TARGET_PARTIAL_FLAG_REG_STALL
10593        || (operands[2] == const1_rtx
10594            && (TARGET_SHIFT1
10595                || TARGET_DOUBLE_WITH_ADD)))"
10596 {
10597   switch (get_attr_type (insn))
10598     {
10599     case TYPE_ALU:
10600       gcc_assert (operands[2] == const1_rtx);
10601       return "add{q}\t{%0, %0|%0, %0}";
10602
10603     default:
10604       if (REG_P (operands[2]))
10605         return "sal{q}\t{%b2, %0|%0, %b2}";
10606       else if (operands[2] == const1_rtx
10607                && (TARGET_SHIFT1 || optimize_size))
10608         return "sal{q}\t%0";
10609       else
10610         return "sal{q}\t{%2, %0|%0, %2}";
10611     }
10612 }
10613   [(set (attr "type")
10614      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10615                           (const_int 0))
10616                       (match_operand 0 "register_operand" ""))
10617                  (match_operand 2 "const1_operand" ""))
10618               (const_string "alu")
10619            ]
10620            (const_string "ishift")))
10621    (set_attr "mode" "DI")])
10622
10623 (define_insn "*ashldi3_1"
10624   [(set (match_operand:DI 0 "register_operand" "=&r,r")
10625         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10626                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10627    (clobber (reg:CC FLAGS_REG))]
10628   "!TARGET_64BIT"
10629   "#"
10630   [(set_attr "type" "multi")])
10631
10632 ;; By default we don't ask for a scratch register, because when DImode
10633 ;; values are manipulated, registers are already at a premium.  But if
10634 ;; we have one handy, we won't turn it away.
10635 (define_peephole2
10636   [(match_scratch:SI 3 "r")
10637    (parallel [(set (match_operand:DI 0 "register_operand" "")
10638                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10639                               (match_operand:QI 2 "nonmemory_operand" "")))
10640               (clobber (reg:CC FLAGS_REG))])
10641    (match_dup 3)]
10642   "!TARGET_64BIT && TARGET_CMOVE"
10643   [(const_int 0)]
10644   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10645
10646 (define_split
10647   [(set (match_operand:DI 0 "register_operand" "")
10648         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10649                    (match_operand:QI 2 "nonmemory_operand" "")))
10650    (clobber (reg:CC FLAGS_REG))]
10651   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10652                      ? flow2_completed : reload_completed)"
10653   [(const_int 0)]
10654   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10655
10656 (define_insn "x86_shld_1"
10657   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10658         (ior:SI (ashift:SI (match_dup 0)
10659                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
10660                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10661                   (minus:QI (const_int 32) (match_dup 2)))))
10662    (clobber (reg:CC FLAGS_REG))]
10663   ""
10664   "@
10665    shld{l}\t{%2, %1, %0|%0, %1, %2}
10666    shld{l}\t{%s2%1, %0|%0, %1, %2}"
10667   [(set_attr "type" "ishift")
10668    (set_attr "prefix_0f" "1")
10669    (set_attr "mode" "SI")
10670    (set_attr "pent_pair" "np")
10671    (set_attr "athlon_decode" "vector")
10672    (set_attr "amdfam10_decode" "vector")])   
10673
10674 (define_expand "x86_shift_adj_1"
10675   [(set (reg:CCZ FLAGS_REG)
10676         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10677                              (const_int 32))
10678                      (const_int 0)))
10679    (set (match_operand:SI 0 "register_operand" "")
10680         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10681                          (match_operand:SI 1 "register_operand" "")
10682                          (match_dup 0)))
10683    (set (match_dup 1)
10684         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10685                          (match_operand:SI 3 "register_operand" "r")
10686                          (match_dup 1)))]
10687   "TARGET_CMOVE"
10688   "")
10689
10690 (define_expand "x86_shift_adj_2"
10691   [(use (match_operand:SI 0 "register_operand" ""))
10692    (use (match_operand:SI 1 "register_operand" ""))
10693    (use (match_operand:QI 2 "register_operand" ""))]
10694   ""
10695 {
10696   rtx label = gen_label_rtx ();
10697   rtx tmp;
10698
10699   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10700
10701   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10702   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10703   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10704                               gen_rtx_LABEL_REF (VOIDmode, label),
10705                               pc_rtx);
10706   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10707   JUMP_LABEL (tmp) = label;
10708
10709   emit_move_insn (operands[0], operands[1]);
10710   ix86_expand_clear (operands[1]);
10711
10712   emit_label (label);
10713   LABEL_NUSES (label) = 1;
10714
10715   DONE;
10716 })
10717
10718 (define_expand "ashlsi3"
10719   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10720         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10721                    (match_operand:QI 2 "nonmemory_operand" "")))
10722    (clobber (reg:CC FLAGS_REG))]
10723   ""
10724   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10725
10726 (define_insn "*ashlsi3_1"
10727   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10728         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10729                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10730    (clobber (reg:CC FLAGS_REG))]
10731   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10732 {
10733   switch (get_attr_type (insn))
10734     {
10735     case TYPE_ALU:
10736       gcc_assert (operands[2] == const1_rtx);
10737       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10738       return "add{l}\t{%0, %0|%0, %0}";
10739
10740     case TYPE_LEA:
10741       return "#";
10742
10743     default:
10744       if (REG_P (operands[2]))
10745         return "sal{l}\t{%b2, %0|%0, %b2}";
10746       else if (operands[2] == const1_rtx
10747                && (TARGET_SHIFT1 || optimize_size))
10748         return "sal{l}\t%0";
10749       else
10750         return "sal{l}\t{%2, %0|%0, %2}";
10751     }
10752 }
10753   [(set (attr "type")
10754      (cond [(eq_attr "alternative" "1")
10755               (const_string "lea")
10756             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10757                           (const_int 0))
10758                       (match_operand 0 "register_operand" ""))
10759                  (match_operand 2 "const1_operand" ""))
10760               (const_string "alu")
10761            ]
10762            (const_string "ishift")))
10763    (set_attr "mode" "SI")])
10764
10765 ;; Convert lea to the lea pattern to avoid flags dependency.
10766 (define_split
10767   [(set (match_operand 0 "register_operand" "")
10768         (ashift (match_operand 1 "index_register_operand" "")
10769                 (match_operand:QI 2 "const_int_operand" "")))
10770    (clobber (reg:CC FLAGS_REG))]
10771   "reload_completed
10772    && true_regnum (operands[0]) != true_regnum (operands[1])
10773    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10774   [(const_int 0)]
10775 {
10776   rtx pat;
10777   enum machine_mode mode = GET_MODE (operands[0]);
10778
10779   if (GET_MODE_SIZE (mode) < 4)
10780     operands[0] = gen_lowpart (SImode, operands[0]);
10781   if (mode != Pmode)
10782     operands[1] = gen_lowpart (Pmode, operands[1]);
10783   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10784
10785   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10786   if (Pmode != SImode)
10787     pat = gen_rtx_SUBREG (SImode, pat, 0);
10788   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10789   DONE;
10790 })
10791
10792 ;; Rare case of shifting RSP is handled by generating move and shift
10793 (define_split
10794   [(set (match_operand 0 "register_operand" "")
10795         (ashift (match_operand 1 "register_operand" "")
10796                 (match_operand:QI 2 "const_int_operand" "")))
10797    (clobber (reg:CC FLAGS_REG))]
10798   "reload_completed
10799    && true_regnum (operands[0]) != true_regnum (operands[1])"
10800   [(const_int 0)]
10801 {
10802   rtx pat, clob;
10803   emit_move_insn (operands[0], operands[1]);
10804   pat = gen_rtx_SET (VOIDmode, operands[0],
10805                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10806                                      operands[0], operands[2]));
10807   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10808   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10809   DONE;
10810 })
10811
10812 (define_insn "*ashlsi3_1_zext"
10813   [(set (match_operand:DI 0 "register_operand" "=r,r")
10814         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10815                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10816    (clobber (reg:CC FLAGS_REG))]
10817   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10818 {
10819   switch (get_attr_type (insn))
10820     {
10821     case TYPE_ALU:
10822       gcc_assert (operands[2] == const1_rtx);
10823       return "add{l}\t{%k0, %k0|%k0, %k0}";
10824
10825     case TYPE_LEA:
10826       return "#";
10827
10828     default:
10829       if (REG_P (operands[2]))
10830         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10831       else if (operands[2] == const1_rtx
10832                && (TARGET_SHIFT1 || optimize_size))
10833         return "sal{l}\t%k0";
10834       else
10835         return "sal{l}\t{%2, %k0|%k0, %2}";
10836     }
10837 }
10838   [(set (attr "type")
10839      (cond [(eq_attr "alternative" "1")
10840               (const_string "lea")
10841             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10842                      (const_int 0))
10843                  (match_operand 2 "const1_operand" ""))
10844               (const_string "alu")
10845            ]
10846            (const_string "ishift")))
10847    (set_attr "mode" "SI")])
10848
10849 ;; Convert lea to the lea pattern to avoid flags dependency.
10850 (define_split
10851   [(set (match_operand:DI 0 "register_operand" "")
10852         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10853                                 (match_operand:QI 2 "const_int_operand" ""))))
10854    (clobber (reg:CC FLAGS_REG))]
10855   "TARGET_64BIT && reload_completed
10856    && true_regnum (operands[0]) != true_regnum (operands[1])"
10857   [(set (match_dup 0) (zero_extend:DI
10858                         (subreg:SI (mult:SI (match_dup 1)
10859                                             (match_dup 2)) 0)))]
10860 {
10861   operands[1] = gen_lowpart (Pmode, operands[1]);
10862   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10863 })
10864
10865 ;; This pattern can't accept a variable shift count, since shifts by
10866 ;; zero don't affect the flags.  We assume that shifts by constant
10867 ;; zero are optimized away.
10868 (define_insn "*ashlsi3_cmp"
10869   [(set (reg FLAGS_REG)
10870         (compare
10871           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10872                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10873           (const_int 0)))
10874    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10875         (ashift:SI (match_dup 1) (match_dup 2)))]
10876   "ix86_match_ccmode (insn, CCGOCmode)
10877    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10878    && (optimize_size
10879        || !TARGET_PARTIAL_FLAG_REG_STALL
10880        || (operands[2] == const1_rtx
10881            && (TARGET_SHIFT1
10882                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10883 {
10884   switch (get_attr_type (insn))
10885     {
10886     case TYPE_ALU:
10887       gcc_assert (operands[2] == const1_rtx);
10888       return "add{l}\t{%0, %0|%0, %0}";
10889
10890     default:
10891       if (REG_P (operands[2]))
10892         return "sal{l}\t{%b2, %0|%0, %b2}";
10893       else if (operands[2] == const1_rtx
10894                && (TARGET_SHIFT1 || optimize_size))
10895         return "sal{l}\t%0";
10896       else
10897         return "sal{l}\t{%2, %0|%0, %2}";
10898     }
10899 }
10900   [(set (attr "type")
10901      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10902                           (const_int 0))
10903                       (match_operand 0 "register_operand" ""))
10904                  (match_operand 2 "const1_operand" ""))
10905               (const_string "alu")
10906            ]
10907            (const_string "ishift")))
10908    (set_attr "mode" "SI")])
10909
10910 (define_insn "*ashlsi3_cconly"
10911   [(set (reg FLAGS_REG)
10912         (compare
10913           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10914                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10915           (const_int 0)))
10916    (clobber (match_scratch:SI 0 "=r"))]
10917   "ix86_match_ccmode (insn, CCGOCmode)
10918    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10919    && (optimize_size
10920        || !TARGET_PARTIAL_FLAG_REG_STALL
10921        || (operands[2] == const1_rtx
10922            && (TARGET_SHIFT1
10923                || TARGET_DOUBLE_WITH_ADD)))"
10924 {
10925   switch (get_attr_type (insn))
10926     {
10927     case TYPE_ALU:
10928       gcc_assert (operands[2] == const1_rtx);
10929       return "add{l}\t{%0, %0|%0, %0}";
10930
10931     default:
10932       if (REG_P (operands[2]))
10933         return "sal{l}\t{%b2, %0|%0, %b2}";
10934       else if (operands[2] == const1_rtx
10935                && (TARGET_SHIFT1 || optimize_size))
10936         return "sal{l}\t%0";
10937       else
10938         return "sal{l}\t{%2, %0|%0, %2}";
10939     }
10940 }
10941   [(set (attr "type")
10942      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10943                           (const_int 0))
10944                       (match_operand 0 "register_operand" ""))
10945                  (match_operand 2 "const1_operand" ""))
10946               (const_string "alu")
10947            ]
10948            (const_string "ishift")))
10949    (set_attr "mode" "SI")])
10950
10951 (define_insn "*ashlsi3_cmp_zext"
10952   [(set (reg FLAGS_REG)
10953         (compare
10954           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10955                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10956           (const_int 0)))
10957    (set (match_operand:DI 0 "register_operand" "=r")
10958         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10959   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10960    && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10961    && (optimize_size
10962        || !TARGET_PARTIAL_FLAG_REG_STALL
10963        || (operands[2] == const1_rtx
10964            && (TARGET_SHIFT1
10965                || TARGET_DOUBLE_WITH_ADD)))"
10966 {
10967   switch (get_attr_type (insn))
10968     {
10969     case TYPE_ALU:
10970       gcc_assert (operands[2] == const1_rtx);
10971       return "add{l}\t{%k0, %k0|%k0, %k0}";
10972
10973     default:
10974       if (REG_P (operands[2]))
10975         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10976       else if (operands[2] == const1_rtx
10977                && (TARGET_SHIFT1 || optimize_size))
10978         return "sal{l}\t%k0";
10979       else
10980         return "sal{l}\t{%2, %k0|%k0, %2}";
10981     }
10982 }
10983   [(set (attr "type")
10984      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10985                      (const_int 0))
10986                  (match_operand 2 "const1_operand" ""))
10987               (const_string "alu")
10988            ]
10989            (const_string "ishift")))
10990    (set_attr "mode" "SI")])
10991
10992 (define_expand "ashlhi3"
10993   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10994         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10995                    (match_operand:QI 2 "nonmemory_operand" "")))
10996    (clobber (reg:CC FLAGS_REG))]
10997   "TARGET_HIMODE_MATH"
10998   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10999
11000 (define_insn "*ashlhi3_1_lea"
11001   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11002         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11003                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11004    (clobber (reg:CC FLAGS_REG))]
11005   "!TARGET_PARTIAL_REG_STALL
11006    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11007 {
11008   switch (get_attr_type (insn))
11009     {
11010     case TYPE_LEA:
11011       return "#";
11012     case TYPE_ALU:
11013       gcc_assert (operands[2] == const1_rtx);
11014       return "add{w}\t{%0, %0|%0, %0}";
11015
11016     default:
11017       if (REG_P (operands[2]))
11018         return "sal{w}\t{%b2, %0|%0, %b2}";
11019       else if (operands[2] == const1_rtx
11020                && (TARGET_SHIFT1 || optimize_size))
11021         return "sal{w}\t%0";
11022       else
11023         return "sal{w}\t{%2, %0|%0, %2}";
11024     }
11025 }
11026   [(set (attr "type")
11027      (cond [(eq_attr "alternative" "1")
11028               (const_string "lea")
11029             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11030                           (const_int 0))
11031                       (match_operand 0 "register_operand" ""))
11032                  (match_operand 2 "const1_operand" ""))
11033               (const_string "alu")
11034            ]
11035            (const_string "ishift")))
11036    (set_attr "mode" "HI,SI")])
11037
11038 (define_insn "*ashlhi3_1"
11039   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11040         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11041                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11042    (clobber (reg:CC FLAGS_REG))]
11043   "TARGET_PARTIAL_REG_STALL
11044    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11045 {
11046   switch (get_attr_type (insn))
11047     {
11048     case TYPE_ALU:
11049       gcc_assert (operands[2] == const1_rtx);
11050       return "add{w}\t{%0, %0|%0, %0}";
11051
11052     default:
11053       if (REG_P (operands[2]))
11054         return "sal{w}\t{%b2, %0|%0, %b2}";
11055       else if (operands[2] == const1_rtx
11056                && (TARGET_SHIFT1 || optimize_size))
11057         return "sal{w}\t%0";
11058       else
11059         return "sal{w}\t{%2, %0|%0, %2}";
11060     }
11061 }
11062   [(set (attr "type")
11063      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11064                           (const_int 0))
11065                       (match_operand 0 "register_operand" ""))
11066                  (match_operand 2 "const1_operand" ""))
11067               (const_string "alu")
11068            ]
11069            (const_string "ishift")))
11070    (set_attr "mode" "HI")])
11071
11072 ;; This pattern can't accept a variable shift count, since shifts by
11073 ;; zero don't affect the flags.  We assume that shifts by constant
11074 ;; zero are optimized away.
11075 (define_insn "*ashlhi3_cmp"
11076   [(set (reg FLAGS_REG)
11077         (compare
11078           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11079                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11080           (const_int 0)))
11081    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11082         (ashift:HI (match_dup 1) (match_dup 2)))]
11083   "ix86_match_ccmode (insn, CCGOCmode)
11084    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11085    && (optimize_size
11086        || !TARGET_PARTIAL_FLAG_REG_STALL
11087        || (operands[2] == const1_rtx
11088            && (TARGET_SHIFT1
11089                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11090 {
11091   switch (get_attr_type (insn))
11092     {
11093     case TYPE_ALU:
11094       gcc_assert (operands[2] == const1_rtx);
11095       return "add{w}\t{%0, %0|%0, %0}";
11096
11097     default:
11098       if (REG_P (operands[2]))
11099         return "sal{w}\t{%b2, %0|%0, %b2}";
11100       else if (operands[2] == const1_rtx
11101                && (TARGET_SHIFT1 || optimize_size))
11102         return "sal{w}\t%0";
11103       else
11104         return "sal{w}\t{%2, %0|%0, %2}";
11105     }
11106 }
11107   [(set (attr "type")
11108      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11109                           (const_int 0))
11110                       (match_operand 0 "register_operand" ""))
11111                  (match_operand 2 "const1_operand" ""))
11112               (const_string "alu")
11113            ]
11114            (const_string "ishift")))
11115    (set_attr "mode" "HI")])
11116
11117 (define_insn "*ashlhi3_cconly"
11118   [(set (reg FLAGS_REG)
11119         (compare
11120           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11121                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11122           (const_int 0)))
11123    (clobber (match_scratch:HI 0 "=r"))]
11124   "ix86_match_ccmode (insn, CCGOCmode)
11125    && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11126    && (optimize_size
11127        || !TARGET_PARTIAL_FLAG_REG_STALL
11128        || (operands[2] == const1_rtx
11129            && (TARGET_SHIFT1
11130                || TARGET_DOUBLE_WITH_ADD)))"
11131 {
11132   switch (get_attr_type (insn))
11133     {
11134     case TYPE_ALU:
11135       gcc_assert (operands[2] == const1_rtx);
11136       return "add{w}\t{%0, %0|%0, %0}";
11137
11138     default:
11139       if (REG_P (operands[2]))
11140         return "sal{w}\t{%b2, %0|%0, %b2}";
11141       else if (operands[2] == const1_rtx
11142                && (TARGET_SHIFT1 || optimize_size))
11143         return "sal{w}\t%0";
11144       else
11145         return "sal{w}\t{%2, %0|%0, %2}";
11146     }
11147 }
11148   [(set (attr "type")
11149      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11150                           (const_int 0))
11151                       (match_operand 0 "register_operand" ""))
11152                  (match_operand 2 "const1_operand" ""))
11153               (const_string "alu")
11154            ]
11155            (const_string "ishift")))
11156    (set_attr "mode" "HI")])
11157
11158 (define_expand "ashlqi3"
11159   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11160         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11161                    (match_operand:QI 2 "nonmemory_operand" "")))
11162    (clobber (reg:CC FLAGS_REG))]
11163   "TARGET_QIMODE_MATH"
11164   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11165
11166 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11167
11168 (define_insn "*ashlqi3_1_lea"
11169   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11170         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11171                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11172    (clobber (reg:CC FLAGS_REG))]
11173   "!TARGET_PARTIAL_REG_STALL
11174    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11175 {
11176   switch (get_attr_type (insn))
11177     {
11178     case TYPE_LEA:
11179       return "#";
11180     case TYPE_ALU:
11181       gcc_assert (operands[2] == const1_rtx);
11182       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11183         return "add{l}\t{%k0, %k0|%k0, %k0}";
11184       else
11185         return "add{b}\t{%0, %0|%0, %0}";
11186
11187     default:
11188       if (REG_P (operands[2]))
11189         {
11190           if (get_attr_mode (insn) == MODE_SI)
11191             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11192           else
11193             return "sal{b}\t{%b2, %0|%0, %b2}";
11194         }
11195       else if (operands[2] == const1_rtx
11196                && (TARGET_SHIFT1 || optimize_size))
11197         {
11198           if (get_attr_mode (insn) == MODE_SI)
11199             return "sal{l}\t%0";
11200           else
11201             return "sal{b}\t%0";
11202         }
11203       else
11204         {
11205           if (get_attr_mode (insn) == MODE_SI)
11206             return "sal{l}\t{%2, %k0|%k0, %2}";
11207           else
11208             return "sal{b}\t{%2, %0|%0, %2}";
11209         }
11210     }
11211 }
11212   [(set (attr "type")
11213      (cond [(eq_attr "alternative" "2")
11214               (const_string "lea")
11215             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11216                           (const_int 0))
11217                       (match_operand 0 "register_operand" ""))
11218                  (match_operand 2 "const1_operand" ""))
11219               (const_string "alu")
11220            ]
11221            (const_string "ishift")))
11222    (set_attr "mode" "QI,SI,SI")])
11223
11224 (define_insn "*ashlqi3_1"
11225   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11226         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11227                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11228    (clobber (reg:CC FLAGS_REG))]
11229   "TARGET_PARTIAL_REG_STALL
11230    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11231 {
11232   switch (get_attr_type (insn))
11233     {
11234     case TYPE_ALU:
11235       gcc_assert (operands[2] == const1_rtx);
11236       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11237         return "add{l}\t{%k0, %k0|%k0, %k0}";
11238       else
11239         return "add{b}\t{%0, %0|%0, %0}";
11240
11241     default:
11242       if (REG_P (operands[2]))
11243         {
11244           if (get_attr_mode (insn) == MODE_SI)
11245             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11246           else
11247             return "sal{b}\t{%b2, %0|%0, %b2}";
11248         }
11249       else if (operands[2] == const1_rtx
11250                && (TARGET_SHIFT1 || optimize_size))
11251         {
11252           if (get_attr_mode (insn) == MODE_SI)
11253             return "sal{l}\t%0";
11254           else
11255             return "sal{b}\t%0";
11256         }
11257       else
11258         {
11259           if (get_attr_mode (insn) == MODE_SI)
11260             return "sal{l}\t{%2, %k0|%k0, %2}";
11261           else
11262             return "sal{b}\t{%2, %0|%0, %2}";
11263         }
11264     }
11265 }
11266   [(set (attr "type")
11267      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11268                           (const_int 0))
11269                       (match_operand 0 "register_operand" ""))
11270                  (match_operand 2 "const1_operand" ""))
11271               (const_string "alu")
11272            ]
11273            (const_string "ishift")))
11274    (set_attr "mode" "QI,SI")])
11275
11276 ;; This pattern can't accept a variable shift count, since shifts by
11277 ;; zero don't affect the flags.  We assume that shifts by constant
11278 ;; zero are optimized away.
11279 (define_insn "*ashlqi3_cmp"
11280   [(set (reg FLAGS_REG)
11281         (compare
11282           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11283                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11284           (const_int 0)))
11285    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11286         (ashift:QI (match_dup 1) (match_dup 2)))]
11287   "ix86_match_ccmode (insn, CCGOCmode)
11288    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11289    && (optimize_size
11290        || !TARGET_PARTIAL_FLAG_REG_STALL
11291        || (operands[2] == const1_rtx
11292            && (TARGET_SHIFT1
11293                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11294 {
11295   switch (get_attr_type (insn))
11296     {
11297     case TYPE_ALU:
11298       gcc_assert (operands[2] == const1_rtx);
11299       return "add{b}\t{%0, %0|%0, %0}";
11300
11301     default:
11302       if (REG_P (operands[2]))
11303         return "sal{b}\t{%b2, %0|%0, %b2}";
11304       else if (operands[2] == const1_rtx
11305                && (TARGET_SHIFT1 || optimize_size))
11306         return "sal{b}\t%0";
11307       else
11308         return "sal{b}\t{%2, %0|%0, %2}";
11309     }
11310 }
11311   [(set (attr "type")
11312      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11313                           (const_int 0))
11314                       (match_operand 0 "register_operand" ""))
11315                  (match_operand 2 "const1_operand" ""))
11316               (const_string "alu")
11317            ]
11318            (const_string "ishift")))
11319    (set_attr "mode" "QI")])
11320
11321 (define_insn "*ashlqi3_cconly"
11322   [(set (reg FLAGS_REG)
11323         (compare
11324           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11325                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11326           (const_int 0)))
11327    (clobber (match_scratch:QI 0 "=q"))]
11328   "ix86_match_ccmode (insn, CCGOCmode)
11329    && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11330    && (optimize_size
11331        || !TARGET_PARTIAL_FLAG_REG_STALL
11332        || (operands[2] == const1_rtx
11333            && (TARGET_SHIFT1
11334                || TARGET_DOUBLE_WITH_ADD)))"
11335 {
11336   switch (get_attr_type (insn))
11337     {
11338     case TYPE_ALU:
11339       gcc_assert (operands[2] == const1_rtx);
11340       return "add{b}\t{%0, %0|%0, %0}";
11341
11342     default:
11343       if (REG_P (operands[2]))
11344         return "sal{b}\t{%b2, %0|%0, %b2}";
11345       else if (operands[2] == const1_rtx
11346                && (TARGET_SHIFT1 || optimize_size))
11347         return "sal{b}\t%0";
11348       else
11349         return "sal{b}\t{%2, %0|%0, %2}";
11350     }
11351 }
11352   [(set (attr "type")
11353      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11354                           (const_int 0))
11355                       (match_operand 0 "register_operand" ""))
11356                  (match_operand 2 "const1_operand" ""))
11357               (const_string "alu")
11358            ]
11359            (const_string "ishift")))
11360    (set_attr "mode" "QI")])
11361
11362 ;; See comment above `ashldi3' about how this works.
11363
11364 (define_expand "ashrti3"
11365   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11366                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11367                                 (match_operand:QI 2 "nonmemory_operand" "")))
11368               (clobber (reg:CC FLAGS_REG))])]
11369   "TARGET_64BIT"
11370 {
11371   if (! immediate_operand (operands[2], QImode))
11372     {
11373       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11374       DONE;
11375     }
11376   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11377   DONE;
11378 })
11379
11380 (define_insn "ashrti3_1"
11381   [(set (match_operand:TI 0 "register_operand" "=r")
11382         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11383                      (match_operand:QI 2 "register_operand" "c")))
11384    (clobber (match_scratch:DI 3 "=&r"))
11385    (clobber (reg:CC FLAGS_REG))]
11386   "TARGET_64BIT"
11387   "#"
11388   [(set_attr "type" "multi")])
11389
11390 (define_insn "*ashrti3_2"
11391   [(set (match_operand:TI 0 "register_operand" "=r")
11392         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11393                      (match_operand:QI 2 "immediate_operand" "O")))
11394    (clobber (reg:CC FLAGS_REG))]
11395   "TARGET_64BIT"
11396   "#"
11397   [(set_attr "type" "multi")])
11398
11399 (define_split
11400   [(set (match_operand:TI 0 "register_operand" "")
11401         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11402                      (match_operand:QI 2 "register_operand" "")))
11403    (clobber (match_scratch:DI 3 ""))
11404    (clobber (reg:CC FLAGS_REG))]
11405   "TARGET_64BIT && reload_completed"
11406   [(const_int 0)]
11407   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11408
11409 (define_split
11410   [(set (match_operand:TI 0 "register_operand" "")
11411         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11412                      (match_operand:QI 2 "immediate_operand" "")))
11413    (clobber (reg:CC FLAGS_REG))]
11414   "TARGET_64BIT && reload_completed"
11415   [(const_int 0)]
11416   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11417
11418 (define_insn "x86_64_shrd"
11419   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11420         (ior:DI (ashiftrt:DI (match_dup 0)
11421                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11422                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11423                   (minus:QI (const_int 64) (match_dup 2)))))
11424    (clobber (reg:CC FLAGS_REG))]
11425   "TARGET_64BIT"
11426   "@
11427    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11428    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11429   [(set_attr "type" "ishift")
11430    (set_attr "prefix_0f" "1")
11431    (set_attr "mode" "DI")
11432    (set_attr "athlon_decode" "vector")
11433    (set_attr "amdfam10_decode" "vector")])   
11434
11435 (define_expand "ashrdi3"
11436   [(set (match_operand:DI 0 "shiftdi_operand" "")
11437         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11438                      (match_operand:QI 2 "nonmemory_operand" "")))]
11439   ""
11440   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11441
11442 (define_insn "*ashrdi3_63_rex64"
11443   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11444         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11445                      (match_operand:DI 2 "const_int_operand" "i,i")))
11446    (clobber (reg:CC FLAGS_REG))]
11447   "TARGET_64BIT && INTVAL (operands[2]) == 63
11448    && (TARGET_USE_CLTD || optimize_size)
11449    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11450   "@
11451    {cqto|cqo}
11452    sar{q}\t{%2, %0|%0, %2}"
11453   [(set_attr "type" "imovx,ishift")
11454    (set_attr "prefix_0f" "0,*")
11455    (set_attr "length_immediate" "0,*")
11456    (set_attr "modrm" "0,1")
11457    (set_attr "mode" "DI")])
11458
11459 (define_insn "*ashrdi3_1_one_bit_rex64"
11460   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11461         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11462                      (match_operand:QI 2 "const1_operand" "")))
11463    (clobber (reg:CC FLAGS_REG))]
11464   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11465    && (TARGET_SHIFT1 || optimize_size)"
11466   "sar{q}\t%0"
11467   [(set_attr "type" "ishift")
11468    (set (attr "length")
11469      (if_then_else (match_operand:DI 0 "register_operand" "")
11470         (const_string "2")
11471         (const_string "*")))])
11472
11473 (define_insn "*ashrdi3_1_rex64"
11474   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11475         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11476                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11477    (clobber (reg:CC FLAGS_REG))]
11478   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11479   "@
11480    sar{q}\t{%2, %0|%0, %2}
11481    sar{q}\t{%b2, %0|%0, %b2}"
11482   [(set_attr "type" "ishift")
11483    (set_attr "mode" "DI")])
11484
11485 ;; This pattern can't accept a variable shift count, since shifts by
11486 ;; zero don't affect the flags.  We assume that shifts by constant
11487 ;; zero are optimized away.
11488 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11489   [(set (reg FLAGS_REG)
11490         (compare
11491           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11492                        (match_operand:QI 2 "const1_operand" ""))
11493           (const_int 0)))
11494    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11495         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11496   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11497    && (TARGET_SHIFT1 || optimize_size)
11498    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11499   "sar{q}\t%0"
11500   [(set_attr "type" "ishift")
11501    (set (attr "length")
11502      (if_then_else (match_operand:DI 0 "register_operand" "")
11503         (const_string "2")
11504         (const_string "*")))])
11505
11506 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11507   [(set (reg FLAGS_REG)
11508         (compare
11509           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11510                        (match_operand:QI 2 "const1_operand" ""))
11511           (const_int 0)))
11512    (clobber (match_scratch:DI 0 "=r"))]
11513   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11514    && (TARGET_SHIFT1 || optimize_size)
11515    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11516   "sar{q}\t%0"
11517   [(set_attr "type" "ishift")
11518    (set_attr "length" "2")])
11519
11520 ;; This pattern can't accept a variable shift count, since shifts by
11521 ;; zero don't affect the flags.  We assume that shifts by constant
11522 ;; zero are optimized away.
11523 (define_insn "*ashrdi3_cmp_rex64"
11524   [(set (reg FLAGS_REG)
11525         (compare
11526           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11527                        (match_operand:QI 2 "const_int_operand" "n"))
11528           (const_int 0)))
11529    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11530         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11531   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11532    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11533    && (optimize_size
11534        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11535   "sar{q}\t{%2, %0|%0, %2}"
11536   [(set_attr "type" "ishift")
11537    (set_attr "mode" "DI")])
11538
11539 (define_insn "*ashrdi3_cconly_rex64"
11540   [(set (reg FLAGS_REG)
11541         (compare
11542           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11543                        (match_operand:QI 2 "const_int_operand" "n"))
11544           (const_int 0)))
11545    (clobber (match_scratch:DI 0 "=r"))]
11546   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11547    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11548    && (optimize_size
11549        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11550   "sar{q}\t{%2, %0|%0, %2}"
11551   [(set_attr "type" "ishift")
11552    (set_attr "mode" "DI")])
11553
11554 (define_insn "*ashrdi3_1"
11555   [(set (match_operand:DI 0 "register_operand" "=r")
11556         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11557                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11558    (clobber (reg:CC FLAGS_REG))]
11559   "!TARGET_64BIT"
11560   "#"
11561   [(set_attr "type" "multi")])
11562
11563 ;; By default we don't ask for a scratch register, because when DImode
11564 ;; values are manipulated, registers are already at a premium.  But if
11565 ;; we have one handy, we won't turn it away.
11566 (define_peephole2
11567   [(match_scratch:SI 3 "r")
11568    (parallel [(set (match_operand:DI 0 "register_operand" "")
11569                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11570                                 (match_operand:QI 2 "nonmemory_operand" "")))
11571               (clobber (reg:CC FLAGS_REG))])
11572    (match_dup 3)]
11573   "!TARGET_64BIT && TARGET_CMOVE"
11574   [(const_int 0)]
11575   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11576
11577 (define_split
11578   [(set (match_operand:DI 0 "register_operand" "")
11579         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11580                      (match_operand:QI 2 "nonmemory_operand" "")))
11581    (clobber (reg:CC FLAGS_REG))]
11582   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11583                      ? flow2_completed : reload_completed)"
11584   [(const_int 0)]
11585   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11586
11587 (define_insn "x86_shrd_1"
11588   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11589         (ior:SI (ashiftrt:SI (match_dup 0)
11590                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11591                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11592                   (minus:QI (const_int 32) (match_dup 2)))))
11593    (clobber (reg:CC FLAGS_REG))]
11594   ""
11595   "@
11596    shrd{l}\t{%2, %1, %0|%0, %1, %2}
11597    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11598   [(set_attr "type" "ishift")
11599    (set_attr "prefix_0f" "1")
11600    (set_attr "pent_pair" "np")
11601    (set_attr "mode" "SI")])
11602
11603 (define_expand "x86_shift_adj_3"
11604   [(use (match_operand:SI 0 "register_operand" ""))
11605    (use (match_operand:SI 1 "register_operand" ""))
11606    (use (match_operand:QI 2 "register_operand" ""))]
11607   ""
11608 {
11609   rtx label = gen_label_rtx ();
11610   rtx tmp;
11611
11612   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11613
11614   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11615   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11616   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11617                               gen_rtx_LABEL_REF (VOIDmode, label),
11618                               pc_rtx);
11619   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11620   JUMP_LABEL (tmp) = label;
11621
11622   emit_move_insn (operands[0], operands[1]);
11623   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11624
11625   emit_label (label);
11626   LABEL_NUSES (label) = 1;
11627
11628   DONE;
11629 })
11630
11631 (define_insn "ashrsi3_31"
11632   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11633         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11634                      (match_operand:SI 2 "const_int_operand" "i,i")))
11635    (clobber (reg:CC FLAGS_REG))]
11636   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11637    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11638   "@
11639    {cltd|cdq}
11640    sar{l}\t{%2, %0|%0, %2}"
11641   [(set_attr "type" "imovx,ishift")
11642    (set_attr "prefix_0f" "0,*")
11643    (set_attr "length_immediate" "0,*")
11644    (set_attr "modrm" "0,1")
11645    (set_attr "mode" "SI")])
11646
11647 (define_insn "*ashrsi3_31_zext"
11648   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11649         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11650                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11651    (clobber (reg:CC FLAGS_REG))]
11652   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11653    && INTVAL (operands[2]) == 31
11654    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11655   "@
11656    {cltd|cdq}
11657    sar{l}\t{%2, %k0|%k0, %2}"
11658   [(set_attr "type" "imovx,ishift")
11659    (set_attr "prefix_0f" "0,*")
11660    (set_attr "length_immediate" "0,*")
11661    (set_attr "modrm" "0,1")
11662    (set_attr "mode" "SI")])
11663
11664 (define_expand "ashrsi3"
11665   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11666         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11667                      (match_operand:QI 2 "nonmemory_operand" "")))
11668    (clobber (reg:CC FLAGS_REG))]
11669   ""
11670   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11671
11672 (define_insn "*ashrsi3_1_one_bit"
11673   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11674         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11675                      (match_operand:QI 2 "const1_operand" "")))
11676    (clobber (reg:CC FLAGS_REG))]
11677   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11678    && (TARGET_SHIFT1 || optimize_size)"
11679   "sar{l}\t%0"
11680   [(set_attr "type" "ishift")
11681    (set (attr "length")
11682      (if_then_else (match_operand:SI 0 "register_operand" "")
11683         (const_string "2")
11684         (const_string "*")))])
11685
11686 (define_insn "*ashrsi3_1_one_bit_zext"
11687   [(set (match_operand:DI 0 "register_operand" "=r")
11688         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11689                                      (match_operand:QI 2 "const1_operand" ""))))
11690    (clobber (reg:CC FLAGS_REG))]
11691   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11692    && (TARGET_SHIFT1 || optimize_size)"
11693   "sar{l}\t%k0"
11694   [(set_attr "type" "ishift")
11695    (set_attr "length" "2")])
11696
11697 (define_insn "*ashrsi3_1"
11698   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11699         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11700                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11701    (clobber (reg:CC FLAGS_REG))]
11702   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11703   "@
11704    sar{l}\t{%2, %0|%0, %2}
11705    sar{l}\t{%b2, %0|%0, %b2}"
11706   [(set_attr "type" "ishift")
11707    (set_attr "mode" "SI")])
11708
11709 (define_insn "*ashrsi3_1_zext"
11710   [(set (match_operand:DI 0 "register_operand" "=r,r")
11711         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11712                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11713    (clobber (reg:CC FLAGS_REG))]
11714   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11715   "@
11716    sar{l}\t{%2, %k0|%k0, %2}
11717    sar{l}\t{%b2, %k0|%k0, %b2}"
11718   [(set_attr "type" "ishift")
11719    (set_attr "mode" "SI")])
11720
11721 ;; This pattern can't accept a variable shift count, since shifts by
11722 ;; zero don't affect the flags.  We assume that shifts by constant
11723 ;; zero are optimized away.
11724 (define_insn "*ashrsi3_one_bit_cmp"
11725   [(set (reg FLAGS_REG)
11726         (compare
11727           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11728                        (match_operand:QI 2 "const1_operand" ""))
11729           (const_int 0)))
11730    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11731         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11732   "ix86_match_ccmode (insn, CCGOCmode)
11733    && (TARGET_SHIFT1 || optimize_size)
11734    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11735   "sar{l}\t%0"
11736   [(set_attr "type" "ishift")
11737    (set (attr "length")
11738      (if_then_else (match_operand:SI 0 "register_operand" "")
11739         (const_string "2")
11740         (const_string "*")))])
11741
11742 (define_insn "*ashrsi3_one_bit_cconly"
11743   [(set (reg FLAGS_REG)
11744         (compare
11745           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11746                        (match_operand:QI 2 "const1_operand" ""))
11747           (const_int 0)))
11748    (clobber (match_scratch:SI 0 "=r"))]
11749   "ix86_match_ccmode (insn, CCGOCmode)
11750    && (TARGET_SHIFT1 || optimize_size)
11751    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11752   "sar{l}\t%0"
11753   [(set_attr "type" "ishift")
11754    (set_attr "length" "2")])
11755
11756 (define_insn "*ashrsi3_one_bit_cmp_zext"
11757   [(set (reg FLAGS_REG)
11758         (compare
11759           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11760                        (match_operand:QI 2 "const1_operand" ""))
11761           (const_int 0)))
11762    (set (match_operand:DI 0 "register_operand" "=r")
11763         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11764   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11765    && (TARGET_SHIFT1 || optimize_size)
11766    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11767   "sar{l}\t%k0"
11768   [(set_attr "type" "ishift")
11769    (set_attr "length" "2")])
11770
11771 ;; This pattern can't accept a variable shift count, since shifts by
11772 ;; zero don't affect the flags.  We assume that shifts by constant
11773 ;; zero are optimized away.
11774 (define_insn "*ashrsi3_cmp"
11775   [(set (reg FLAGS_REG)
11776         (compare
11777           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11778                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11779           (const_int 0)))
11780    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11781         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11782   "ix86_match_ccmode (insn, CCGOCmode)
11783    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11784    && (optimize_size
11785        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11786   "sar{l}\t{%2, %0|%0, %2}"
11787   [(set_attr "type" "ishift")
11788    (set_attr "mode" "SI")])
11789
11790 (define_insn "*ashrsi3_cconly"
11791   [(set (reg FLAGS_REG)
11792         (compare
11793           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11794                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11795           (const_int 0)))
11796    (clobber (match_scratch:SI 0 "=r"))]
11797   "ix86_match_ccmode (insn, CCGOCmode)
11798    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11799    && (optimize_size
11800        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11801   "sar{l}\t{%2, %0|%0, %2}"
11802   [(set_attr "type" "ishift")
11803    (set_attr "mode" "SI")])
11804
11805 (define_insn "*ashrsi3_cmp_zext"
11806   [(set (reg FLAGS_REG)
11807         (compare
11808           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11809                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11810           (const_int 0)))
11811    (set (match_operand:DI 0 "register_operand" "=r")
11812         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11813   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11814    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11815    && (optimize_size
11816        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11817   "sar{l}\t{%2, %k0|%k0, %2}"
11818   [(set_attr "type" "ishift")
11819    (set_attr "mode" "SI")])
11820
11821 (define_expand "ashrhi3"
11822   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11823         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11824                      (match_operand:QI 2 "nonmemory_operand" "")))
11825    (clobber (reg:CC FLAGS_REG))]
11826   "TARGET_HIMODE_MATH"
11827   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11828
11829 (define_insn "*ashrhi3_1_one_bit"
11830   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11831         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11832                      (match_operand:QI 2 "const1_operand" "")))
11833    (clobber (reg:CC FLAGS_REG))]
11834   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11835    && (TARGET_SHIFT1 || optimize_size)"
11836   "sar{w}\t%0"
11837   [(set_attr "type" "ishift")
11838    (set (attr "length")
11839      (if_then_else (match_operand 0 "register_operand" "")
11840         (const_string "2")
11841         (const_string "*")))])
11842
11843 (define_insn "*ashrhi3_1"
11844   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11845         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11846                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11847    (clobber (reg:CC FLAGS_REG))]
11848   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11849   "@
11850    sar{w}\t{%2, %0|%0, %2}
11851    sar{w}\t{%b2, %0|%0, %b2}"
11852   [(set_attr "type" "ishift")
11853    (set_attr "mode" "HI")])
11854
11855 ;; This pattern can't accept a variable shift count, since shifts by
11856 ;; zero don't affect the flags.  We assume that shifts by constant
11857 ;; zero are optimized away.
11858 (define_insn "*ashrhi3_one_bit_cmp"
11859   [(set (reg FLAGS_REG)
11860         (compare
11861           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11862                        (match_operand:QI 2 "const1_operand" ""))
11863           (const_int 0)))
11864    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11865         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11866   "ix86_match_ccmode (insn, CCGOCmode)
11867    && (TARGET_SHIFT1 || optimize_size)
11868    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11869   "sar{w}\t%0"
11870   [(set_attr "type" "ishift")
11871    (set (attr "length")
11872      (if_then_else (match_operand 0 "register_operand" "")
11873         (const_string "2")
11874         (const_string "*")))])
11875
11876 (define_insn "*ashrhi3_one_bit_cconly"
11877   [(set (reg FLAGS_REG)
11878         (compare
11879           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11880                        (match_operand:QI 2 "const1_operand" ""))
11881           (const_int 0)))
11882    (clobber (match_scratch:HI 0 "=r"))]
11883   "ix86_match_ccmode (insn, CCGOCmode)
11884    && (TARGET_SHIFT1 || optimize_size)
11885    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11886   "sar{w}\t%0"
11887   [(set_attr "type" "ishift")
11888    (set_attr "length" "2")])
11889
11890 ;; This pattern can't accept a variable shift count, since shifts by
11891 ;; zero don't affect the flags.  We assume that shifts by constant
11892 ;; zero are optimized away.
11893 (define_insn "*ashrhi3_cmp"
11894   [(set (reg FLAGS_REG)
11895         (compare
11896           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11897                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11898           (const_int 0)))
11899    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11900         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11901   "ix86_match_ccmode (insn, CCGOCmode)
11902    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11903    && (optimize_size
11904        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11905   "sar{w}\t{%2, %0|%0, %2}"
11906   [(set_attr "type" "ishift")
11907    (set_attr "mode" "HI")])
11908
11909 (define_insn "*ashrhi3_cconly"
11910   [(set (reg FLAGS_REG)
11911         (compare
11912           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11913                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11914           (const_int 0)))
11915    (clobber (match_scratch:HI 0 "=r"))]
11916   "ix86_match_ccmode (insn, CCGOCmode)
11917    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11918    && (optimize_size
11919        || !TARGET_PARTIAL_FLAG_REG_STALL)"
11920   "sar{w}\t{%2, %0|%0, %2}"
11921   [(set_attr "type" "ishift")
11922    (set_attr "mode" "HI")])
11923
11924 (define_expand "ashrqi3"
11925   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11926         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11927                      (match_operand:QI 2 "nonmemory_operand" "")))
11928    (clobber (reg:CC FLAGS_REG))]
11929   "TARGET_QIMODE_MATH"
11930   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11931
11932 (define_insn "*ashrqi3_1_one_bit"
11933   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11934         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11935                      (match_operand:QI 2 "const1_operand" "")))
11936    (clobber (reg:CC FLAGS_REG))]
11937   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11938    && (TARGET_SHIFT1 || optimize_size)"
11939   "sar{b}\t%0"
11940   [(set_attr "type" "ishift")
11941    (set (attr "length")
11942      (if_then_else (match_operand 0 "register_operand" "")
11943         (const_string "2")
11944         (const_string "*")))])
11945
11946 (define_insn "*ashrqi3_1_one_bit_slp"
11947   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11948         (ashiftrt:QI (match_dup 0)
11949                      (match_operand:QI 1 "const1_operand" "")))
11950    (clobber (reg:CC FLAGS_REG))]
11951   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11952    && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11953    && (TARGET_SHIFT1 || optimize_size)"
11954   "sar{b}\t%0"
11955   [(set_attr "type" "ishift1")
11956    (set (attr "length")
11957      (if_then_else (match_operand 0 "register_operand" "")
11958         (const_string "2")
11959         (const_string "*")))])
11960
11961 (define_insn "*ashrqi3_1"
11962   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11963         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11964                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11965    (clobber (reg:CC FLAGS_REG))]
11966   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11967   "@
11968    sar{b}\t{%2, %0|%0, %2}
11969    sar{b}\t{%b2, %0|%0, %b2}"
11970   [(set_attr "type" "ishift")
11971    (set_attr "mode" "QI")])
11972
11973 (define_insn "*ashrqi3_1_slp"
11974   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11975         (ashiftrt:QI (match_dup 0)
11976                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11977    (clobber (reg:CC FLAGS_REG))]
11978   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11979    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11980   "@
11981    sar{b}\t{%1, %0|%0, %1}
11982    sar{b}\t{%b1, %0|%0, %b1}"
11983   [(set_attr "type" "ishift1")
11984    (set_attr "mode" "QI")])
11985
11986 ;; This pattern can't accept a variable shift count, since shifts by
11987 ;; zero don't affect the flags.  We assume that shifts by constant
11988 ;; zero are optimized away.
11989 (define_insn "*ashrqi3_one_bit_cmp"
11990   [(set (reg FLAGS_REG)
11991         (compare
11992           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11993                        (match_operand:QI 2 "const1_operand" "I"))
11994           (const_int 0)))
11995    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11996         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11997   "ix86_match_ccmode (insn, CCGOCmode)
11998    && (TARGET_SHIFT1 || optimize_size)
11999    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12000   "sar{b}\t%0"
12001   [(set_attr "type" "ishift")
12002    (set (attr "length")
12003      (if_then_else (match_operand 0 "register_operand" "")
12004         (const_string "2")
12005         (const_string "*")))])
12006
12007 (define_insn "*ashrqi3_one_bit_cconly"
12008   [(set (reg FLAGS_REG)
12009         (compare
12010           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12011                        (match_operand:QI 2 "const1_operand" "I"))
12012           (const_int 0)))
12013    (clobber (match_scratch:QI 0 "=q"))]
12014   "ix86_match_ccmode (insn, CCGOCmode)
12015    && (TARGET_SHIFT1 || optimize_size)
12016    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12017   "sar{b}\t%0"
12018   [(set_attr "type" "ishift")
12019    (set_attr "length" "2")])
12020
12021 ;; This pattern can't accept a variable shift count, since shifts by
12022 ;; zero don't affect the flags.  We assume that shifts by constant
12023 ;; zero are optimized away.
12024 (define_insn "*ashrqi3_cmp"
12025   [(set (reg FLAGS_REG)
12026         (compare
12027           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12028                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12029           (const_int 0)))
12030    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12031         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12032   "ix86_match_ccmode (insn, CCGOCmode)
12033    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12034    && (optimize_size
12035        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12036   "sar{b}\t{%2, %0|%0, %2}"
12037   [(set_attr "type" "ishift")
12038    (set_attr "mode" "QI")])
12039
12040 (define_insn "*ashrqi3_cconly"
12041   [(set (reg FLAGS_REG)
12042         (compare
12043           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12044                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12045           (const_int 0)))
12046    (clobber (match_scratch:QI 0 "=q"))]
12047   "ix86_match_ccmode (insn, CCGOCmode)
12048    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12049    && (optimize_size
12050        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12051   "sar{b}\t{%2, %0|%0, %2}"
12052   [(set_attr "type" "ishift")
12053    (set_attr "mode" "QI")])
12054
12055 \f
12056 ;; Logical shift instructions
12057
12058 ;; See comment above `ashldi3' about how this works.
12059
12060 (define_expand "lshrti3"
12061   [(parallel [(set (match_operand:TI 0 "register_operand" "")
12062                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12063                                 (match_operand:QI 2 "nonmemory_operand" "")))
12064               (clobber (reg:CC FLAGS_REG))])]
12065   "TARGET_64BIT"
12066 {
12067   if (! immediate_operand (operands[2], QImode))
12068     {
12069       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12070       DONE;
12071     }
12072   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12073   DONE;
12074 })
12075
12076 (define_insn "lshrti3_1"
12077   [(set (match_operand:TI 0 "register_operand" "=r")
12078         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12079                      (match_operand:QI 2 "register_operand" "c")))
12080    (clobber (match_scratch:DI 3 "=&r"))
12081    (clobber (reg:CC FLAGS_REG))]
12082   "TARGET_64BIT"
12083   "#"
12084   [(set_attr "type" "multi")])
12085
12086 (define_insn "*lshrti3_2"
12087   [(set (match_operand:TI 0 "register_operand" "=r")
12088         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12089                      (match_operand:QI 2 "immediate_operand" "O")))
12090    (clobber (reg:CC FLAGS_REG))]
12091   "TARGET_64BIT"
12092   "#"
12093   [(set_attr "type" "multi")])
12094
12095 (define_split
12096   [(set (match_operand:TI 0 "register_operand" "")
12097         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12098                      (match_operand:QI 2 "register_operand" "")))
12099    (clobber (match_scratch:DI 3 ""))
12100    (clobber (reg:CC FLAGS_REG))]
12101   "TARGET_64BIT && reload_completed"
12102   [(const_int 0)]
12103   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12104
12105 (define_split
12106   [(set (match_operand:TI 0 "register_operand" "")
12107         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12108                      (match_operand:QI 2 "immediate_operand" "")))
12109    (clobber (reg:CC FLAGS_REG))]
12110   "TARGET_64BIT && reload_completed"
12111   [(const_int 0)]
12112   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12113
12114 (define_expand "lshrdi3"
12115   [(set (match_operand:DI 0 "shiftdi_operand" "")
12116         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12117                      (match_operand:QI 2 "nonmemory_operand" "")))]
12118   ""
12119   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12120
12121 (define_insn "*lshrdi3_1_one_bit_rex64"
12122   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12123         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12124                      (match_operand:QI 2 "const1_operand" "")))
12125    (clobber (reg:CC FLAGS_REG))]
12126   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12127    && (TARGET_SHIFT1 || optimize_size)"
12128   "shr{q}\t%0"
12129   [(set_attr "type" "ishift")
12130    (set (attr "length")
12131      (if_then_else (match_operand:DI 0 "register_operand" "")
12132         (const_string "2")
12133         (const_string "*")))])
12134
12135 (define_insn "*lshrdi3_1_rex64"
12136   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12137         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12138                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12139    (clobber (reg:CC FLAGS_REG))]
12140   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12141   "@
12142    shr{q}\t{%2, %0|%0, %2}
12143    shr{q}\t{%b2, %0|%0, %b2}"
12144   [(set_attr "type" "ishift")
12145    (set_attr "mode" "DI")])
12146
12147 ;; This pattern can't accept a variable shift count, since shifts by
12148 ;; zero don't affect the flags.  We assume that shifts by constant
12149 ;; zero are optimized away.
12150 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12151   [(set (reg FLAGS_REG)
12152         (compare
12153           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12154                        (match_operand:QI 2 "const1_operand" ""))
12155           (const_int 0)))
12156    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12157         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12158   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12159    && (TARGET_SHIFT1 || optimize_size)
12160    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12161   "shr{q}\t%0"
12162   [(set_attr "type" "ishift")
12163    (set (attr "length")
12164      (if_then_else (match_operand:DI 0 "register_operand" "")
12165         (const_string "2")
12166         (const_string "*")))])
12167
12168 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12169   [(set (reg FLAGS_REG)
12170         (compare
12171           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12172                        (match_operand:QI 2 "const1_operand" ""))
12173           (const_int 0)))
12174    (clobber (match_scratch:DI 0 "=r"))]
12175   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12176    && (TARGET_SHIFT1 || optimize_size)
12177    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12178   "shr{q}\t%0"
12179   [(set_attr "type" "ishift")
12180    (set_attr "length" "2")])
12181
12182 ;; This pattern can't accept a variable shift count, since shifts by
12183 ;; zero don't affect the flags.  We assume that shifts by constant
12184 ;; zero are optimized away.
12185 (define_insn "*lshrdi3_cmp_rex64"
12186   [(set (reg FLAGS_REG)
12187         (compare
12188           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12189                        (match_operand:QI 2 "const_int_operand" "e"))
12190           (const_int 0)))
12191    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12192         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12193   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12194    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12195    && (optimize_size
12196        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12197   "shr{q}\t{%2, %0|%0, %2}"
12198   [(set_attr "type" "ishift")
12199    (set_attr "mode" "DI")])
12200
12201 (define_insn "*lshrdi3_cconly_rex64"
12202   [(set (reg FLAGS_REG)
12203         (compare
12204           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12205                        (match_operand:QI 2 "const_int_operand" "e"))
12206           (const_int 0)))
12207    (clobber (match_scratch:DI 0 "=r"))]
12208   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12209    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12210    && (optimize_size
12211        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12212   "shr{q}\t{%2, %0|%0, %2}"
12213   [(set_attr "type" "ishift")
12214    (set_attr "mode" "DI")])
12215
12216 (define_insn "*lshrdi3_1"
12217   [(set (match_operand:DI 0 "register_operand" "=r")
12218         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12219                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12220    (clobber (reg:CC FLAGS_REG))]
12221   "!TARGET_64BIT"
12222   "#"
12223   [(set_attr "type" "multi")])
12224
12225 ;; By default we don't ask for a scratch register, because when DImode
12226 ;; values are manipulated, registers are already at a premium.  But if
12227 ;; we have one handy, we won't turn it away.
12228 (define_peephole2
12229   [(match_scratch:SI 3 "r")
12230    (parallel [(set (match_operand:DI 0 "register_operand" "")
12231                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12232                                 (match_operand:QI 2 "nonmemory_operand" "")))
12233               (clobber (reg:CC FLAGS_REG))])
12234    (match_dup 3)]
12235   "!TARGET_64BIT && TARGET_CMOVE"
12236   [(const_int 0)]
12237   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12238
12239 (define_split
12240   [(set (match_operand:DI 0 "register_operand" "")
12241         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12242                      (match_operand:QI 2 "nonmemory_operand" "")))
12243    (clobber (reg:CC FLAGS_REG))]
12244   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12245                      ? flow2_completed : reload_completed)"
12246   [(const_int 0)]
12247   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12248
12249 (define_expand "lshrsi3"
12250   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12251         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12252                      (match_operand:QI 2 "nonmemory_operand" "")))
12253    (clobber (reg:CC FLAGS_REG))]
12254   ""
12255   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12256
12257 (define_insn "*lshrsi3_1_one_bit"
12258   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12259         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12260                      (match_operand:QI 2 "const1_operand" "")))
12261    (clobber (reg:CC FLAGS_REG))]
12262   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12263    && (TARGET_SHIFT1 || optimize_size)"
12264   "shr{l}\t%0"
12265   [(set_attr "type" "ishift")
12266    (set (attr "length")
12267      (if_then_else (match_operand:SI 0 "register_operand" "")
12268         (const_string "2")
12269         (const_string "*")))])
12270
12271 (define_insn "*lshrsi3_1_one_bit_zext"
12272   [(set (match_operand:DI 0 "register_operand" "=r")
12273         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12274                      (match_operand:QI 2 "const1_operand" "")))
12275    (clobber (reg:CC FLAGS_REG))]
12276   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12277    && (TARGET_SHIFT1 || optimize_size)"
12278   "shr{l}\t%k0"
12279   [(set_attr "type" "ishift")
12280    (set_attr "length" "2")])
12281
12282 (define_insn "*lshrsi3_1"
12283   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12284         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12285                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12286    (clobber (reg:CC FLAGS_REG))]
12287   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12288   "@
12289    shr{l}\t{%2, %0|%0, %2}
12290    shr{l}\t{%b2, %0|%0, %b2}"
12291   [(set_attr "type" "ishift")
12292    (set_attr "mode" "SI")])
12293
12294 (define_insn "*lshrsi3_1_zext"
12295   [(set (match_operand:DI 0 "register_operand" "=r,r")
12296         (zero_extend:DI
12297           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12298                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12299    (clobber (reg:CC FLAGS_REG))]
12300   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12301   "@
12302    shr{l}\t{%2, %k0|%k0, %2}
12303    shr{l}\t{%b2, %k0|%k0, %b2}"
12304   [(set_attr "type" "ishift")
12305    (set_attr "mode" "SI")])
12306
12307 ;; This pattern can't accept a variable shift count, since shifts by
12308 ;; zero don't affect the flags.  We assume that shifts by constant
12309 ;; zero are optimized away.
12310 (define_insn "*lshrsi3_one_bit_cmp"
12311   [(set (reg FLAGS_REG)
12312         (compare
12313           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12314                        (match_operand:QI 2 "const1_operand" ""))
12315           (const_int 0)))
12316    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12317         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12318   "ix86_match_ccmode (insn, CCGOCmode)
12319    && (TARGET_SHIFT1 || optimize_size)
12320    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12321   "shr{l}\t%0"
12322   [(set_attr "type" "ishift")
12323    (set (attr "length")
12324      (if_then_else (match_operand:SI 0 "register_operand" "")
12325         (const_string "2")
12326         (const_string "*")))])
12327
12328 (define_insn "*lshrsi3_one_bit_cconly"
12329   [(set (reg FLAGS_REG)
12330         (compare
12331           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12332                        (match_operand:QI 2 "const1_operand" ""))
12333           (const_int 0)))
12334    (clobber (match_scratch:SI 0 "=r"))]
12335   "ix86_match_ccmode (insn, CCGOCmode)
12336    && (TARGET_SHIFT1 || optimize_size)
12337    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12338   "shr{l}\t%0"
12339   [(set_attr "type" "ishift")
12340    (set_attr "length" "2")])
12341
12342 (define_insn "*lshrsi3_cmp_one_bit_zext"
12343   [(set (reg FLAGS_REG)
12344         (compare
12345           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12346                        (match_operand:QI 2 "const1_operand" ""))
12347           (const_int 0)))
12348    (set (match_operand:DI 0 "register_operand" "=r")
12349         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12350   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12351    && (TARGET_SHIFT1 || optimize_size)
12352    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12353   "shr{l}\t%k0"
12354   [(set_attr "type" "ishift")
12355    (set_attr "length" "2")])
12356
12357 ;; This pattern can't accept a variable shift count, since shifts by
12358 ;; zero don't affect the flags.  We assume that shifts by constant
12359 ;; zero are optimized away.
12360 (define_insn "*lshrsi3_cmp"
12361   [(set (reg FLAGS_REG)
12362         (compare
12363           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12364                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12365           (const_int 0)))
12366    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12367         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12368   "ix86_match_ccmode (insn, CCGOCmode)
12369    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12370    && (optimize_size
12371        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12372   "shr{l}\t{%2, %0|%0, %2}"
12373   [(set_attr "type" "ishift")
12374    (set_attr "mode" "SI")])
12375
12376 (define_insn "*lshrsi3_cconly"
12377   [(set (reg FLAGS_REG)
12378       (compare
12379         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12380                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12381         (const_int 0)))
12382    (clobber (match_scratch:SI 0 "=r"))]
12383   "ix86_match_ccmode (insn, CCGOCmode)
12384    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12385    && (optimize_size
12386        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12387   "shr{l}\t{%2, %0|%0, %2}"
12388   [(set_attr "type" "ishift")
12389    (set_attr "mode" "SI")])
12390
12391 (define_insn "*lshrsi3_cmp_zext"
12392   [(set (reg FLAGS_REG)
12393         (compare
12394           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12395                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12396           (const_int 0)))
12397    (set (match_operand:DI 0 "register_operand" "=r")
12398         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12399   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12400    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12401    && (optimize_size
12402        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12403   "shr{l}\t{%2, %k0|%k0, %2}"
12404   [(set_attr "type" "ishift")
12405    (set_attr "mode" "SI")])
12406
12407 (define_expand "lshrhi3"
12408   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12409         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12410                      (match_operand:QI 2 "nonmemory_operand" "")))
12411    (clobber (reg:CC FLAGS_REG))]
12412   "TARGET_HIMODE_MATH"
12413   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12414
12415 (define_insn "*lshrhi3_1_one_bit"
12416   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12417         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12418                      (match_operand:QI 2 "const1_operand" "")))
12419    (clobber (reg:CC FLAGS_REG))]
12420   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12421    && (TARGET_SHIFT1 || optimize_size)"
12422   "shr{w}\t%0"
12423   [(set_attr "type" "ishift")
12424    (set (attr "length")
12425      (if_then_else (match_operand 0 "register_operand" "")
12426         (const_string "2")
12427         (const_string "*")))])
12428
12429 (define_insn "*lshrhi3_1"
12430   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12431         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12432                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12433    (clobber (reg:CC FLAGS_REG))]
12434   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12435   "@
12436    shr{w}\t{%2, %0|%0, %2}
12437    shr{w}\t{%b2, %0|%0, %b2}"
12438   [(set_attr "type" "ishift")
12439    (set_attr "mode" "HI")])
12440
12441 ;; This pattern can't accept a variable shift count, since shifts by
12442 ;; zero don't affect the flags.  We assume that shifts by constant
12443 ;; zero are optimized away.
12444 (define_insn "*lshrhi3_one_bit_cmp"
12445   [(set (reg FLAGS_REG)
12446         (compare
12447           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12448                        (match_operand:QI 2 "const1_operand" ""))
12449           (const_int 0)))
12450    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12451         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12452   "ix86_match_ccmode (insn, CCGOCmode)
12453    && (TARGET_SHIFT1 || optimize_size)
12454    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12455   "shr{w}\t%0"
12456   [(set_attr "type" "ishift")
12457    (set (attr "length")
12458      (if_then_else (match_operand:SI 0 "register_operand" "")
12459         (const_string "2")
12460         (const_string "*")))])
12461
12462 (define_insn "*lshrhi3_one_bit_cconly"
12463   [(set (reg FLAGS_REG)
12464         (compare
12465           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12466                        (match_operand:QI 2 "const1_operand" ""))
12467           (const_int 0)))
12468    (clobber (match_scratch:HI 0 "=r"))]
12469   "ix86_match_ccmode (insn, CCGOCmode)
12470    && (TARGET_SHIFT1 || optimize_size)
12471    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12472   "shr{w}\t%0"
12473   [(set_attr "type" "ishift")
12474    (set_attr "length" "2")])
12475
12476 ;; This pattern can't accept a variable shift count, since shifts by
12477 ;; zero don't affect the flags.  We assume that shifts by constant
12478 ;; zero are optimized away.
12479 (define_insn "*lshrhi3_cmp"
12480   [(set (reg FLAGS_REG)
12481         (compare
12482           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12483                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12484           (const_int 0)))
12485    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12486         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12487   "ix86_match_ccmode (insn, CCGOCmode)
12488    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12489    && (optimize_size
12490        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12491   "shr{w}\t{%2, %0|%0, %2}"
12492   [(set_attr "type" "ishift")
12493    (set_attr "mode" "HI")])
12494
12495 (define_insn "*lshrhi3_cconly"
12496   [(set (reg FLAGS_REG)
12497         (compare
12498           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12499                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12500           (const_int 0)))
12501    (clobber (match_scratch:HI 0 "=r"))]
12502   "ix86_match_ccmode (insn, CCGOCmode)
12503    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12504    && (optimize_size
12505        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12506   "shr{w}\t{%2, %0|%0, %2}"
12507   [(set_attr "type" "ishift")
12508    (set_attr "mode" "HI")])
12509
12510 (define_expand "lshrqi3"
12511   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12512         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12513                      (match_operand:QI 2 "nonmemory_operand" "")))
12514    (clobber (reg:CC FLAGS_REG))]
12515   "TARGET_QIMODE_MATH"
12516   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12517
12518 (define_insn "*lshrqi3_1_one_bit"
12519   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12520         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12521                      (match_operand:QI 2 "const1_operand" "")))
12522    (clobber (reg:CC FLAGS_REG))]
12523   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12524    && (TARGET_SHIFT1 || optimize_size)"
12525   "shr{b}\t%0"
12526   [(set_attr "type" "ishift")
12527    (set (attr "length")
12528      (if_then_else (match_operand 0 "register_operand" "")
12529         (const_string "2")
12530         (const_string "*")))])
12531
12532 (define_insn "*lshrqi3_1_one_bit_slp"
12533   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12534         (lshiftrt:QI (match_dup 0)
12535                      (match_operand:QI 1 "const1_operand" "")))
12536    (clobber (reg:CC FLAGS_REG))]
12537   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12538    && (TARGET_SHIFT1 || optimize_size)"
12539   "shr{b}\t%0"
12540   [(set_attr "type" "ishift1")
12541    (set (attr "length")
12542      (if_then_else (match_operand 0 "register_operand" "")
12543         (const_string "2")
12544         (const_string "*")))])
12545
12546 (define_insn "*lshrqi3_1"
12547   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12548         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12549                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12550    (clobber (reg:CC FLAGS_REG))]
12551   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12552   "@
12553    shr{b}\t{%2, %0|%0, %2}
12554    shr{b}\t{%b2, %0|%0, %b2}"
12555   [(set_attr "type" "ishift")
12556    (set_attr "mode" "QI")])
12557
12558 (define_insn "*lshrqi3_1_slp"
12559   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12560         (lshiftrt:QI (match_dup 0)
12561                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12562    (clobber (reg:CC FLAGS_REG))]
12563   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12564    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12565   "@
12566    shr{b}\t{%1, %0|%0, %1}
12567    shr{b}\t{%b1, %0|%0, %b1}"
12568   [(set_attr "type" "ishift1")
12569    (set_attr "mode" "QI")])
12570
12571 ;; This pattern can't accept a variable shift count, since shifts by
12572 ;; zero don't affect the flags.  We assume that shifts by constant
12573 ;; zero are optimized away.
12574 (define_insn "*lshrqi2_one_bit_cmp"
12575   [(set (reg FLAGS_REG)
12576         (compare
12577           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12578                        (match_operand:QI 2 "const1_operand" ""))
12579           (const_int 0)))
12580    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12581         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12582   "ix86_match_ccmode (insn, CCGOCmode)
12583    && (TARGET_SHIFT1 || optimize_size)
12584    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12585   "shr{b}\t%0"
12586   [(set_attr "type" "ishift")
12587    (set (attr "length")
12588      (if_then_else (match_operand:SI 0 "register_operand" "")
12589         (const_string "2")
12590         (const_string "*")))])
12591
12592 (define_insn "*lshrqi2_one_bit_cconly"
12593   [(set (reg FLAGS_REG)
12594         (compare
12595           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12596                        (match_operand:QI 2 "const1_operand" ""))
12597           (const_int 0)))
12598    (clobber (match_scratch:QI 0 "=q"))]
12599   "ix86_match_ccmode (insn, CCGOCmode)
12600    && (TARGET_SHIFT1 || optimize_size)
12601    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12602   "shr{b}\t%0"
12603   [(set_attr "type" "ishift")
12604    (set_attr "length" "2")])
12605
12606 ;; This pattern can't accept a variable shift count, since shifts by
12607 ;; zero don't affect the flags.  We assume that shifts by constant
12608 ;; zero are optimized away.
12609 (define_insn "*lshrqi2_cmp"
12610   [(set (reg FLAGS_REG)
12611         (compare
12612           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12613                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12614           (const_int 0)))
12615    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12616         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12617   "ix86_match_ccmode (insn, CCGOCmode)
12618    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12619    && (optimize_size
12620        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12621   "shr{b}\t{%2, %0|%0, %2}"
12622   [(set_attr "type" "ishift")
12623    (set_attr "mode" "QI")])
12624
12625 (define_insn "*lshrqi2_cconly"
12626   [(set (reg FLAGS_REG)
12627         (compare
12628           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12629                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12630           (const_int 0)))
12631    (clobber (match_scratch:QI 0 "=q"))]
12632   "ix86_match_ccmode (insn, CCGOCmode)
12633    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12634    && (optimize_size
12635        || !TARGET_PARTIAL_FLAG_REG_STALL)"
12636   "shr{b}\t{%2, %0|%0, %2}"
12637   [(set_attr "type" "ishift")
12638    (set_attr "mode" "QI")])
12639 \f
12640 ;; Rotate instructions
12641
12642 (define_expand "rotldi3"
12643   [(set (match_operand:DI 0 "shiftdi_operand" "")
12644         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12645                    (match_operand:QI 2 "nonmemory_operand" "")))
12646    (clobber (reg:CC FLAGS_REG))]
12647  ""
12648 {
12649   if (TARGET_64BIT)
12650     {
12651       ix86_expand_binary_operator (ROTATE, DImode, operands);
12652       DONE;
12653     }
12654   if (!const_1_to_31_operand (operands[2], VOIDmode))
12655     FAIL;
12656   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12657   DONE;
12658 })
12659
12660 ;; Implement rotation using two double-precision shift instructions
12661 ;; and a scratch register.
12662 (define_insn_and_split "ix86_rotldi3"
12663  [(set (match_operand:DI 0 "register_operand" "=r")
12664        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12665                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12666   (clobber (reg:CC FLAGS_REG))
12667   (clobber (match_scratch:SI 3 "=&r"))]
12668  "!TARGET_64BIT"
12669  ""
12670  "&& reload_completed"
12671  [(set (match_dup 3) (match_dup 4))
12672   (parallel
12673    [(set (match_dup 4)
12674          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12675                  (lshiftrt:SI (match_dup 5)
12676                               (minus:QI (const_int 32) (match_dup 2)))))
12677     (clobber (reg:CC FLAGS_REG))])
12678   (parallel
12679    [(set (match_dup 5)
12680          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12681                  (lshiftrt:SI (match_dup 3)
12682                               (minus:QI (const_int 32) (match_dup 2)))))
12683     (clobber (reg:CC FLAGS_REG))])]
12684  "split_di (operands, 1, operands + 4, operands + 5);")
12685
12686 (define_insn "*rotlsi3_1_one_bit_rex64"
12687   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12688         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12689                    (match_operand:QI 2 "const1_operand" "")))
12690    (clobber (reg:CC FLAGS_REG))]
12691   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12692    && (TARGET_SHIFT1 || optimize_size)"
12693   "rol{q}\t%0"
12694   [(set_attr "type" "rotate")
12695    (set (attr "length")
12696      (if_then_else (match_operand:DI 0 "register_operand" "")
12697         (const_string "2")
12698         (const_string "*")))])
12699
12700 (define_insn "*rotldi3_1_rex64"
12701   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12702         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12703                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12704    (clobber (reg:CC FLAGS_REG))]
12705   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12706   "@
12707    rol{q}\t{%2, %0|%0, %2}
12708    rol{q}\t{%b2, %0|%0, %b2}"
12709   [(set_attr "type" "rotate")
12710    (set_attr "mode" "DI")])
12711
12712 (define_expand "rotlsi3"
12713   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12714         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12715                    (match_operand:QI 2 "nonmemory_operand" "")))
12716    (clobber (reg:CC FLAGS_REG))]
12717   ""
12718   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12719
12720 (define_insn "*rotlsi3_1_one_bit"
12721   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12722         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12723                    (match_operand:QI 2 "const1_operand" "")))
12724    (clobber (reg:CC FLAGS_REG))]
12725   "ix86_binary_operator_ok (ROTATE, SImode, operands)
12726    && (TARGET_SHIFT1 || optimize_size)"
12727   "rol{l}\t%0"
12728   [(set_attr "type" "rotate")
12729    (set (attr "length")
12730      (if_then_else (match_operand:SI 0 "register_operand" "")
12731         (const_string "2")
12732         (const_string "*")))])
12733
12734 (define_insn "*rotlsi3_1_one_bit_zext"
12735   [(set (match_operand:DI 0 "register_operand" "=r")
12736         (zero_extend:DI
12737           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12738                      (match_operand:QI 2 "const1_operand" ""))))
12739    (clobber (reg:CC FLAGS_REG))]
12740   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12741    && (TARGET_SHIFT1 || optimize_size)"
12742   "rol{l}\t%k0"
12743   [(set_attr "type" "rotate")
12744    (set_attr "length" "2")])
12745
12746 (define_insn "*rotlsi3_1"
12747   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12748         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12749                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12750    (clobber (reg:CC FLAGS_REG))]
12751   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12752   "@
12753    rol{l}\t{%2, %0|%0, %2}
12754    rol{l}\t{%b2, %0|%0, %b2}"
12755   [(set_attr "type" "rotate")
12756    (set_attr "mode" "SI")])
12757
12758 (define_insn "*rotlsi3_1_zext"
12759   [(set (match_operand:DI 0 "register_operand" "=r,r")
12760         (zero_extend:DI
12761           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12762                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12763    (clobber (reg:CC FLAGS_REG))]
12764   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12765   "@
12766    rol{l}\t{%2, %k0|%k0, %2}
12767    rol{l}\t{%b2, %k0|%k0, %b2}"
12768   [(set_attr "type" "rotate")
12769    (set_attr "mode" "SI")])
12770
12771 (define_expand "rotlhi3"
12772   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12773         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12774                    (match_operand:QI 2 "nonmemory_operand" "")))
12775    (clobber (reg:CC FLAGS_REG))]
12776   "TARGET_HIMODE_MATH"
12777   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12778
12779 (define_insn "*rotlhi3_1_one_bit"
12780   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12781         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12782                    (match_operand:QI 2 "const1_operand" "")))
12783    (clobber (reg:CC FLAGS_REG))]
12784   "ix86_binary_operator_ok (ROTATE, HImode, operands)
12785    && (TARGET_SHIFT1 || optimize_size)"
12786   "rol{w}\t%0"
12787   [(set_attr "type" "rotate")
12788    (set (attr "length")
12789      (if_then_else (match_operand 0 "register_operand" "")
12790         (const_string "2")
12791         (const_string "*")))])
12792
12793 (define_insn "*rotlhi3_1"
12794   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12795         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12796                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12797    (clobber (reg:CC FLAGS_REG))]
12798   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12799   "@
12800    rol{w}\t{%2, %0|%0, %2}
12801    rol{w}\t{%b2, %0|%0, %b2}"
12802   [(set_attr "type" "rotate")
12803    (set_attr "mode" "HI")])
12804
12805 (define_expand "rotlqi3"
12806   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12807         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12808                    (match_operand:QI 2 "nonmemory_operand" "")))
12809    (clobber (reg:CC FLAGS_REG))]
12810   "TARGET_QIMODE_MATH"
12811   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12812
12813 (define_insn "*rotlqi3_1_one_bit_slp"
12814   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12815         (rotate:QI (match_dup 0)
12816                    (match_operand:QI 1 "const1_operand" "")))
12817    (clobber (reg:CC FLAGS_REG))]
12818   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12819    && (TARGET_SHIFT1 || optimize_size)"
12820   "rol{b}\t%0"
12821   [(set_attr "type" "rotate1")
12822    (set (attr "length")
12823      (if_then_else (match_operand 0 "register_operand" "")
12824         (const_string "2")
12825         (const_string "*")))])
12826
12827 (define_insn "*rotlqi3_1_one_bit"
12828   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12829         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12830                    (match_operand:QI 2 "const1_operand" "")))
12831    (clobber (reg:CC FLAGS_REG))]
12832   "ix86_binary_operator_ok (ROTATE, QImode, operands)
12833    && (TARGET_SHIFT1 || optimize_size)"
12834   "rol{b}\t%0"
12835   [(set_attr "type" "rotate")
12836    (set (attr "length")
12837      (if_then_else (match_operand 0 "register_operand" "")
12838         (const_string "2")
12839         (const_string "*")))])
12840
12841 (define_insn "*rotlqi3_1_slp"
12842   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12843         (rotate:QI (match_dup 0)
12844                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12845    (clobber (reg:CC FLAGS_REG))]
12846   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12847    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12848   "@
12849    rol{b}\t{%1, %0|%0, %1}
12850    rol{b}\t{%b1, %0|%0, %b1}"
12851   [(set_attr "type" "rotate1")
12852    (set_attr "mode" "QI")])
12853
12854 (define_insn "*rotlqi3_1"
12855   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12856         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12857                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12858    (clobber (reg:CC FLAGS_REG))]
12859   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12860   "@
12861    rol{b}\t{%2, %0|%0, %2}
12862    rol{b}\t{%b2, %0|%0, %b2}"
12863   [(set_attr "type" "rotate")
12864    (set_attr "mode" "QI")])
12865
12866 (define_expand "rotrdi3"
12867   [(set (match_operand:DI 0 "shiftdi_operand" "")
12868         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12869                    (match_operand:QI 2 "nonmemory_operand" "")))
12870    (clobber (reg:CC FLAGS_REG))]
12871  ""
12872 {
12873   if (TARGET_64BIT)
12874     {
12875       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12876       DONE;
12877     }
12878   if (!const_1_to_31_operand (operands[2], VOIDmode))
12879     FAIL;
12880   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12881   DONE;
12882 })
12883
12884 ;; Implement rotation using two double-precision shift instructions
12885 ;; and a scratch register.
12886 (define_insn_and_split "ix86_rotrdi3"
12887  [(set (match_operand:DI 0 "register_operand" "=r")
12888        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12889                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12890   (clobber (reg:CC FLAGS_REG))
12891   (clobber (match_scratch:SI 3 "=&r"))]
12892  "!TARGET_64BIT"
12893  ""
12894  "&& reload_completed"
12895  [(set (match_dup 3) (match_dup 4))
12896   (parallel
12897    [(set (match_dup 4)
12898          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12899                  (ashift:SI (match_dup 5)
12900                             (minus:QI (const_int 32) (match_dup 2)))))
12901     (clobber (reg:CC FLAGS_REG))])
12902   (parallel
12903    [(set (match_dup 5)
12904          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12905                  (ashift:SI (match_dup 3)
12906                             (minus:QI (const_int 32) (match_dup 2)))))
12907     (clobber (reg:CC FLAGS_REG))])]
12908  "split_di (operands, 1, operands + 4, operands + 5);")
12909
12910 (define_insn "*rotrdi3_1_one_bit_rex64"
12911   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12912         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12913                      (match_operand:QI 2 "const1_operand" "")))
12914    (clobber (reg:CC FLAGS_REG))]
12915   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12916    && (TARGET_SHIFT1 || optimize_size)"
12917   "ror{q}\t%0"
12918   [(set_attr "type" "rotate")
12919    (set (attr "length")
12920      (if_then_else (match_operand:DI 0 "register_operand" "")
12921         (const_string "2")
12922         (const_string "*")))])
12923
12924 (define_insn "*rotrdi3_1_rex64"
12925   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12926         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12927                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12928    (clobber (reg:CC FLAGS_REG))]
12929   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12930   "@
12931    ror{q}\t{%2, %0|%0, %2}
12932    ror{q}\t{%b2, %0|%0, %b2}"
12933   [(set_attr "type" "rotate")
12934    (set_attr "mode" "DI")])
12935
12936 (define_expand "rotrsi3"
12937   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12938         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12939                      (match_operand:QI 2 "nonmemory_operand" "")))
12940    (clobber (reg:CC FLAGS_REG))]
12941   ""
12942   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12943
12944 (define_insn "*rotrsi3_1_one_bit"
12945   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12946         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12947                      (match_operand:QI 2 "const1_operand" "")))
12948    (clobber (reg:CC FLAGS_REG))]
12949   "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12950    && (TARGET_SHIFT1 || optimize_size)"
12951   "ror{l}\t%0"
12952   [(set_attr "type" "rotate")
12953    (set (attr "length")
12954      (if_then_else (match_operand:SI 0 "register_operand" "")
12955         (const_string "2")
12956         (const_string "*")))])
12957
12958 (define_insn "*rotrsi3_1_one_bit_zext"
12959   [(set (match_operand:DI 0 "register_operand" "=r")
12960         (zero_extend:DI
12961           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12962                        (match_operand:QI 2 "const1_operand" ""))))
12963    (clobber (reg:CC FLAGS_REG))]
12964   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12965    && (TARGET_SHIFT1 || optimize_size)"
12966   "ror{l}\t%k0"
12967   [(set_attr "type" "rotate")
12968    (set (attr "length")
12969      (if_then_else (match_operand:SI 0 "register_operand" "")
12970         (const_string "2")
12971         (const_string "*")))])
12972
12973 (define_insn "*rotrsi3_1"
12974   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12975         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12976                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12977    (clobber (reg:CC FLAGS_REG))]
12978   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12979   "@
12980    ror{l}\t{%2, %0|%0, %2}
12981    ror{l}\t{%b2, %0|%0, %b2}"
12982   [(set_attr "type" "rotate")
12983    (set_attr "mode" "SI")])
12984
12985 (define_insn "*rotrsi3_1_zext"
12986   [(set (match_operand:DI 0 "register_operand" "=r,r")
12987         (zero_extend:DI
12988           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12989                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12990    (clobber (reg:CC FLAGS_REG))]
12991   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12992   "@
12993    ror{l}\t{%2, %k0|%k0, %2}
12994    ror{l}\t{%b2, %k0|%k0, %b2}"
12995   [(set_attr "type" "rotate")
12996    (set_attr "mode" "SI")])
12997
12998 (define_expand "rotrhi3"
12999   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13000         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13001                      (match_operand:QI 2 "nonmemory_operand" "")))
13002    (clobber (reg:CC FLAGS_REG))]
13003   "TARGET_HIMODE_MATH"
13004   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13005
13006 (define_insn "*rotrhi3_one_bit"
13007   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13008         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13009                      (match_operand:QI 2 "const1_operand" "")))
13010    (clobber (reg:CC FLAGS_REG))]
13011   "ix86_binary_operator_ok (ROTATERT, HImode, operands)
13012    && (TARGET_SHIFT1 || optimize_size)"
13013   "ror{w}\t%0"
13014   [(set_attr "type" "rotate")
13015    (set (attr "length")
13016      (if_then_else (match_operand 0 "register_operand" "")
13017         (const_string "2")
13018         (const_string "*")))])
13019
13020 (define_insn "*rotrhi3"
13021   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13022         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13023                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13024    (clobber (reg:CC FLAGS_REG))]
13025   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13026   "@
13027    ror{w}\t{%2, %0|%0, %2}
13028    ror{w}\t{%b2, %0|%0, %b2}"
13029   [(set_attr "type" "rotate")
13030    (set_attr "mode" "HI")])
13031
13032 (define_expand "rotrqi3"
13033   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13034         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13035                      (match_operand:QI 2 "nonmemory_operand" "")))
13036    (clobber (reg:CC FLAGS_REG))]
13037   "TARGET_QIMODE_MATH"
13038   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13039
13040 (define_insn "*rotrqi3_1_one_bit"
13041   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13042         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13043                      (match_operand:QI 2 "const1_operand" "")))
13044    (clobber (reg:CC FLAGS_REG))]
13045   "ix86_binary_operator_ok (ROTATERT, QImode, operands)
13046    && (TARGET_SHIFT1 || optimize_size)"
13047   "ror{b}\t%0"
13048   [(set_attr "type" "rotate")
13049    (set (attr "length")
13050      (if_then_else (match_operand 0 "register_operand" "")
13051         (const_string "2")
13052         (const_string "*")))])
13053
13054 (define_insn "*rotrqi3_1_one_bit_slp"
13055   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13056         (rotatert:QI (match_dup 0)
13057                      (match_operand:QI 1 "const1_operand" "")))
13058    (clobber (reg:CC FLAGS_REG))]
13059   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13060    && (TARGET_SHIFT1 || optimize_size)"
13061   "ror{b}\t%0"
13062   [(set_attr "type" "rotate1")
13063    (set (attr "length")
13064      (if_then_else (match_operand 0 "register_operand" "")
13065         (const_string "2")
13066         (const_string "*")))])
13067
13068 (define_insn "*rotrqi3_1"
13069   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13070         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13071                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13072    (clobber (reg:CC FLAGS_REG))]
13073   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13074   "@
13075    ror{b}\t{%2, %0|%0, %2}
13076    ror{b}\t{%b2, %0|%0, %b2}"
13077   [(set_attr "type" "rotate")
13078    (set_attr "mode" "QI")])
13079
13080 (define_insn "*rotrqi3_1_slp"
13081   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13082         (rotatert:QI (match_dup 0)
13083                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13084    (clobber (reg:CC FLAGS_REG))]
13085   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13086    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13087   "@
13088    ror{b}\t{%1, %0|%0, %1}
13089    ror{b}\t{%b1, %0|%0, %b1}"
13090   [(set_attr "type" "rotate1")
13091    (set_attr "mode" "QI")])
13092 \f
13093 ;; Bit set / bit test instructions
13094
13095 (define_expand "extv"
13096   [(set (match_operand:SI 0 "register_operand" "")
13097         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13098                          (match_operand:SI 2 "const8_operand" "")
13099                          (match_operand:SI 3 "const8_operand" "")))]
13100   ""
13101 {
13102   /* Handle extractions from %ah et al.  */
13103   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13104     FAIL;
13105
13106   /* From mips.md: extract_bit_field doesn't verify that our source
13107      matches the predicate, so check it again here.  */
13108   if (! ext_register_operand (operands[1], VOIDmode))
13109     FAIL;
13110 })
13111
13112 (define_expand "extzv"
13113   [(set (match_operand:SI 0 "register_operand" "")
13114         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13115                          (match_operand:SI 2 "const8_operand" "")
13116                          (match_operand:SI 3 "const8_operand" "")))]
13117   ""
13118 {
13119   /* Handle extractions from %ah et al.  */
13120   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13121     FAIL;
13122
13123   /* From mips.md: extract_bit_field doesn't verify that our source
13124      matches the predicate, so check it again here.  */
13125   if (! ext_register_operand (operands[1], VOIDmode))
13126     FAIL;
13127 })
13128
13129 (define_expand "insv"
13130   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13131                       (match_operand 1 "const8_operand" "")
13132                       (match_operand 2 "const8_operand" ""))
13133         (match_operand 3 "register_operand" ""))]
13134   ""
13135 {
13136   /* Handle insertions to %ah et al.  */
13137   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13138     FAIL;
13139
13140   /* From mips.md: insert_bit_field doesn't verify that our source
13141      matches the predicate, so check it again here.  */
13142   if (! ext_register_operand (operands[0], VOIDmode))
13143     FAIL;
13144
13145   if (TARGET_64BIT)
13146     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13147   else
13148     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13149
13150   DONE;
13151 })
13152
13153 ;; %%% bts, btr, btc, bt.
13154 ;; In general these instructions are *slow* when applied to memory,
13155 ;; since they enforce atomic operation.  When applied to registers,
13156 ;; it depends on the cpu implementation.  They're never faster than
13157 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13158 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13159 ;; within the instruction itself, so operating on bits in the high
13160 ;; 32-bits of a register becomes easier.
13161 ;;
13162 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13163 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13164 ;; negdf respectively, so they can never be disabled entirely.
13165
13166 (define_insn "*btsq"
13167   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13168                          (const_int 1)
13169                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13170         (const_int 1))
13171    (clobber (reg:CC FLAGS_REG))]
13172   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13173   "bts{q} %1,%0"
13174   [(set_attr "type" "alu1")])
13175
13176 (define_insn "*btrq"
13177   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13178                          (const_int 1)
13179                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13180         (const_int 0))
13181    (clobber (reg:CC FLAGS_REG))]
13182   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13183   "btr{q} %1,%0"
13184   [(set_attr "type" "alu1")])
13185
13186 (define_insn "*btcq"
13187   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13188                          (const_int 1)
13189                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13190         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13191    (clobber (reg:CC FLAGS_REG))]
13192   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13193   "btc{q} %1,%0"
13194   [(set_attr "type" "alu1")])
13195
13196 ;; Allow Nocona to avoid these instructions if a register is available.
13197
13198 (define_peephole2
13199   [(match_scratch:DI 2 "r")
13200    (parallel [(set (zero_extract:DI
13201                      (match_operand:DI 0 "register_operand" "")
13202                      (const_int 1)
13203                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13204                    (const_int 1))
13205               (clobber (reg:CC FLAGS_REG))])]
13206   "TARGET_64BIT && !TARGET_USE_BT"
13207   [(const_int 0)]
13208 {
13209   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13210   rtx op1;
13211
13212   if (HOST_BITS_PER_WIDE_INT >= 64)
13213     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13214   else if (i < HOST_BITS_PER_WIDE_INT)
13215     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13216   else
13217     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13218
13219   op1 = immed_double_const (lo, hi, DImode);
13220   if (i >= 31)
13221     {
13222       emit_move_insn (operands[2], op1);
13223       op1 = operands[2];
13224     }
13225
13226   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13227   DONE;
13228 })
13229
13230 (define_peephole2
13231   [(match_scratch:DI 2 "r")
13232    (parallel [(set (zero_extract:DI
13233                      (match_operand:DI 0 "register_operand" "")
13234                      (const_int 1)
13235                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13236                    (const_int 0))
13237               (clobber (reg:CC FLAGS_REG))])]
13238   "TARGET_64BIT && !TARGET_USE_BT"
13239   [(const_int 0)]
13240 {
13241   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13242   rtx op1;
13243
13244   if (HOST_BITS_PER_WIDE_INT >= 64)
13245     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13246   else if (i < HOST_BITS_PER_WIDE_INT)
13247     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13248   else
13249     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13250
13251   op1 = immed_double_const (~lo, ~hi, DImode);
13252   if (i >= 32)
13253     {
13254       emit_move_insn (operands[2], op1);
13255       op1 = operands[2];
13256     }
13257
13258   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13259   DONE;
13260 })
13261
13262 (define_peephole2
13263   [(match_scratch:DI 2 "r")
13264    (parallel [(set (zero_extract:DI
13265                      (match_operand:DI 0 "register_operand" "")
13266                      (const_int 1)
13267                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13268               (not:DI (zero_extract:DI
13269                         (match_dup 0) (const_int 1) (match_dup 1))))
13270               (clobber (reg:CC FLAGS_REG))])]
13271   "TARGET_64BIT && !TARGET_USE_BT"
13272   [(const_int 0)]
13273 {
13274   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13275   rtx op1;
13276
13277   if (HOST_BITS_PER_WIDE_INT >= 64)
13278     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13279   else if (i < HOST_BITS_PER_WIDE_INT)
13280     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13281   else
13282     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13283
13284   op1 = immed_double_const (lo, hi, DImode);
13285   if (i >= 31)
13286     {
13287       emit_move_insn (operands[2], op1);
13288       op1 = operands[2];
13289     }
13290
13291   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13292   DONE;
13293 })
13294 \f
13295 ;; Store-flag instructions.
13296
13297 ;; For all sCOND expanders, also expand the compare or test insn that
13298 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13299
13300 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13301 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13302 ;; way, which can later delete the movzx if only QImode is needed.
13303
13304 (define_expand "seq"
13305   [(set (match_operand:QI 0 "register_operand" "")
13306         (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13307   ""
13308   "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13309
13310 (define_expand "sne"
13311   [(set (match_operand:QI 0 "register_operand" "")
13312         (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13313   ""
13314   "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13315
13316 (define_expand "sgt"
13317   [(set (match_operand:QI 0 "register_operand" "")
13318         (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13319   ""
13320   "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13321
13322 (define_expand "sgtu"
13323   [(set (match_operand:QI 0 "register_operand" "")
13324         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13325   ""
13326   "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13327
13328 (define_expand "slt"
13329   [(set (match_operand:QI 0 "register_operand" "")
13330         (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13331   ""
13332   "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13333
13334 (define_expand "sltu"
13335   [(set (match_operand:QI 0 "register_operand" "")
13336         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13337   ""
13338   "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13339
13340 (define_expand "sge"
13341   [(set (match_operand:QI 0 "register_operand" "")
13342         (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13343   ""
13344   "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13345
13346 (define_expand "sgeu"
13347   [(set (match_operand:QI 0 "register_operand" "")
13348         (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13349   ""
13350   "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13351
13352 (define_expand "sle"
13353   [(set (match_operand:QI 0 "register_operand" "")
13354         (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13355   ""
13356   "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13357
13358 (define_expand "sleu"
13359   [(set (match_operand:QI 0 "register_operand" "")
13360         (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13361   ""
13362   "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13363
13364 (define_expand "sunordered"
13365   [(set (match_operand:QI 0 "register_operand" "")
13366         (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13367   "TARGET_80387 || TARGET_SSE"
13368   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13369
13370 (define_expand "sordered"
13371   [(set (match_operand:QI 0 "register_operand" "")
13372         (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13373   "TARGET_80387"
13374   "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13375
13376 (define_expand "suneq"
13377   [(set (match_operand:QI 0 "register_operand" "")
13378         (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13379   "TARGET_80387 || TARGET_SSE"
13380   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13381
13382 (define_expand "sunge"
13383   [(set (match_operand:QI 0 "register_operand" "")
13384         (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13385   "TARGET_80387 || TARGET_SSE"
13386   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13387
13388 (define_expand "sungt"
13389   [(set (match_operand:QI 0 "register_operand" "")
13390         (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13391   "TARGET_80387 || TARGET_SSE"
13392   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13393
13394 (define_expand "sunle"
13395   [(set (match_operand:QI 0 "register_operand" "")
13396         (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13397   "TARGET_80387 || TARGET_SSE"
13398   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13399
13400 (define_expand "sunlt"
13401   [(set (match_operand:QI 0 "register_operand" "")
13402         (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13403   "TARGET_80387 || TARGET_SSE"
13404   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13405
13406 (define_expand "sltgt"
13407   [(set (match_operand:QI 0 "register_operand" "")
13408         (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13409   "TARGET_80387 || TARGET_SSE"
13410   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13411
13412 (define_insn "*setcc_1"
13413   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13414         (match_operator:QI 1 "ix86_comparison_operator"
13415           [(reg FLAGS_REG) (const_int 0)]))]
13416   ""
13417   "set%C1\t%0"
13418   [(set_attr "type" "setcc")
13419    (set_attr "mode" "QI")])
13420
13421 (define_insn "*setcc_2"
13422   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13423         (match_operator:QI 1 "ix86_comparison_operator"
13424           [(reg FLAGS_REG) (const_int 0)]))]
13425   ""
13426   "set%C1\t%0"
13427   [(set_attr "type" "setcc")
13428    (set_attr "mode" "QI")])
13429
13430 ;; In general it is not safe to assume too much about CCmode registers,
13431 ;; so simplify-rtx stops when it sees a second one.  Under certain
13432 ;; conditions this is safe on x86, so help combine not create
13433 ;;
13434 ;;      seta    %al
13435 ;;      testb   %al, %al
13436 ;;      sete    %al
13437
13438 (define_split
13439   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13440         (ne:QI (match_operator 1 "ix86_comparison_operator"
13441                  [(reg FLAGS_REG) (const_int 0)])
13442             (const_int 0)))]
13443   ""
13444   [(set (match_dup 0) (match_dup 1))]
13445 {
13446   PUT_MODE (operands[1], QImode);
13447 })
13448
13449 (define_split
13450   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13451         (ne:QI (match_operator 1 "ix86_comparison_operator"
13452                  [(reg FLAGS_REG) (const_int 0)])
13453             (const_int 0)))]
13454   ""
13455   [(set (match_dup 0) (match_dup 1))]
13456 {
13457   PUT_MODE (operands[1], QImode);
13458 })
13459
13460 (define_split
13461   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13462         (eq:QI (match_operator 1 "ix86_comparison_operator"
13463                  [(reg FLAGS_REG) (const_int 0)])
13464             (const_int 0)))]
13465   ""
13466   [(set (match_dup 0) (match_dup 1))]
13467 {
13468   rtx new_op1 = copy_rtx (operands[1]);
13469   operands[1] = new_op1;
13470   PUT_MODE (new_op1, QImode);
13471   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13472                                              GET_MODE (XEXP (new_op1, 0))));
13473
13474   /* Make sure that (a) the CCmode we have for the flags is strong
13475      enough for the reversed compare or (b) we have a valid FP compare.  */
13476   if (! ix86_comparison_operator (new_op1, VOIDmode))
13477     FAIL;
13478 })
13479
13480 (define_split
13481   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13482         (eq:QI (match_operator 1 "ix86_comparison_operator"
13483                  [(reg FLAGS_REG) (const_int 0)])
13484             (const_int 0)))]
13485   ""
13486   [(set (match_dup 0) (match_dup 1))]
13487 {
13488   rtx new_op1 = copy_rtx (operands[1]);
13489   operands[1] = new_op1;
13490   PUT_MODE (new_op1, QImode);
13491   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13492                                              GET_MODE (XEXP (new_op1, 0))));
13493
13494   /* Make sure that (a) the CCmode we have for the flags is strong
13495      enough for the reversed compare or (b) we have a valid FP compare.  */
13496   if (! ix86_comparison_operator (new_op1, VOIDmode))
13497     FAIL;
13498 })
13499
13500 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13501 ;; subsequent logical operations are used to imitate conditional moves.
13502 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13503 ;; it directly.
13504
13505 (define_insn "*sse_setccsf"
13506   [(set (match_operand:SF 0 "register_operand" "=x")
13507         (match_operator:SF 1 "sse_comparison_operator"
13508           [(match_operand:SF 2 "register_operand" "0")
13509            (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13510   "TARGET_SSE"
13511   "cmp%D1ss\t{%3, %0|%0, %3}"
13512   [(set_attr "type" "ssecmp")
13513    (set_attr "mode" "SF")])
13514
13515 (define_insn "*sse_setccdf"
13516   [(set (match_operand:DF 0 "register_operand" "=Y")
13517         (match_operator:DF 1 "sse_comparison_operator"
13518           [(match_operand:DF 2 "register_operand" "0")
13519            (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13520   "TARGET_SSE2"
13521   "cmp%D1sd\t{%3, %0|%0, %3}"
13522   [(set_attr "type" "ssecmp")
13523    (set_attr "mode" "DF")])
13524 \f
13525 ;; Basic conditional jump instructions.
13526 ;; We ignore the overflow flag for signed branch instructions.
13527
13528 ;; For all bCOND expanders, also expand the compare or test insn that
13529 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13530
13531 (define_expand "beq"
13532   [(set (pc)
13533         (if_then_else (match_dup 1)
13534                       (label_ref (match_operand 0 "" ""))
13535                       (pc)))]
13536   ""
13537   "ix86_expand_branch (EQ, operands[0]); DONE;")
13538
13539 (define_expand "bne"
13540   [(set (pc)
13541         (if_then_else (match_dup 1)
13542                       (label_ref (match_operand 0 "" ""))
13543                       (pc)))]
13544   ""
13545   "ix86_expand_branch (NE, operands[0]); DONE;")
13546
13547 (define_expand "bgt"
13548   [(set (pc)
13549         (if_then_else (match_dup 1)
13550                       (label_ref (match_operand 0 "" ""))
13551                       (pc)))]
13552   ""
13553   "ix86_expand_branch (GT, operands[0]); DONE;")
13554
13555 (define_expand "bgtu"
13556   [(set (pc)
13557         (if_then_else (match_dup 1)
13558                       (label_ref (match_operand 0 "" ""))
13559                       (pc)))]
13560   ""
13561   "ix86_expand_branch (GTU, operands[0]); DONE;")
13562
13563 (define_expand "blt"
13564   [(set (pc)
13565         (if_then_else (match_dup 1)
13566                       (label_ref (match_operand 0 "" ""))
13567                       (pc)))]
13568   ""
13569   "ix86_expand_branch (LT, operands[0]); DONE;")
13570
13571 (define_expand "bltu"
13572   [(set (pc)
13573         (if_then_else (match_dup 1)
13574                       (label_ref (match_operand 0 "" ""))
13575                       (pc)))]
13576   ""
13577   "ix86_expand_branch (LTU, operands[0]); DONE;")
13578
13579 (define_expand "bge"
13580   [(set (pc)
13581         (if_then_else (match_dup 1)
13582                       (label_ref (match_operand 0 "" ""))
13583                       (pc)))]
13584   ""
13585   "ix86_expand_branch (GE, operands[0]); DONE;")
13586
13587 (define_expand "bgeu"
13588   [(set (pc)
13589         (if_then_else (match_dup 1)
13590                       (label_ref (match_operand 0 "" ""))
13591                       (pc)))]
13592   ""
13593   "ix86_expand_branch (GEU, operands[0]); DONE;")
13594
13595 (define_expand "ble"
13596   [(set (pc)
13597         (if_then_else (match_dup 1)
13598                       (label_ref (match_operand 0 "" ""))
13599                       (pc)))]
13600   ""
13601   "ix86_expand_branch (LE, operands[0]); DONE;")
13602
13603 (define_expand "bleu"
13604   [(set (pc)
13605         (if_then_else (match_dup 1)
13606                       (label_ref (match_operand 0 "" ""))
13607                       (pc)))]
13608   ""
13609   "ix86_expand_branch (LEU, operands[0]); DONE;")
13610
13611 (define_expand "bunordered"
13612   [(set (pc)
13613         (if_then_else (match_dup 1)
13614                       (label_ref (match_operand 0 "" ""))
13615                       (pc)))]
13616   "TARGET_80387 || TARGET_SSE_MATH"
13617   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13618
13619 (define_expand "bordered"
13620   [(set (pc)
13621         (if_then_else (match_dup 1)
13622                       (label_ref (match_operand 0 "" ""))
13623                       (pc)))]
13624   "TARGET_80387 || TARGET_SSE_MATH"
13625   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13626
13627 (define_expand "buneq"
13628   [(set (pc)
13629         (if_then_else (match_dup 1)
13630                       (label_ref (match_operand 0 "" ""))
13631                       (pc)))]
13632   "TARGET_80387 || TARGET_SSE_MATH"
13633   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13634
13635 (define_expand "bunge"
13636   [(set (pc)
13637         (if_then_else (match_dup 1)
13638                       (label_ref (match_operand 0 "" ""))
13639                       (pc)))]
13640   "TARGET_80387 || TARGET_SSE_MATH"
13641   "ix86_expand_branch (UNGE, operands[0]); DONE;")
13642
13643 (define_expand "bungt"
13644   [(set (pc)
13645         (if_then_else (match_dup 1)
13646                       (label_ref (match_operand 0 "" ""))
13647                       (pc)))]
13648   "TARGET_80387 || TARGET_SSE_MATH"
13649   "ix86_expand_branch (UNGT, operands[0]); DONE;")
13650
13651 (define_expand "bunle"
13652   [(set (pc)
13653         (if_then_else (match_dup 1)
13654                       (label_ref (match_operand 0 "" ""))
13655                       (pc)))]
13656   "TARGET_80387 || TARGET_SSE_MATH"
13657   "ix86_expand_branch (UNLE, operands[0]); DONE;")
13658
13659 (define_expand "bunlt"
13660   [(set (pc)
13661         (if_then_else (match_dup 1)
13662                       (label_ref (match_operand 0 "" ""))
13663                       (pc)))]
13664   "TARGET_80387 || TARGET_SSE_MATH"
13665   "ix86_expand_branch (UNLT, operands[0]); DONE;")
13666
13667 (define_expand "bltgt"
13668   [(set (pc)
13669         (if_then_else (match_dup 1)
13670                       (label_ref (match_operand 0 "" ""))
13671                       (pc)))]
13672   "TARGET_80387 || TARGET_SSE_MATH"
13673   "ix86_expand_branch (LTGT, operands[0]); DONE;")
13674
13675 (define_insn "*jcc_1"
13676   [(set (pc)
13677         (if_then_else (match_operator 1 "ix86_comparison_operator"
13678                                       [(reg FLAGS_REG) (const_int 0)])
13679                       (label_ref (match_operand 0 "" ""))
13680                       (pc)))]
13681   ""
13682   "%+j%C1\t%l0"
13683   [(set_attr "type" "ibr")
13684    (set_attr "modrm" "0")
13685    (set (attr "length")
13686            (if_then_else (and (ge (minus (match_dup 0) (pc))
13687                                   (const_int -126))
13688                               (lt (minus (match_dup 0) (pc))
13689                                   (const_int 128)))
13690              (const_int 2)
13691              (const_int 6)))])
13692
13693 (define_insn "*jcc_2"
13694   [(set (pc)
13695         (if_then_else (match_operator 1 "ix86_comparison_operator"
13696                                       [(reg FLAGS_REG) (const_int 0)])
13697                       (pc)
13698                       (label_ref (match_operand 0 "" ""))))]
13699   ""
13700   "%+j%c1\t%l0"
13701   [(set_attr "type" "ibr")
13702    (set_attr "modrm" "0")
13703    (set (attr "length")
13704            (if_then_else (and (ge (minus (match_dup 0) (pc))
13705                                   (const_int -126))
13706                               (lt (minus (match_dup 0) (pc))
13707                                   (const_int 128)))
13708              (const_int 2)
13709              (const_int 6)))])
13710
13711 ;; In general it is not safe to assume too much about CCmode registers,
13712 ;; so simplify-rtx stops when it sees a second one.  Under certain
13713 ;; conditions this is safe on x86, so help combine not create
13714 ;;
13715 ;;      seta    %al
13716 ;;      testb   %al, %al
13717 ;;      je      Lfoo
13718
13719 (define_split
13720   [(set (pc)
13721         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13722                                       [(reg FLAGS_REG) (const_int 0)])
13723                           (const_int 0))
13724                       (label_ref (match_operand 1 "" ""))
13725                       (pc)))]
13726   ""
13727   [(set (pc)
13728         (if_then_else (match_dup 0)
13729                       (label_ref (match_dup 1))
13730                       (pc)))]
13731 {
13732   PUT_MODE (operands[0], VOIDmode);
13733 })
13734
13735 (define_split
13736   [(set (pc)
13737         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13738                                       [(reg FLAGS_REG) (const_int 0)])
13739                           (const_int 0))
13740                       (label_ref (match_operand 1 "" ""))
13741                       (pc)))]
13742   ""
13743   [(set (pc)
13744         (if_then_else (match_dup 0)
13745                       (label_ref (match_dup 1))
13746                       (pc)))]
13747 {
13748   rtx new_op0 = copy_rtx (operands[0]);
13749   operands[0] = new_op0;
13750   PUT_MODE (new_op0, VOIDmode);
13751   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13752                                              GET_MODE (XEXP (new_op0, 0))));
13753
13754   /* Make sure that (a) the CCmode we have for the flags is strong
13755      enough for the reversed compare or (b) we have a valid FP compare.  */
13756   if (! ix86_comparison_operator (new_op0, VOIDmode))
13757     FAIL;
13758 })
13759
13760 ;; Define combination compare-and-branch fp compare instructions to use
13761 ;; during early optimization.  Splitting the operation apart early makes
13762 ;; for bad code when we want to reverse the operation.
13763
13764 (define_insn "*fp_jcc_1_mixed"
13765   [(set (pc)
13766         (if_then_else (match_operator 0 "comparison_operator"
13767                         [(match_operand 1 "register_operand" "f,x")
13768                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13769           (label_ref (match_operand 3 "" ""))
13770           (pc)))
13771    (clobber (reg:CCFP FPSR_REG))
13772    (clobber (reg:CCFP FLAGS_REG))]
13773   "TARGET_MIX_SSE_I387
13774    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13775    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13776    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13777   "#")
13778
13779 (define_insn "*fp_jcc_1_sse"
13780   [(set (pc)
13781         (if_then_else (match_operator 0 "comparison_operator"
13782                         [(match_operand 1 "register_operand" "x")
13783                          (match_operand 2 "nonimmediate_operand" "xm")])
13784           (label_ref (match_operand 3 "" ""))
13785           (pc)))
13786    (clobber (reg:CCFP FPSR_REG))
13787    (clobber (reg:CCFP FLAGS_REG))]
13788   "TARGET_SSE_MATH
13789    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13790    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13791    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13792   "#")
13793
13794 (define_insn "*fp_jcc_1_387"
13795   [(set (pc)
13796         (if_then_else (match_operator 0 "comparison_operator"
13797                         [(match_operand 1 "register_operand" "f")
13798                          (match_operand 2 "register_operand" "f")])
13799           (label_ref (match_operand 3 "" ""))
13800           (pc)))
13801    (clobber (reg:CCFP FPSR_REG))
13802    (clobber (reg:CCFP FLAGS_REG))]
13803   "TARGET_CMOVE && TARGET_80387
13804    && FLOAT_MODE_P (GET_MODE (operands[1]))
13805    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13806    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13807   "#")
13808
13809 (define_insn "*fp_jcc_2_mixed"
13810   [(set (pc)
13811         (if_then_else (match_operator 0 "comparison_operator"
13812                         [(match_operand 1 "register_operand" "f,x")
13813                          (match_operand 2 "nonimmediate_operand" "f,xm")])
13814           (pc)
13815           (label_ref (match_operand 3 "" ""))))
13816    (clobber (reg:CCFP FPSR_REG))
13817    (clobber (reg:CCFP FLAGS_REG))]
13818   "TARGET_MIX_SSE_I387
13819    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13820    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13821    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13822   "#")
13823
13824 (define_insn "*fp_jcc_2_sse"
13825   [(set (pc)
13826         (if_then_else (match_operator 0 "comparison_operator"
13827                         [(match_operand 1 "register_operand" "x")
13828                          (match_operand 2 "nonimmediate_operand" "xm")])
13829           (pc)
13830           (label_ref (match_operand 3 "" ""))))
13831    (clobber (reg:CCFP FPSR_REG))
13832    (clobber (reg:CCFP FLAGS_REG))]
13833   "TARGET_SSE_MATH
13834    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13835    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13836    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13837   "#")
13838
13839 (define_insn "*fp_jcc_2_387"
13840   [(set (pc)
13841         (if_then_else (match_operator 0 "comparison_operator"
13842                         [(match_operand 1 "register_operand" "f")
13843                          (match_operand 2 "register_operand" "f")])
13844           (pc)
13845           (label_ref (match_operand 3 "" ""))))
13846    (clobber (reg:CCFP FPSR_REG))
13847    (clobber (reg:CCFP FLAGS_REG))]
13848   "TARGET_CMOVE && TARGET_80387
13849    && FLOAT_MODE_P (GET_MODE (operands[1]))
13850    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13851    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13852   "#")
13853
13854 (define_insn "*fp_jcc_3_387"
13855   [(set (pc)
13856         (if_then_else (match_operator 0 "comparison_operator"
13857                         [(match_operand 1 "register_operand" "f")
13858                          (match_operand 2 "nonimmediate_operand" "fm")])
13859           (label_ref (match_operand 3 "" ""))
13860           (pc)))
13861    (clobber (reg:CCFP FPSR_REG))
13862    (clobber (reg:CCFP FLAGS_REG))
13863    (clobber (match_scratch:HI 4 "=a"))]
13864   "TARGET_80387
13865    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13866    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13867    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13868    && SELECT_CC_MODE (GET_CODE (operands[0]),
13869                       operands[1], operands[2]) == CCFPmode
13870    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13871   "#")
13872
13873 (define_insn "*fp_jcc_4_387"
13874   [(set (pc)
13875         (if_then_else (match_operator 0 "comparison_operator"
13876                         [(match_operand 1 "register_operand" "f")
13877                          (match_operand 2 "nonimmediate_operand" "fm")])
13878           (pc)
13879           (label_ref (match_operand 3 "" ""))))
13880    (clobber (reg:CCFP FPSR_REG))
13881    (clobber (reg:CCFP FLAGS_REG))
13882    (clobber (match_scratch:HI 4 "=a"))]
13883   "TARGET_80387
13884    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13885    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13886    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13887    && SELECT_CC_MODE (GET_CODE (operands[0]),
13888                       operands[1], operands[2]) == CCFPmode
13889    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13890   "#")
13891
13892 (define_insn "*fp_jcc_5_387"
13893   [(set (pc)
13894         (if_then_else (match_operator 0 "comparison_operator"
13895                         [(match_operand 1 "register_operand" "f")
13896                          (match_operand 2 "register_operand" "f")])
13897           (label_ref (match_operand 3 "" ""))
13898           (pc)))
13899    (clobber (reg:CCFP FPSR_REG))
13900    (clobber (reg:CCFP FLAGS_REG))
13901    (clobber (match_scratch:HI 4 "=a"))]
13902   "TARGET_80387
13903    && FLOAT_MODE_P (GET_MODE (operands[1]))
13904    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13905    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13906   "#")
13907
13908 (define_insn "*fp_jcc_6_387"
13909   [(set (pc)
13910         (if_then_else (match_operator 0 "comparison_operator"
13911                         [(match_operand 1 "register_operand" "f")
13912                          (match_operand 2 "register_operand" "f")])
13913           (pc)
13914           (label_ref (match_operand 3 "" ""))))
13915    (clobber (reg:CCFP FPSR_REG))
13916    (clobber (reg:CCFP FLAGS_REG))
13917    (clobber (match_scratch:HI 4 "=a"))]
13918   "TARGET_80387
13919    && FLOAT_MODE_P (GET_MODE (operands[1]))
13920    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13921    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13922   "#")
13923
13924 (define_insn "*fp_jcc_7_387"
13925   [(set (pc)
13926         (if_then_else (match_operator 0 "comparison_operator"
13927                         [(match_operand 1 "register_operand" "f")
13928                          (match_operand 2 "const0_operand" "X")])
13929           (label_ref (match_operand 3 "" ""))
13930           (pc)))
13931    (clobber (reg:CCFP FPSR_REG))
13932    (clobber (reg:CCFP FLAGS_REG))
13933    (clobber (match_scratch:HI 4 "=a"))]
13934   "TARGET_80387
13935    && FLOAT_MODE_P (GET_MODE (operands[1]))
13936    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13937    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13938    && SELECT_CC_MODE (GET_CODE (operands[0]),
13939                       operands[1], operands[2]) == CCFPmode
13940    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13941   "#")
13942
13943 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13944 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13945 ;; with a precedence over other operators and is always put in the first
13946 ;; place. Swap condition and operands to match ficom instruction.
13947
13948 (define_insn "*fp_jcc_8<mode>_387"
13949   [(set (pc)
13950         (if_then_else (match_operator 0 "comparison_operator"
13951                         [(match_operator 1 "float_operator"
13952                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13953                            (match_operand 3 "register_operand" "f,f")])
13954           (label_ref (match_operand 4 "" ""))
13955           (pc)))
13956    (clobber (reg:CCFP FPSR_REG))
13957    (clobber (reg:CCFP FLAGS_REG))
13958    (clobber (match_scratch:HI 5 "=a,a"))]
13959   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13960    && FLOAT_MODE_P (GET_MODE (operands[3]))
13961    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13962    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13963    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13964    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13965   "#")
13966
13967 (define_split
13968   [(set (pc)
13969         (if_then_else (match_operator 0 "comparison_operator"
13970                         [(match_operand 1 "register_operand" "")
13971                          (match_operand 2 "nonimmediate_operand" "")])
13972           (match_operand 3 "" "")
13973           (match_operand 4 "" "")))
13974    (clobber (reg:CCFP FPSR_REG))
13975    (clobber (reg:CCFP FLAGS_REG))]
13976   "reload_completed"
13977   [(const_int 0)]
13978 {
13979   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13980                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13981   DONE;
13982 })
13983
13984 (define_split
13985   [(set (pc)
13986         (if_then_else (match_operator 0 "comparison_operator"
13987                         [(match_operand 1 "register_operand" "")
13988                          (match_operand 2 "general_operand" "")])
13989           (match_operand 3 "" "")
13990           (match_operand 4 "" "")))
13991    (clobber (reg:CCFP FPSR_REG))
13992    (clobber (reg:CCFP FLAGS_REG))
13993    (clobber (match_scratch:HI 5 "=a"))]
13994   "reload_completed"
13995   [(const_int 0)]
13996 {
13997   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13998                         operands[3], operands[4], operands[5], NULL_RTX);
13999   DONE;
14000 })
14001
14002 (define_split
14003   [(set (pc)
14004         (if_then_else (match_operator 0 "comparison_operator"
14005                         [(match_operator 1 "float_operator"
14006                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14007                            (match_operand 3 "register_operand" "")])
14008           (match_operand 4 "" "")
14009           (match_operand 5 "" "")))
14010    (clobber (reg:CCFP FPSR_REG))
14011    (clobber (reg:CCFP FLAGS_REG))
14012    (clobber (match_scratch:HI 6 "=a"))]
14013   "reload_completed"
14014   [(const_int 0)]
14015 {
14016   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14017   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14018                         operands[3], operands[7],
14019                         operands[4], operands[5], operands[6], NULL_RTX);
14020   DONE;
14021 })
14022
14023 ;; %%% Kill this when reload knows how to do it.
14024 (define_split
14025   [(set (pc)
14026         (if_then_else (match_operator 0 "comparison_operator"
14027                         [(match_operator 1 "float_operator"
14028                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14029                            (match_operand 3 "register_operand" "")])
14030           (match_operand 4 "" "")
14031           (match_operand 5 "" "")))
14032    (clobber (reg:CCFP FPSR_REG))
14033    (clobber (reg:CCFP FLAGS_REG))
14034    (clobber (match_scratch:HI 6 "=a"))]
14035   "reload_completed"
14036   [(const_int 0)]
14037 {
14038   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14039   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14040   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14041                         operands[3], operands[7],
14042                         operands[4], operands[5], operands[6], operands[2]);
14043   DONE;
14044 })
14045 \f
14046 ;; Unconditional and other jump instructions
14047
14048 (define_insn "jump"
14049   [(set (pc)
14050         (label_ref (match_operand 0 "" "")))]
14051   ""
14052   "jmp\t%l0"
14053   [(set_attr "type" "ibr")
14054    (set (attr "length")
14055            (if_then_else (and (ge (minus (match_dup 0) (pc))
14056                                   (const_int -126))
14057                               (lt (minus (match_dup 0) (pc))
14058                                   (const_int 128)))
14059              (const_int 2)
14060              (const_int 5)))
14061    (set_attr "modrm" "0")])
14062
14063 (define_expand "indirect_jump"
14064   [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
14065   ""
14066   "")
14067
14068 (define_insn "*indirect_jump"
14069   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14070   "!TARGET_64BIT"
14071   "jmp\t%A0"
14072   [(set_attr "type" "ibr")
14073    (set_attr "length_immediate" "0")])
14074
14075 (define_insn "*indirect_jump_rtx64"
14076   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14077   "TARGET_64BIT"
14078   "jmp\t%A0"
14079   [(set_attr "type" "ibr")
14080    (set_attr "length_immediate" "0")])
14081
14082 (define_expand "tablejump"
14083   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14084               (use (label_ref (match_operand 1 "" "")))])]
14085   ""
14086 {
14087   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14088      relative.  Convert the relative address to an absolute address.  */
14089   if (flag_pic)
14090     {
14091       rtx op0, op1;
14092       enum rtx_code code;
14093
14094       if (TARGET_64BIT)
14095         {
14096           code = PLUS;
14097           op0 = operands[0];
14098           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14099         }
14100       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14101         {
14102           code = PLUS;
14103           op0 = operands[0];
14104           op1 = pic_offset_table_rtx;
14105         }
14106       else
14107         {
14108           code = MINUS;
14109           op0 = pic_offset_table_rtx;
14110           op1 = operands[0];
14111         }
14112
14113       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14114                                          OPTAB_DIRECT);
14115     }
14116 })
14117
14118 (define_insn "*tablejump_1"
14119   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14120    (use (label_ref (match_operand 1 "" "")))]
14121   "!TARGET_64BIT"
14122   "jmp\t%A0"
14123   [(set_attr "type" "ibr")
14124    (set_attr "length_immediate" "0")])
14125
14126 (define_insn "*tablejump_1_rtx64"
14127   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14128    (use (label_ref (match_operand 1 "" "")))]
14129   "TARGET_64BIT"
14130   "jmp\t%A0"
14131   [(set_attr "type" "ibr")
14132    (set_attr "length_immediate" "0")])
14133 \f
14134 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14135
14136 (define_peephole2
14137   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14138    (set (match_operand:QI 1 "register_operand" "")
14139         (match_operator:QI 2 "ix86_comparison_operator"
14140           [(reg FLAGS_REG) (const_int 0)]))
14141    (set (match_operand 3 "q_regs_operand" "")
14142         (zero_extend (match_dup 1)))]
14143   "(peep2_reg_dead_p (3, operands[1])
14144     || operands_match_p (operands[1], operands[3]))
14145    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14146   [(set (match_dup 4) (match_dup 0))
14147    (set (strict_low_part (match_dup 5))
14148         (match_dup 2))]
14149 {
14150   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14151   operands[5] = gen_lowpart (QImode, operands[3]);
14152   ix86_expand_clear (operands[3]);
14153 })
14154
14155 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14156
14157 (define_peephole2
14158   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14159    (set (match_operand:QI 1 "register_operand" "")
14160         (match_operator:QI 2 "ix86_comparison_operator"
14161           [(reg FLAGS_REG) (const_int 0)]))
14162    (parallel [(set (match_operand 3 "q_regs_operand" "")
14163                    (zero_extend (match_dup 1)))
14164               (clobber (reg:CC FLAGS_REG))])]
14165   "(peep2_reg_dead_p (3, operands[1])
14166     || operands_match_p (operands[1], operands[3]))
14167    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14168   [(set (match_dup 4) (match_dup 0))
14169    (set (strict_low_part (match_dup 5))
14170         (match_dup 2))]
14171 {
14172   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14173   operands[5] = gen_lowpart (QImode, operands[3]);
14174   ix86_expand_clear (operands[3]);
14175 })
14176 \f
14177 ;; Call instructions.
14178
14179 ;; The predicates normally associated with named expanders are not properly
14180 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14181 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14182
14183 ;; Call subroutine returning no value.
14184
14185 (define_expand "call_pop"
14186   [(parallel [(call (match_operand:QI 0 "" "")
14187                     (match_operand:SI 1 "" ""))
14188               (set (reg:SI SP_REG)
14189                    (plus:SI (reg:SI SP_REG)
14190                             (match_operand:SI 3 "" "")))])]
14191   "!TARGET_64BIT"
14192 {
14193   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14194   DONE;
14195 })
14196
14197 (define_insn "*call_pop_0"
14198   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14199          (match_operand:SI 1 "" ""))
14200    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14201                             (match_operand:SI 2 "immediate_operand" "")))]
14202   "!TARGET_64BIT"
14203 {
14204   if (SIBLING_CALL_P (insn))
14205     return "jmp\t%P0";
14206   else
14207     return "call\t%P0";
14208 }
14209   [(set_attr "type" "call")])
14210
14211 (define_insn "*call_pop_1"
14212   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14213          (match_operand:SI 1 "" ""))
14214    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14215                             (match_operand:SI 2 "immediate_operand" "i")))]
14216   "!TARGET_64BIT"
14217 {
14218   if (constant_call_address_operand (operands[0], Pmode))
14219     {
14220       if (SIBLING_CALL_P (insn))
14221         return "jmp\t%P0";
14222       else
14223         return "call\t%P0";
14224     }
14225   if (SIBLING_CALL_P (insn))
14226     return "jmp\t%A0";
14227   else
14228     return "call\t%A0";
14229 }
14230   [(set_attr "type" "call")])
14231
14232 (define_expand "call"
14233   [(call (match_operand:QI 0 "" "")
14234          (match_operand 1 "" ""))
14235    (use (match_operand 2 "" ""))]
14236   ""
14237 {
14238   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14239   DONE;
14240 })
14241
14242 (define_expand "sibcall"
14243   [(call (match_operand:QI 0 "" "")
14244          (match_operand 1 "" ""))
14245    (use (match_operand 2 "" ""))]
14246   ""
14247 {
14248   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14249   DONE;
14250 })
14251
14252 (define_insn "*call_0"
14253   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14254          (match_operand 1 "" ""))]
14255   ""
14256 {
14257   if (SIBLING_CALL_P (insn))
14258     return "jmp\t%P0";
14259   else
14260     return "call\t%P0";
14261 }
14262   [(set_attr "type" "call")])
14263
14264 (define_insn "*call_1"
14265   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14266          (match_operand 1 "" ""))]
14267   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14268 {
14269   if (constant_call_address_operand (operands[0], Pmode))
14270     return "call\t%P0";
14271   return "call\t%A0";
14272 }
14273   [(set_attr "type" "call")])
14274
14275 (define_insn "*sibcall_1"
14276   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14277          (match_operand 1 "" ""))]
14278   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14279 {
14280   if (constant_call_address_operand (operands[0], Pmode))
14281     return "jmp\t%P0";
14282   return "jmp\t%A0";
14283 }
14284   [(set_attr "type" "call")])
14285
14286 (define_insn "*call_1_rex64"
14287   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14288          (match_operand 1 "" ""))]
14289   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14290 {
14291   if (constant_call_address_operand (operands[0], Pmode))
14292     return "call\t%P0";
14293   return "call\t%A0";
14294 }
14295   [(set_attr "type" "call")])
14296
14297 (define_insn "*sibcall_1_rex64"
14298   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14299          (match_operand 1 "" ""))]
14300   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14301   "jmp\t%P0"
14302   [(set_attr "type" "call")])
14303
14304 (define_insn "*sibcall_1_rex64_v"
14305   [(call (mem:QI (reg:DI R11_REG))
14306          (match_operand 0 "" ""))]
14307   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14308   "jmp\t*%%r11"
14309   [(set_attr "type" "call")])
14310
14311
14312 ;; Call subroutine, returning value in operand 0
14313
14314 (define_expand "call_value_pop"
14315   [(parallel [(set (match_operand 0 "" "")
14316                    (call (match_operand:QI 1 "" "")
14317                          (match_operand:SI 2 "" "")))
14318               (set (reg:SI SP_REG)
14319                    (plus:SI (reg:SI SP_REG)
14320                             (match_operand:SI 4 "" "")))])]
14321   "!TARGET_64BIT"
14322 {
14323   ix86_expand_call (operands[0], operands[1], operands[2],
14324                     operands[3], operands[4], 0);
14325   DONE;
14326 })
14327
14328 (define_expand "call_value"
14329   [(set (match_operand 0 "" "")
14330         (call (match_operand:QI 1 "" "")
14331               (match_operand:SI 2 "" "")))
14332    (use (match_operand:SI 3 "" ""))]
14333   ;; Operand 2 not used on the i386.
14334   ""
14335 {
14336   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14337   DONE;
14338 })
14339
14340 (define_expand "sibcall_value"
14341   [(set (match_operand 0 "" "")
14342         (call (match_operand:QI 1 "" "")
14343               (match_operand:SI 2 "" "")))
14344    (use (match_operand:SI 3 "" ""))]
14345   ;; Operand 2 not used on the i386.
14346   ""
14347 {
14348   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14349   DONE;
14350 })
14351
14352 ;; Call subroutine returning any type.
14353
14354 (define_expand "untyped_call"
14355   [(parallel [(call (match_operand 0 "" "")
14356                     (const_int 0))
14357               (match_operand 1 "" "")
14358               (match_operand 2 "" "")])]
14359   ""
14360 {
14361   int i;
14362
14363   /* In order to give reg-stack an easier job in validating two
14364      coprocessor registers as containing a possible return value,
14365      simply pretend the untyped call returns a complex long double
14366      value.  */
14367
14368   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14369                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14370                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14371                     NULL, 0);
14372
14373   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14374     {
14375       rtx set = XVECEXP (operands[2], 0, i);
14376       emit_move_insn (SET_DEST (set), SET_SRC (set));
14377     }
14378
14379   /* The optimizer does not know that the call sets the function value
14380      registers we stored in the result block.  We avoid problems by
14381      claiming that all hard registers are used and clobbered at this
14382      point.  */
14383   emit_insn (gen_blockage (const0_rtx));
14384
14385   DONE;
14386 })
14387 \f
14388 ;; Prologue and epilogue instructions
14389
14390 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14391 ;; all of memory.  This blocks insns from being moved across this point.
14392
14393 (define_insn "blockage"
14394   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14395   ""
14396   ""
14397   [(set_attr "length" "0")])
14398
14399 ;; Insn emitted into the body of a function to return from a function.
14400 ;; This is only done if the function's epilogue is known to be simple.
14401 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14402
14403 (define_expand "return"
14404   [(return)]
14405   "ix86_can_use_return_insn_p ()"
14406 {
14407   if (current_function_pops_args)
14408     {
14409       rtx popc = GEN_INT (current_function_pops_args);
14410       emit_jump_insn (gen_return_pop_internal (popc));
14411       DONE;
14412     }
14413 })
14414
14415 (define_insn "return_internal"
14416   [(return)]
14417   "reload_completed"
14418   "ret"
14419   [(set_attr "length" "1")
14420    (set_attr "length_immediate" "0")
14421    (set_attr "modrm" "0")])
14422
14423 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14424 ;; instruction Athlon and K8 have.
14425
14426 (define_insn "return_internal_long"
14427   [(return)
14428    (unspec [(const_int 0)] UNSPEC_REP)]
14429   "reload_completed"
14430   "rep {;} ret"
14431   [(set_attr "length" "1")
14432    (set_attr "length_immediate" "0")
14433    (set_attr "prefix_rep" "1")
14434    (set_attr "modrm" "0")])
14435
14436 (define_insn "return_pop_internal"
14437   [(return)
14438    (use (match_operand:SI 0 "const_int_operand" ""))]
14439   "reload_completed"
14440   "ret\t%0"
14441   [(set_attr "length" "3")
14442    (set_attr "length_immediate" "2")
14443    (set_attr "modrm" "0")])
14444
14445 (define_insn "return_indirect_internal"
14446   [(return)
14447    (use (match_operand:SI 0 "register_operand" "r"))]
14448   "reload_completed"
14449   "jmp\t%A0"
14450   [(set_attr "type" "ibr")
14451    (set_attr "length_immediate" "0")])
14452
14453 (define_insn "nop"
14454   [(const_int 0)]
14455   ""
14456   "nop"
14457   [(set_attr "length" "1")
14458    (set_attr "length_immediate" "0")
14459    (set_attr "modrm" "0")])
14460
14461 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14462 ;; branch prediction penalty for the third jump in a 16-byte
14463 ;; block on K8.
14464
14465 (define_insn "align"
14466   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14467   ""
14468 {
14469 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14470   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14471 #else
14472   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14473      The align insn is used to avoid 3 jump instructions in the row to improve
14474      branch prediction and the benefits hardly outweigh the cost of extra 8
14475      nops on the average inserted by full alignment pseudo operation.  */
14476 #endif
14477   return "";
14478 }
14479   [(set_attr "length" "16")])
14480
14481 (define_expand "prologue"
14482   [(const_int 1)]
14483   ""
14484   "ix86_expand_prologue (); DONE;")
14485
14486 (define_insn "set_got"
14487   [(set (match_operand:SI 0 "register_operand" "=r")
14488         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14489    (clobber (reg:CC FLAGS_REG))]
14490   "!TARGET_64BIT"
14491   { return output_set_got (operands[0], NULL_RTX); }
14492   [(set_attr "type" "multi")
14493    (set_attr "length" "12")])
14494
14495 (define_insn "set_got_labelled"
14496   [(set (match_operand:SI 0 "register_operand" "=r")
14497         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14498          UNSPEC_SET_GOT))
14499    (clobber (reg:CC FLAGS_REG))]
14500   "!TARGET_64BIT"
14501   { return output_set_got (operands[0], operands[1]); }
14502   [(set_attr "type" "multi")
14503    (set_attr "length" "12")])
14504
14505 (define_insn "set_got_rex64"
14506   [(set (match_operand:DI 0 "register_operand" "=r")
14507         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14508   "TARGET_64BIT"
14509   "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14510   [(set_attr "type" "lea")
14511    (set_attr "length" "6")])
14512
14513 (define_expand "epilogue"
14514   [(const_int 1)]
14515   ""
14516   "ix86_expand_epilogue (1); DONE;")
14517
14518 (define_expand "sibcall_epilogue"
14519   [(const_int 1)]
14520   ""
14521   "ix86_expand_epilogue (0); DONE;")
14522
14523 (define_expand "eh_return"
14524   [(use (match_operand 0 "register_operand" ""))]
14525   ""
14526 {
14527   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14528
14529   /* Tricky bit: we write the address of the handler to which we will
14530      be returning into someone else's stack frame, one word below the
14531      stack address we wish to restore.  */
14532   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14533   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14534   tmp = gen_rtx_MEM (Pmode, tmp);
14535   emit_move_insn (tmp, ra);
14536
14537   if (Pmode == SImode)
14538     emit_jump_insn (gen_eh_return_si (sa));
14539   else
14540     emit_jump_insn (gen_eh_return_di (sa));
14541   emit_barrier ();
14542   DONE;
14543 })
14544
14545 (define_insn_and_split "eh_return_si"
14546   [(set (pc)
14547         (unspec [(match_operand:SI 0 "register_operand" "c")]
14548                  UNSPEC_EH_RETURN))]
14549   "!TARGET_64BIT"
14550   "#"
14551   "reload_completed"
14552   [(const_int 1)]
14553   "ix86_expand_epilogue (2); DONE;")
14554
14555 (define_insn_and_split "eh_return_di"
14556   [(set (pc)
14557         (unspec [(match_operand:DI 0 "register_operand" "c")]
14558                  UNSPEC_EH_RETURN))]
14559   "TARGET_64BIT"
14560   "#"
14561   "reload_completed"
14562   [(const_int 1)]
14563   "ix86_expand_epilogue (2); DONE;")
14564
14565 (define_insn "leave"
14566   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14567    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14568    (clobber (mem:BLK (scratch)))]
14569   "!TARGET_64BIT"
14570   "leave"
14571   [(set_attr "type" "leave")])
14572
14573 (define_insn "leave_rex64"
14574   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14575    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14576    (clobber (mem:BLK (scratch)))]
14577   "TARGET_64BIT"
14578   "leave"
14579   [(set_attr "type" "leave")])
14580 \f
14581 (define_expand "ffssi2"
14582   [(parallel
14583      [(set (match_operand:SI 0 "register_operand" "")
14584            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14585       (clobber (match_scratch:SI 2 ""))
14586       (clobber (reg:CC FLAGS_REG))])]
14587   ""
14588   "")
14589
14590 (define_insn_and_split "*ffs_cmove"
14591   [(set (match_operand:SI 0 "register_operand" "=r")
14592         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14593    (clobber (match_scratch:SI 2 "=&r"))
14594    (clobber (reg:CC FLAGS_REG))]
14595   "TARGET_CMOVE"
14596   "#"
14597   "&& reload_completed"
14598   [(set (match_dup 2) (const_int -1))
14599    (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14600               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14601    (set (match_dup 0) (if_then_else:SI
14602                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14603                         (match_dup 2)
14604                         (match_dup 0)))
14605    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14606               (clobber (reg:CC FLAGS_REG))])]
14607   "")
14608
14609 (define_insn_and_split "*ffs_no_cmove"
14610   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14611         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14612    (clobber (match_scratch:SI 2 "=&q"))
14613    (clobber (reg:CC FLAGS_REG))]
14614   ""
14615   "#"
14616   "reload_completed"
14617   [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14618               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14619    (set (strict_low_part (match_dup 3))
14620         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14621    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14622               (clobber (reg:CC FLAGS_REG))])
14623    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14624               (clobber (reg:CC FLAGS_REG))])
14625    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14626               (clobber (reg:CC FLAGS_REG))])]
14627 {
14628   operands[3] = gen_lowpart (QImode, operands[2]);
14629   ix86_expand_clear (operands[2]);
14630 })
14631
14632 (define_insn "*ffssi_1"
14633   [(set (reg:CCZ FLAGS_REG)
14634         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14635                      (const_int 0)))
14636    (set (match_operand:SI 0 "register_operand" "=r")
14637         (ctz:SI (match_dup 1)))]
14638   ""
14639   "bsf{l}\t{%1, %0|%0, %1}"
14640   [(set_attr "prefix_0f" "1")])
14641
14642 (define_expand "ffsdi2"
14643   [(parallel
14644      [(set (match_operand:DI 0 "register_operand" "")
14645            (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14646       (clobber (match_scratch:DI 2 ""))
14647       (clobber (reg:CC FLAGS_REG))])]
14648   "TARGET_64BIT && TARGET_CMOVE"
14649   "")
14650
14651 (define_insn_and_split "*ffs_rex64"
14652   [(set (match_operand:DI 0 "register_operand" "=r")
14653         (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14654    (clobber (match_scratch:DI 2 "=&r"))
14655    (clobber (reg:CC FLAGS_REG))]
14656   "TARGET_64BIT && TARGET_CMOVE"
14657   "#"
14658   "&& reload_completed"
14659   [(set (match_dup 2) (const_int -1))
14660    (parallel [(set (reg:CCZ FLAGS_REG)
14661                    (compare:CCZ (match_dup 1) (const_int 0)))
14662               (set (match_dup 0) (ctz:DI (match_dup 1)))])
14663    (set (match_dup 0) (if_then_else:DI
14664                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14665                         (match_dup 2)
14666                         (match_dup 0)))
14667    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14668               (clobber (reg:CC FLAGS_REG))])]
14669   "")
14670
14671 (define_insn "*ffsdi_1"
14672   [(set (reg:CCZ FLAGS_REG)
14673         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14674                      (const_int 0)))
14675    (set (match_operand:DI 0 "register_operand" "=r")
14676         (ctz:DI (match_dup 1)))]
14677   "TARGET_64BIT"
14678   "bsf{q}\t{%1, %0|%0, %1}"
14679   [(set_attr "prefix_0f" "1")])
14680
14681 (define_insn "ctzsi2"
14682   [(set (match_operand:SI 0 "register_operand" "=r")
14683         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14684    (clobber (reg:CC FLAGS_REG))]
14685   ""
14686   "bsf{l}\t{%1, %0|%0, %1}"
14687   [(set_attr "prefix_0f" "1")])
14688
14689 (define_insn "ctzdi2"
14690   [(set (match_operand:DI 0 "register_operand" "=r")
14691         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14692    (clobber (reg:CC FLAGS_REG))]
14693   "TARGET_64BIT"
14694   "bsf{q}\t{%1, %0|%0, %1}"
14695   [(set_attr "prefix_0f" "1")])
14696
14697 (define_expand "clzsi2"
14698   [(parallel
14699      [(set (match_operand:SI 0 "register_operand" "")
14700            (minus:SI (const_int 31)
14701                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14702       (clobber (reg:CC FLAGS_REG))])
14703    (parallel
14704      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14705       (clobber (reg:CC FLAGS_REG))])]
14706   ""
14707 {
14708   if (TARGET_ABM)
14709     {
14710       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14711       DONE;
14712     }
14713 })
14714
14715 (define_insn "clzsi2_abm"
14716   [(set (match_operand:SI 0 "register_operand" "=r")
14717         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14718    (clobber (reg:CC FLAGS_REG))]
14719   "TARGET_ABM"
14720   "lzcnt{l}\t{%1, %0|%0, %1}"
14721   [(set_attr "prefix_rep" "1")
14722    (set_attr "type" "bitmanip")
14723    (set_attr "mode" "SI")])
14724
14725 (define_insn "*bsr"
14726   [(set (match_operand:SI 0 "register_operand" "=r")
14727         (minus:SI (const_int 31)
14728                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14729    (clobber (reg:CC FLAGS_REG))]
14730   ""
14731   "bsr{l}\t{%1, %0|%0, %1}"
14732   [(set_attr "prefix_0f" "1")
14733    (set_attr "mode" "SI")])
14734
14735 (define_insn "popcountsi2"
14736   [(set (match_operand:SI 0 "register_operand" "=r")
14737         (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14738    (clobber (reg:CC FLAGS_REG))]
14739   "TARGET_POPCNT"
14740   "popcnt{l}\t{%1, %0|%0, %1}"
14741   [(set_attr "prefix_rep" "1")
14742    (set_attr "type" "bitmanip")
14743    (set_attr "mode" "SI")])
14744
14745 (define_insn "*popcountsi2_cmp"
14746   [(set (reg FLAGS_REG)
14747         (compare
14748           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14749           (const_int 0)))
14750    (set (match_operand:SI 0 "register_operand" "=r")
14751         (popcount:SI (match_dup 1)))]
14752   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14753   "popcnt{l}\t{%1, %0|%0, %1}"
14754   [(set_attr "prefix_rep" "1")
14755    (set_attr "type" "bitmanip")
14756    (set_attr "mode" "SI")])
14757
14758 (define_insn "*popcountsi2_cmp_zext"
14759   [(set (reg FLAGS_REG)
14760         (compare
14761           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14762           (const_int 0)))
14763    (set (match_operand:DI 0 "register_operand" "=r")
14764         (zero_extend:DI(popcount:SI (match_dup 1))))]
14765   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14766   "popcnt{l}\t{%1, %0|%0, %1}"
14767   [(set_attr "prefix_rep" "1")
14768    (set_attr "type" "bitmanip")
14769    (set_attr "mode" "SI")])
14770
14771 (define_insn "bswapsi2"
14772   [(set (match_operand:SI 0 "register_operand" "=r")
14773         (bswap:SI (match_operand:SI 1 "register_operand" "0")))
14774    (clobber (reg:CC FLAGS_REG))]
14775   "TARGET_BSWAP"
14776   "bswap\t%k0"
14777   [(set_attr "prefix_0f" "1")
14778    (set_attr "length" "2")])
14779
14780 (define_insn "bswapdi2"
14781   [(set (match_operand:DI 0 "register_operand" "=r")
14782         (bswap:DI (match_operand:DI 1 "register_operand" "0")))
14783    (clobber (reg:CC FLAGS_REG))]
14784   "TARGET_64BIT && TARGET_BSWAP"
14785   "bswap\t%0"
14786   [(set_attr "prefix_0f" "1")
14787    (set_attr "length" "3")])
14788
14789 (define_expand "clzdi2"
14790   [(parallel
14791      [(set (match_operand:DI 0 "register_operand" "")
14792            (minus:DI (const_int 63)
14793                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14794       (clobber (reg:CC FLAGS_REG))])
14795    (parallel
14796      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14797       (clobber (reg:CC FLAGS_REG))])]
14798   "TARGET_64BIT"
14799 {
14800   if (TARGET_ABM)
14801     {
14802       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14803       DONE;
14804     }
14805 })
14806
14807 (define_insn "clzdi2_abm"
14808   [(set (match_operand:DI 0 "register_operand" "=r")
14809         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14810    (clobber (reg:CC FLAGS_REG))]
14811   "TARGET_64BIT && TARGET_ABM"
14812   "lzcnt{q}\t{%1, %0|%0, %1}"
14813   [(set_attr "prefix_rep" "1")
14814    (set_attr "type" "bitmanip")
14815    (set_attr "mode" "DI")])
14816
14817 (define_insn "*bsr_rex64"
14818   [(set (match_operand:DI 0 "register_operand" "=r")
14819         (minus:DI (const_int 63)
14820                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14821    (clobber (reg:CC FLAGS_REG))]
14822   "TARGET_64BIT"
14823   "bsr{q}\t{%1, %0|%0, %1}"
14824   [(set_attr "prefix_0f" "1")
14825    (set_attr "mode" "DI")])
14826
14827 (define_insn "popcountdi2"
14828   [(set (match_operand:DI 0 "register_operand" "=r")
14829         (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14830    (clobber (reg:CC FLAGS_REG))]
14831   "TARGET_64BIT && TARGET_POPCNT"
14832   "popcnt{q}\t{%1, %0|%0, %1}"
14833   [(set_attr "prefix_rep" "1")
14834    (set_attr "type" "bitmanip")
14835    (set_attr "mode" "DI")])
14836
14837 (define_insn "*popcountdi2_cmp"
14838   [(set (reg FLAGS_REG)
14839         (compare
14840           (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
14841           (const_int 0)))
14842    (set (match_operand:DI 0 "register_operand" "=r")
14843         (popcount:DI (match_dup 1)))]
14844   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14845   "popcnt{q}\t{%1, %0|%0, %1}"
14846   [(set_attr "prefix_rep" "1")
14847    (set_attr "type" "bitmanip")
14848    (set_attr "mode" "DI")])
14849
14850 (define_expand "clzhi2"
14851   [(parallel
14852      [(set (match_operand:HI 0 "register_operand" "")
14853            (minus:HI (const_int 15)
14854                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
14855       (clobber (reg:CC FLAGS_REG))])
14856    (parallel
14857      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
14858       (clobber (reg:CC FLAGS_REG))])]
14859   ""
14860 {
14861   if (TARGET_ABM)
14862     {
14863       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
14864       DONE;
14865     }
14866 })
14867
14868 (define_insn "clzhi2_abm"
14869   [(set (match_operand:HI 0 "register_operand" "=r")
14870         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
14871    (clobber (reg:CC FLAGS_REG))]
14872   "TARGET_ABM"
14873   "lzcnt{w}\t{%1, %0|%0, %1}"
14874   [(set_attr "prefix_rep" "1")
14875    (set_attr "type" "bitmanip")
14876    (set_attr "mode" "HI")])
14877
14878 (define_insn "*bsrhi"
14879   [(set (match_operand:HI 0 "register_operand" "=r")
14880         (minus:HI (const_int 15)
14881                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
14882    (clobber (reg:CC FLAGS_REG))]
14883   ""
14884   "bsr{w}\t{%1, %0|%0, %1}"
14885   [(set_attr "prefix_0f" "1")
14886    (set_attr "mode" "HI")])
14887
14888 (define_insn "popcounthi2"
14889   [(set (match_operand:HI 0 "register_operand" "=r")
14890         (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
14891    (clobber (reg:CC FLAGS_REG))]
14892   "TARGET_POPCNT"
14893   "popcnt{w}\t{%1, %0|%0, %1}"
14894   [(set_attr "prefix_rep" "1")
14895    (set_attr "type" "bitmanip")
14896    (set_attr "mode" "HI")])
14897
14898 (define_insn "*popcounthi2_cmp"
14899   [(set (reg FLAGS_REG)
14900         (compare
14901           (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
14902           (const_int 0)))
14903    (set (match_operand:HI 0 "register_operand" "=r")
14904         (popcount:HI (match_dup 1)))]
14905   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14906   "popcnt{w}\t{%1, %0|%0, %1}"
14907   [(set_attr "prefix_rep" "1")
14908    (set_attr "type" "bitmanip")
14909    (set_attr "mode" "HI")])
14910 \f
14911 ;; Thread-local storage patterns for ELF.
14912 ;;
14913 ;; Note that these code sequences must appear exactly as shown
14914 ;; in order to allow linker relaxation.
14915
14916 (define_insn "*tls_global_dynamic_32_gnu"
14917   [(set (match_operand:SI 0 "register_operand" "=a")
14918         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14919                     (match_operand:SI 2 "tls_symbolic_operand" "")
14920                     (match_operand:SI 3 "call_insn_operand" "")]
14921                     UNSPEC_TLS_GD))
14922    (clobber (match_scratch:SI 4 "=d"))
14923    (clobber (match_scratch:SI 5 "=c"))
14924    (clobber (reg:CC FLAGS_REG))]
14925   "!TARGET_64BIT && TARGET_GNU_TLS"
14926   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14927   [(set_attr "type" "multi")
14928    (set_attr "length" "12")])
14929
14930 (define_insn "*tls_global_dynamic_32_sun"
14931   [(set (match_operand:SI 0 "register_operand" "=a")
14932         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14933                     (match_operand:SI 2 "tls_symbolic_operand" "")
14934                     (match_operand:SI 3 "call_insn_operand" "")]
14935                     UNSPEC_TLS_GD))
14936    (clobber (match_scratch:SI 4 "=d"))
14937    (clobber (match_scratch:SI 5 "=c"))
14938    (clobber (reg:CC FLAGS_REG))]
14939   "!TARGET_64BIT && TARGET_SUN_TLS"
14940   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14941         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14942   [(set_attr "type" "multi")
14943    (set_attr "length" "14")])
14944
14945 (define_expand "tls_global_dynamic_32"
14946   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14947                    (unspec:SI
14948                     [(match_dup 2)
14949                      (match_operand:SI 1 "tls_symbolic_operand" "")
14950                      (match_dup 3)]
14951                     UNSPEC_TLS_GD))
14952               (clobber (match_scratch:SI 4 ""))
14953               (clobber (match_scratch:SI 5 ""))
14954               (clobber (reg:CC FLAGS_REG))])]
14955   ""
14956 {
14957   if (flag_pic)
14958     operands[2] = pic_offset_table_rtx;
14959   else
14960     {
14961       operands[2] = gen_reg_rtx (Pmode);
14962       emit_insn (gen_set_got (operands[2]));
14963     }
14964   if (TARGET_GNU2_TLS)
14965     {
14966        emit_insn (gen_tls_dynamic_gnu2_32
14967                   (operands[0], operands[1], operands[2]));
14968        DONE;
14969     }
14970   operands[3] = ix86_tls_get_addr ();
14971 })
14972
14973 (define_insn "*tls_global_dynamic_64"
14974   [(set (match_operand:DI 0 "register_operand" "=a")
14975         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14976                  (match_operand:DI 3 "" "")))
14977    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14978               UNSPEC_TLS_GD)]
14979   "TARGET_64BIT"
14980   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14981   [(set_attr "type" "multi")
14982    (set_attr "length" "16")])
14983
14984 (define_expand "tls_global_dynamic_64"
14985   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14986                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14987               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14988                          UNSPEC_TLS_GD)])]
14989   ""
14990 {
14991   if (TARGET_GNU2_TLS)
14992     {
14993        emit_insn (gen_tls_dynamic_gnu2_64
14994                   (operands[0], operands[1]));
14995        DONE;
14996     }
14997   operands[2] = ix86_tls_get_addr ();
14998 })
14999
15000 (define_insn "*tls_local_dynamic_base_32_gnu"
15001   [(set (match_operand:SI 0 "register_operand" "=a")
15002         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15003                     (match_operand:SI 2 "call_insn_operand" "")]
15004                    UNSPEC_TLS_LD_BASE))
15005    (clobber (match_scratch:SI 3 "=d"))
15006    (clobber (match_scratch:SI 4 "=c"))
15007    (clobber (reg:CC FLAGS_REG))]
15008   "!TARGET_64BIT && TARGET_GNU_TLS"
15009   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15010   [(set_attr "type" "multi")
15011    (set_attr "length" "11")])
15012
15013 (define_insn "*tls_local_dynamic_base_32_sun"
15014   [(set (match_operand:SI 0 "register_operand" "=a")
15015         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15016                     (match_operand:SI 2 "call_insn_operand" "")]
15017                    UNSPEC_TLS_LD_BASE))
15018    (clobber (match_scratch:SI 3 "=d"))
15019    (clobber (match_scratch:SI 4 "=c"))
15020    (clobber (reg:CC FLAGS_REG))]
15021   "!TARGET_64BIT && TARGET_SUN_TLS"
15022   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15023         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15024   [(set_attr "type" "multi")
15025    (set_attr "length" "13")])
15026
15027 (define_expand "tls_local_dynamic_base_32"
15028   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15029                    (unspec:SI [(match_dup 1) (match_dup 2)]
15030                               UNSPEC_TLS_LD_BASE))
15031               (clobber (match_scratch:SI 3 ""))
15032               (clobber (match_scratch:SI 4 ""))
15033               (clobber (reg:CC FLAGS_REG))])]
15034   ""
15035 {
15036   if (flag_pic)
15037     operands[1] = pic_offset_table_rtx;
15038   else
15039     {
15040       operands[1] = gen_reg_rtx (Pmode);
15041       emit_insn (gen_set_got (operands[1]));
15042     }
15043   if (TARGET_GNU2_TLS)
15044     {
15045        emit_insn (gen_tls_dynamic_gnu2_32
15046                   (operands[0], ix86_tls_module_base (), operands[1]));
15047        DONE;
15048     }
15049   operands[2] = ix86_tls_get_addr ();
15050 })
15051
15052 (define_insn "*tls_local_dynamic_base_64"
15053   [(set (match_operand:DI 0 "register_operand" "=a")
15054         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15055                  (match_operand:DI 2 "" "")))
15056    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15057   "TARGET_64BIT"
15058   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15059   [(set_attr "type" "multi")
15060    (set_attr "length" "12")])
15061
15062 (define_expand "tls_local_dynamic_base_64"
15063   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15064                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15065               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15066   ""
15067 {
15068   if (TARGET_GNU2_TLS)
15069     {
15070        emit_insn (gen_tls_dynamic_gnu2_64
15071                   (operands[0], ix86_tls_module_base ()));
15072        DONE;
15073     }
15074   operands[1] = ix86_tls_get_addr ();
15075 })
15076
15077 ;; Local dynamic of a single variable is a lose.  Show combine how
15078 ;; to convert that back to global dynamic.
15079
15080 (define_insn_and_split "*tls_local_dynamic_32_once"
15081   [(set (match_operand:SI 0 "register_operand" "=a")
15082         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15083                              (match_operand:SI 2 "call_insn_operand" "")]
15084                             UNSPEC_TLS_LD_BASE)
15085                  (const:SI (unspec:SI
15086                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15087                             UNSPEC_DTPOFF))))
15088    (clobber (match_scratch:SI 4 "=d"))
15089    (clobber (match_scratch:SI 5 "=c"))
15090    (clobber (reg:CC FLAGS_REG))]
15091   ""
15092   "#"
15093   ""
15094   [(parallel [(set (match_dup 0)
15095                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15096                               UNSPEC_TLS_GD))
15097               (clobber (match_dup 4))
15098               (clobber (match_dup 5))
15099               (clobber (reg:CC FLAGS_REG))])]
15100   "")
15101
15102 ;; Load and add the thread base pointer from %gs:0.
15103
15104 (define_insn "*load_tp_si"
15105   [(set (match_operand:SI 0 "register_operand" "=r")
15106         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15107   "!TARGET_64BIT"
15108   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15109   [(set_attr "type" "imov")
15110    (set_attr "modrm" "0")
15111    (set_attr "length" "7")
15112    (set_attr "memory" "load")
15113    (set_attr "imm_disp" "false")])
15114
15115 (define_insn "*add_tp_si"
15116   [(set (match_operand:SI 0 "register_operand" "=r")
15117         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15118                  (match_operand:SI 1 "register_operand" "0")))
15119    (clobber (reg:CC FLAGS_REG))]
15120   "!TARGET_64BIT"
15121   "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15122   [(set_attr "type" "alu")
15123    (set_attr "modrm" "0")
15124    (set_attr "length" "7")
15125    (set_attr "memory" "load")
15126    (set_attr "imm_disp" "false")])
15127
15128 (define_insn "*load_tp_di"
15129   [(set (match_operand:DI 0 "register_operand" "=r")
15130         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15131   "TARGET_64BIT"
15132   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15133   [(set_attr "type" "imov")
15134    (set_attr "modrm" "0")
15135    (set_attr "length" "7")
15136    (set_attr "memory" "load")
15137    (set_attr "imm_disp" "false")])
15138
15139 (define_insn "*add_tp_di"
15140   [(set (match_operand:DI 0 "register_operand" "=r")
15141         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15142                  (match_operand:DI 1 "register_operand" "0")))
15143    (clobber (reg:CC FLAGS_REG))]
15144   "TARGET_64BIT"
15145   "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15146   [(set_attr "type" "alu")
15147    (set_attr "modrm" "0")
15148    (set_attr "length" "7")
15149    (set_attr "memory" "load")
15150    (set_attr "imm_disp" "false")])
15151
15152 ;; GNU2 TLS patterns can be split.
15153
15154 (define_expand "tls_dynamic_gnu2_32"
15155   [(set (match_dup 3)
15156         (plus:SI (match_operand:SI 2 "register_operand" "")
15157                  (const:SI
15158                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15159                              UNSPEC_TLSDESC))))
15160    (parallel
15161     [(set (match_operand:SI 0 "register_operand" "")
15162           (unspec:SI [(match_dup 1) (match_dup 3)
15163                       (match_dup 2) (reg:SI SP_REG)]
15164                       UNSPEC_TLSDESC))
15165      (clobber (reg:CC FLAGS_REG))])]
15166   "!TARGET_64BIT && TARGET_GNU2_TLS"
15167 {
15168   operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15169   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15170 })
15171
15172 (define_insn "*tls_dynamic_lea_32"
15173   [(set (match_operand:SI 0 "register_operand" "=r")
15174         (plus:SI (match_operand:SI 1 "register_operand" "b")
15175                  (const:SI
15176                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15177                               UNSPEC_TLSDESC))))]
15178   "!TARGET_64BIT && TARGET_GNU2_TLS"
15179   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15180   [(set_attr "type" "lea")
15181    (set_attr "mode" "SI")
15182    (set_attr "length" "6")
15183    (set_attr "length_address" "4")])
15184
15185 (define_insn "*tls_dynamic_call_32"
15186   [(set (match_operand:SI 0 "register_operand" "=a")
15187         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15188                     (match_operand:SI 2 "register_operand" "0")
15189                     ;; we have to make sure %ebx still points to the GOT
15190                     (match_operand:SI 3 "register_operand" "b")
15191                     (reg:SI SP_REG)]
15192                    UNSPEC_TLSDESC))
15193    (clobber (reg:CC FLAGS_REG))]
15194   "!TARGET_64BIT && TARGET_GNU2_TLS"
15195   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15196   [(set_attr "type" "call")
15197    (set_attr "length" "2")
15198    (set_attr "length_address" "0")])
15199
15200 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15201   [(set (match_operand:SI 0 "register_operand" "=&a")
15202         (plus:SI
15203          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15204                      (match_operand:SI 4 "" "")
15205                      (match_operand:SI 2 "register_operand" "b")
15206                      (reg:SI SP_REG)]
15207                     UNSPEC_TLSDESC)
15208          (const:SI (unspec:SI
15209                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15210                     UNSPEC_DTPOFF))))
15211    (clobber (reg:CC FLAGS_REG))]
15212   "!TARGET_64BIT && TARGET_GNU2_TLS"
15213   "#"
15214   ""
15215   [(set (match_dup 0) (match_dup 5))]
15216 {
15217   operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15218   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15219 })
15220
15221 (define_expand "tls_dynamic_gnu2_64"
15222   [(set (match_dup 2)
15223         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15224                    UNSPEC_TLSDESC))
15225    (parallel
15226     [(set (match_operand:DI 0 "register_operand" "")
15227           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15228                      UNSPEC_TLSDESC))
15229      (clobber (reg:CC FLAGS_REG))])]
15230   "TARGET_64BIT && TARGET_GNU2_TLS"
15231 {
15232   operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15233   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15234 })
15235
15236 (define_insn "*tls_dynamic_lea_64"
15237   [(set (match_operand:DI 0 "register_operand" "=r")
15238         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15239                    UNSPEC_TLSDESC))]
15240   "TARGET_64BIT && TARGET_GNU2_TLS"
15241   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15242   [(set_attr "type" "lea")
15243    (set_attr "mode" "DI")
15244    (set_attr "length" "7")
15245    (set_attr "length_address" "4")])
15246
15247 (define_insn "*tls_dynamic_call_64"
15248   [(set (match_operand:DI 0 "register_operand" "=a")
15249         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15250                     (match_operand:DI 2 "register_operand" "0")
15251                     (reg:DI SP_REG)]
15252                    UNSPEC_TLSDESC))
15253    (clobber (reg:CC FLAGS_REG))]
15254   "TARGET_64BIT && TARGET_GNU2_TLS"
15255   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15256   [(set_attr "type" "call")
15257    (set_attr "length" "2")
15258    (set_attr "length_address" "0")])
15259
15260 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15261   [(set (match_operand:DI 0 "register_operand" "=&a")
15262         (plus:DI
15263          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15264                      (match_operand:DI 3 "" "")
15265                      (reg:DI SP_REG)]
15266                     UNSPEC_TLSDESC)
15267          (const:DI (unspec:DI
15268                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15269                     UNSPEC_DTPOFF))))
15270    (clobber (reg:CC FLAGS_REG))]
15271   "TARGET_64BIT && TARGET_GNU2_TLS"
15272   "#"
15273   ""
15274   [(set (match_dup 0) (match_dup 4))]
15275 {
15276   operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15277   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15278 })
15279
15280 ;;
15281 \f
15282 ;; These patterns match the binary 387 instructions for addM3, subM3,
15283 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15284 ;; SFmode.  The first is the normal insn, the second the same insn but
15285 ;; with one operand a conversion, and the third the same insn but with
15286 ;; the other operand a conversion.  The conversion may be SFmode or
15287 ;; SImode if the target mode DFmode, but only SImode if the target mode
15288 ;; is SFmode.
15289
15290 ;; Gcc is slightly more smart about handling normal two address instructions
15291 ;; so use special patterns for add and mull.
15292
15293 (define_insn "*fop_sf_comm_mixed"
15294   [(set (match_operand:SF 0 "register_operand" "=f,x")
15295         (match_operator:SF 3 "binary_fp_operator"
15296                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15297                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15298   "TARGET_MIX_SSE_I387
15299    && COMMUTATIVE_ARITH_P (operands[3])
15300    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15301   "* return output_387_binary_op (insn, operands);"
15302   [(set (attr "type")
15303         (if_then_else (eq_attr "alternative" "1")
15304            (if_then_else (match_operand:SF 3 "mult_operator" "")
15305               (const_string "ssemul")
15306               (const_string "sseadd"))
15307            (if_then_else (match_operand:SF 3 "mult_operator" "")
15308               (const_string "fmul")
15309               (const_string "fop"))))
15310    (set_attr "mode" "SF")])
15311
15312 (define_insn "*fop_sf_comm_sse"
15313   [(set (match_operand:SF 0 "register_operand" "=x")
15314         (match_operator:SF 3 "binary_fp_operator"
15315                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15316                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15317   "TARGET_SSE_MATH
15318    && COMMUTATIVE_ARITH_P (operands[3])
15319    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15320   "* return output_387_binary_op (insn, operands);"
15321   [(set (attr "type")
15322         (if_then_else (match_operand:SF 3 "mult_operator" "")
15323            (const_string "ssemul")
15324            (const_string "sseadd")))
15325    (set_attr "mode" "SF")])
15326
15327 (define_insn "*fop_sf_comm_i387"
15328   [(set (match_operand:SF 0 "register_operand" "=f")
15329         (match_operator:SF 3 "binary_fp_operator"
15330                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15331                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15332   "TARGET_80387
15333    && COMMUTATIVE_ARITH_P (operands[3])
15334    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15335   "* return output_387_binary_op (insn, operands);"
15336   [(set (attr "type")
15337         (if_then_else (match_operand:SF 3 "mult_operator" "")
15338            (const_string "fmul")
15339            (const_string "fop")))
15340    (set_attr "mode" "SF")])
15341
15342 (define_insn "*fop_sf_1_mixed"
15343   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15344         (match_operator:SF 3 "binary_fp_operator"
15345                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15346                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15347   "TARGET_MIX_SSE_I387
15348    && !COMMUTATIVE_ARITH_P (operands[3])
15349    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15350   "* return output_387_binary_op (insn, operands);"
15351   [(set (attr "type")
15352         (cond [(and (eq_attr "alternative" "2")
15353                     (match_operand:SF 3 "mult_operator" ""))
15354                  (const_string "ssemul")
15355                (and (eq_attr "alternative" "2")
15356                     (match_operand:SF 3 "div_operator" ""))
15357                  (const_string "ssediv")
15358                (eq_attr "alternative" "2")
15359                  (const_string "sseadd")
15360                (match_operand:SF 3 "mult_operator" "")
15361                  (const_string "fmul")
15362                (match_operand:SF 3 "div_operator" "")
15363                  (const_string "fdiv")
15364               ]
15365               (const_string "fop")))
15366    (set_attr "mode" "SF")])
15367
15368 (define_insn "*fop_sf_1_sse"
15369   [(set (match_operand:SF 0 "register_operand" "=x")
15370         (match_operator:SF 3 "binary_fp_operator"
15371                         [(match_operand:SF 1 "register_operand" "0")
15372                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15373   "TARGET_SSE_MATH
15374    && !COMMUTATIVE_ARITH_P (operands[3])"
15375   "* return output_387_binary_op (insn, operands);"
15376   [(set (attr "type")
15377         (cond [(match_operand:SF 3 "mult_operator" "")
15378                  (const_string "ssemul")
15379                (match_operand:SF 3 "div_operator" "")
15380                  (const_string "ssediv")
15381               ]
15382               (const_string "sseadd")))
15383    (set_attr "mode" "SF")])
15384
15385 ;; This pattern is not fully shadowed by the pattern above.
15386 (define_insn "*fop_sf_1_i387"
15387   [(set (match_operand:SF 0 "register_operand" "=f,f")
15388         (match_operator:SF 3 "binary_fp_operator"
15389                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15390                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15391   "TARGET_80387 && !TARGET_SSE_MATH
15392    && !COMMUTATIVE_ARITH_P (operands[3])
15393    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15394   "* return output_387_binary_op (insn, operands);"
15395   [(set (attr "type")
15396         (cond [(match_operand:SF 3 "mult_operator" "")
15397                  (const_string "fmul")
15398                (match_operand:SF 3 "div_operator" "")
15399                  (const_string "fdiv")
15400               ]
15401               (const_string "fop")))
15402    (set_attr "mode" "SF")])
15403
15404 ;; ??? Add SSE splitters for these!
15405 (define_insn "*fop_sf_2<mode>_i387"
15406   [(set (match_operand:SF 0 "register_operand" "=f,f")
15407         (match_operator:SF 3 "binary_fp_operator"
15408           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15409            (match_operand:SF 2 "register_operand" "0,0")]))]
15410   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15411   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15412   [(set (attr "type")
15413         (cond [(match_operand:SF 3 "mult_operator" "")
15414                  (const_string "fmul")
15415                (match_operand:SF 3 "div_operator" "")
15416                  (const_string "fdiv")
15417               ]
15418               (const_string "fop")))
15419    (set_attr "fp_int_src" "true")
15420    (set_attr "mode" "<MODE>")])
15421
15422 (define_insn "*fop_sf_3<mode>_i387"
15423   [(set (match_operand:SF 0 "register_operand" "=f,f")
15424         (match_operator:SF 3 "binary_fp_operator"
15425           [(match_operand:SF 1 "register_operand" "0,0")
15426            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15427   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15428   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15429   [(set (attr "type")
15430         (cond [(match_operand:SF 3 "mult_operator" "")
15431                  (const_string "fmul")
15432                (match_operand:SF 3 "div_operator" "")
15433                  (const_string "fdiv")
15434               ]
15435               (const_string "fop")))
15436    (set_attr "fp_int_src" "true")
15437    (set_attr "mode" "<MODE>")])
15438
15439 (define_insn "*fop_df_comm_mixed"
15440   [(set (match_operand:DF 0 "register_operand" "=f,Y")
15441         (match_operator:DF 3 "binary_fp_operator"
15442                         [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15443                          (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15444   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15445    && COMMUTATIVE_ARITH_P (operands[3])
15446    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15447   "* return output_387_binary_op (insn, operands);"
15448   [(set (attr "type")
15449         (if_then_else (eq_attr "alternative" "1")
15450            (if_then_else (match_operand:DF 3 "mult_operator" "")
15451               (const_string "ssemul")
15452               (const_string "sseadd"))
15453            (if_then_else (match_operand:DF 3 "mult_operator" "")
15454               (const_string "fmul")
15455               (const_string "fop"))))
15456    (set_attr "mode" "DF")])
15457
15458 (define_insn "*fop_df_comm_sse"
15459   [(set (match_operand:DF 0 "register_operand" "=Y")
15460         (match_operator:DF 3 "binary_fp_operator"
15461                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15462                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15463   "TARGET_SSE2 && TARGET_SSE_MATH
15464    && COMMUTATIVE_ARITH_P (operands[3])
15465    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15466   "* return output_387_binary_op (insn, operands);"
15467   [(set (attr "type")
15468         (if_then_else (match_operand:DF 3 "mult_operator" "")
15469            (const_string "ssemul")
15470            (const_string "sseadd")))
15471    (set_attr "mode" "DF")])
15472
15473 (define_insn "*fop_df_comm_i387"
15474   [(set (match_operand:DF 0 "register_operand" "=f")
15475         (match_operator:DF 3 "binary_fp_operator"
15476                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15477                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15478   "TARGET_80387
15479    && COMMUTATIVE_ARITH_P (operands[3])
15480    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15481   "* return output_387_binary_op (insn, operands);"
15482   [(set (attr "type")
15483         (if_then_else (match_operand:DF 3 "mult_operator" "")
15484            (const_string "fmul")
15485            (const_string "fop")))
15486    (set_attr "mode" "DF")])
15487
15488 (define_insn "*fop_df_1_mixed"
15489   [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15490         (match_operator:DF 3 "binary_fp_operator"
15491                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15492                          (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15493   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15494    && !COMMUTATIVE_ARITH_P (operands[3])
15495    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15496   "* return output_387_binary_op (insn, operands);"
15497   [(set (attr "type")
15498         (cond [(and (eq_attr "alternative" "2")
15499                     (match_operand:DF 3 "mult_operator" ""))
15500                  (const_string "ssemul")
15501                (and (eq_attr "alternative" "2")
15502                     (match_operand:DF 3 "div_operator" ""))
15503                  (const_string "ssediv")
15504                (eq_attr "alternative" "2")
15505                  (const_string "sseadd")
15506                (match_operand:DF 3 "mult_operator" "")
15507                  (const_string "fmul")
15508                (match_operand:DF 3 "div_operator" "")
15509                  (const_string "fdiv")
15510               ]
15511               (const_string "fop")))
15512    (set_attr "mode" "DF")])
15513
15514 (define_insn "*fop_df_1_sse"
15515   [(set (match_operand:DF 0 "register_operand" "=Y")
15516         (match_operator:DF 3 "binary_fp_operator"
15517                         [(match_operand:DF 1 "register_operand" "0")
15518                          (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15519   "TARGET_SSE2 && TARGET_SSE_MATH
15520    && !COMMUTATIVE_ARITH_P (operands[3])"
15521   "* return output_387_binary_op (insn, operands);"
15522   [(set_attr "mode" "DF")
15523    (set (attr "type")
15524         (cond [(match_operand:DF 3 "mult_operator" "")
15525                  (const_string "ssemul")
15526                (match_operand:DF 3 "div_operator" "")
15527                  (const_string "ssediv")
15528               ]
15529               (const_string "sseadd")))])
15530
15531 ;; This pattern is not fully shadowed by the pattern above.
15532 (define_insn "*fop_df_1_i387"
15533   [(set (match_operand:DF 0 "register_operand" "=f,f")
15534         (match_operator:DF 3 "binary_fp_operator"
15535                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15536                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15537   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15538    && !COMMUTATIVE_ARITH_P (operands[3])
15539    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15540   "* return output_387_binary_op (insn, operands);"
15541   [(set (attr "type")
15542         (cond [(match_operand:DF 3 "mult_operator" "")
15543                  (const_string "fmul")
15544                (match_operand:DF 3 "div_operator" "")
15545                  (const_string "fdiv")
15546               ]
15547               (const_string "fop")))
15548    (set_attr "mode" "DF")])
15549
15550 ;; ??? Add SSE splitters for these!
15551 (define_insn "*fop_df_2<mode>_i387"
15552   [(set (match_operand:DF 0 "register_operand" "=f,f")
15553         (match_operator:DF 3 "binary_fp_operator"
15554            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15555             (match_operand:DF 2 "register_operand" "0,0")]))]
15556   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15557    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15558   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15559   [(set (attr "type")
15560         (cond [(match_operand:DF 3 "mult_operator" "")
15561                  (const_string "fmul")
15562                (match_operand:DF 3 "div_operator" "")
15563                  (const_string "fdiv")
15564               ]
15565               (const_string "fop")))
15566    (set_attr "fp_int_src" "true")
15567    (set_attr "mode" "<MODE>")])
15568
15569 (define_insn "*fop_df_3<mode>_i387"
15570   [(set (match_operand:DF 0 "register_operand" "=f,f")
15571         (match_operator:DF 3 "binary_fp_operator"
15572            [(match_operand:DF 1 "register_operand" "0,0")
15573             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15574   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15575    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15576   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15577   [(set (attr "type")
15578         (cond [(match_operand:DF 3 "mult_operator" "")
15579                  (const_string "fmul")
15580                (match_operand:DF 3 "div_operator" "")
15581                  (const_string "fdiv")
15582               ]
15583               (const_string "fop")))
15584    (set_attr "fp_int_src" "true")
15585    (set_attr "mode" "<MODE>")])
15586
15587 (define_insn "*fop_df_4_i387"
15588   [(set (match_operand:DF 0 "register_operand" "=f,f")
15589         (match_operator:DF 3 "binary_fp_operator"
15590            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15591             (match_operand:DF 2 "register_operand" "0,f")]))]
15592   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15593    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15594   "* return output_387_binary_op (insn, operands);"
15595   [(set (attr "type")
15596         (cond [(match_operand:DF 3 "mult_operator" "")
15597                  (const_string "fmul")
15598                (match_operand:DF 3 "div_operator" "")
15599                  (const_string "fdiv")
15600               ]
15601               (const_string "fop")))
15602    (set_attr "mode" "SF")])
15603
15604 (define_insn "*fop_df_5_i387"
15605   [(set (match_operand:DF 0 "register_operand" "=f,f")
15606         (match_operator:DF 3 "binary_fp_operator"
15607           [(match_operand:DF 1 "register_operand" "0,f")
15608            (float_extend:DF
15609             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15610   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15611   "* return output_387_binary_op (insn, operands);"
15612   [(set (attr "type")
15613         (cond [(match_operand:DF 3 "mult_operator" "")
15614                  (const_string "fmul")
15615                (match_operand:DF 3 "div_operator" "")
15616                  (const_string "fdiv")
15617               ]
15618               (const_string "fop")))
15619    (set_attr "mode" "SF")])
15620
15621 (define_insn "*fop_df_6_i387"
15622   [(set (match_operand:DF 0 "register_operand" "=f,f")
15623         (match_operator:DF 3 "binary_fp_operator"
15624           [(float_extend:DF
15625             (match_operand:SF 1 "register_operand" "0,f"))
15626            (float_extend:DF
15627             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15628   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15629   "* return output_387_binary_op (insn, operands);"
15630   [(set (attr "type")
15631         (cond [(match_operand:DF 3 "mult_operator" "")
15632                  (const_string "fmul")
15633                (match_operand:DF 3 "div_operator" "")
15634                  (const_string "fdiv")
15635               ]
15636               (const_string "fop")))
15637    (set_attr "mode" "SF")])
15638
15639 (define_insn "*fop_xf_comm_i387"
15640   [(set (match_operand:XF 0 "register_operand" "=f")
15641         (match_operator:XF 3 "binary_fp_operator"
15642                         [(match_operand:XF 1 "register_operand" "%0")
15643                          (match_operand:XF 2 "register_operand" "f")]))]
15644   "TARGET_80387
15645    && COMMUTATIVE_ARITH_P (operands[3])"
15646   "* return output_387_binary_op (insn, operands);"
15647   [(set (attr "type")
15648         (if_then_else (match_operand:XF 3 "mult_operator" "")
15649            (const_string "fmul")
15650            (const_string "fop")))
15651    (set_attr "mode" "XF")])
15652
15653 (define_insn "*fop_xf_1_i387"
15654   [(set (match_operand:XF 0 "register_operand" "=f,f")
15655         (match_operator:XF 3 "binary_fp_operator"
15656                         [(match_operand:XF 1 "register_operand" "0,f")
15657                          (match_operand:XF 2 "register_operand" "f,0")]))]
15658   "TARGET_80387
15659    && !COMMUTATIVE_ARITH_P (operands[3])"
15660   "* return output_387_binary_op (insn, operands);"
15661   [(set (attr "type")
15662         (cond [(match_operand:XF 3 "mult_operator" "")
15663                  (const_string "fmul")
15664                (match_operand:XF 3 "div_operator" "")
15665                  (const_string "fdiv")
15666               ]
15667               (const_string "fop")))
15668    (set_attr "mode" "XF")])
15669
15670 (define_insn "*fop_xf_2<mode>_i387"
15671   [(set (match_operand:XF 0 "register_operand" "=f,f")
15672         (match_operator:XF 3 "binary_fp_operator"
15673            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15674             (match_operand:XF 2 "register_operand" "0,0")]))]
15675   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15676   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15677   [(set (attr "type")
15678         (cond [(match_operand:XF 3 "mult_operator" "")
15679                  (const_string "fmul")
15680                (match_operand:XF 3 "div_operator" "")
15681                  (const_string "fdiv")
15682               ]
15683               (const_string "fop")))
15684    (set_attr "fp_int_src" "true")
15685    (set_attr "mode" "<MODE>")])
15686
15687 (define_insn "*fop_xf_3<mode>_i387"
15688   [(set (match_operand:XF 0 "register_operand" "=f,f")
15689         (match_operator:XF 3 "binary_fp_operator"
15690           [(match_operand:XF 1 "register_operand" "0,0")
15691            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15692   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15693   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15694   [(set (attr "type")
15695         (cond [(match_operand:XF 3 "mult_operator" "")
15696                  (const_string "fmul")
15697                (match_operand:XF 3 "div_operator" "")
15698                  (const_string "fdiv")
15699               ]
15700               (const_string "fop")))
15701    (set_attr "fp_int_src" "true")
15702    (set_attr "mode" "<MODE>")])
15703
15704 (define_insn "*fop_xf_4_i387"
15705   [(set (match_operand:XF 0 "register_operand" "=f,f")
15706         (match_operator:XF 3 "binary_fp_operator"
15707            [(float_extend:XF
15708               (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
15709             (match_operand:XF 2 "register_operand" "0,f")]))]
15710   "TARGET_80387"
15711   "* return output_387_binary_op (insn, operands);"
15712   [(set (attr "type")
15713         (cond [(match_operand:XF 3 "mult_operator" "")
15714                  (const_string "fmul")
15715                (match_operand:XF 3 "div_operator" "")
15716                  (const_string "fdiv")
15717               ]
15718               (const_string "fop")))
15719    (set_attr "mode" "SF")])
15720
15721 (define_insn "*fop_xf_5_i387"
15722   [(set (match_operand:XF 0 "register_operand" "=f,f")
15723         (match_operator:XF 3 "binary_fp_operator"
15724           [(match_operand:XF 1 "register_operand" "0,f")
15725            (float_extend:XF
15726              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15727   "TARGET_80387"
15728   "* return output_387_binary_op (insn, operands);"
15729   [(set (attr "type")
15730         (cond [(match_operand:XF 3 "mult_operator" "")
15731                  (const_string "fmul")
15732                (match_operand:XF 3 "div_operator" "")
15733                  (const_string "fdiv")
15734               ]
15735               (const_string "fop")))
15736    (set_attr "mode" "SF")])
15737
15738 (define_insn "*fop_xf_6_i387"
15739   [(set (match_operand:XF 0 "register_operand" "=f,f")
15740         (match_operator:XF 3 "binary_fp_operator"
15741           [(float_extend:XF
15742              (match_operand:X87MODEF12 1 "register_operand" "0,f"))
15743            (float_extend:XF
15744              (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15745   "TARGET_80387"
15746   "* return output_387_binary_op (insn, operands);"
15747   [(set (attr "type")
15748         (cond [(match_operand:XF 3 "mult_operator" "")
15749                  (const_string "fmul")
15750                (match_operand:XF 3 "div_operator" "")
15751                  (const_string "fdiv")
15752               ]
15753               (const_string "fop")))
15754    (set_attr "mode" "SF")])
15755
15756 (define_split
15757   [(set (match_operand 0 "register_operand" "")
15758         (match_operator 3 "binary_fp_operator"
15759            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15760             (match_operand 2 "register_operand" "")]))]
15761   "TARGET_80387 && reload_completed
15762    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15763   [(const_int 0)]
15764 {
15765   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15766   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15767   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15768                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15769                                           GET_MODE (operands[3]),
15770                                           operands[4],
15771                                           operands[2])));
15772   ix86_free_from_memory (GET_MODE (operands[1]));
15773   DONE;
15774 })
15775
15776 (define_split
15777   [(set (match_operand 0 "register_operand" "")
15778         (match_operator 3 "binary_fp_operator"
15779            [(match_operand 1 "register_operand" "")
15780             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15781   "TARGET_80387 && reload_completed
15782    && FLOAT_MODE_P (GET_MODE (operands[0]))"
15783   [(const_int 0)]
15784 {
15785   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15786   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15787   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15788                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15789                                           GET_MODE (operands[3]),
15790                                           operands[1],
15791                                           operands[4])));
15792   ix86_free_from_memory (GET_MODE (operands[2]));
15793   DONE;
15794 })
15795 \f
15796 ;; FPU special functions.
15797
15798 ;; This pattern implements a no-op XFmode truncation for
15799 ;; all fancy i386 XFmode math functions.
15800
15801 (define_insn "truncxf<mode>2_i387_noop_unspec"
15802   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15803         (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
15804         UNSPEC_TRUNC_NOOP))]
15805   "TARGET_USE_FANCY_MATH_387"
15806   "* return output_387_reg_move (insn, operands);"
15807   [(set_attr "type" "fmov")
15808    (set_attr "mode" "<MODE>")])
15809
15810 (define_insn "sqrtxf2"
15811   [(set (match_operand:XF 0 "register_operand" "=f")
15812         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15813   "TARGET_USE_FANCY_MATH_387"
15814   "fsqrt"
15815   [(set_attr "type" "fpspc")
15816    (set_attr "mode" "XF")
15817    (set_attr "athlon_decode" "direct")
15818    (set_attr "amdfam10_decode" "direct")])
15819
15820 (define_insn "sqrt_extend<mode>xf2_i387"
15821   [(set (match_operand:XF 0 "register_operand" "=f")
15822         (sqrt:XF
15823           (float_extend:XF
15824             (match_operand:X87MODEF12 1 "register_operand" "0"))))]
15825   "TARGET_USE_FANCY_MATH_387"
15826   "fsqrt"
15827   [(set_attr "type" "fpspc")
15828    (set_attr "mode" "XF")
15829    (set_attr "athlon_decode" "direct")   
15830    (set_attr "amdfam10_decode" "direct")])
15831
15832 (define_insn "*sqrt<mode>2_sse"
15833   [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
15834         (sqrt:SSEMODEF
15835           (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
15836   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15837   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
15838   [(set_attr "type" "sse")
15839    (set_attr "mode" "<MODE>")
15840    (set_attr "athlon_decode" "*")
15841    (set_attr "amdfam10_decode" "*")])
15842
15843 (define_expand "sqrt<mode>2"
15844   [(set (match_operand:X87MODEF12 0 "register_operand" "")
15845         (sqrt:X87MODEF12
15846           (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
15847   "TARGET_USE_FANCY_MATH_387
15848    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15849 {
15850   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15851     {
15852       rtx op0 = gen_reg_rtx (XFmode);
15853       rtx op1 = force_reg (<MODE>mode, operands[1]);
15854
15855       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15856       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15857       DONE;
15858    }
15859 })
15860
15861 (define_insn "fpremxf4_i387"
15862   [(set (match_operand:XF 0 "register_operand" "=f")
15863         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15864                     (match_operand:XF 3 "register_operand" "1")]
15865                    UNSPEC_FPREM_F))
15866    (set (match_operand:XF 1 "register_operand" "=u")
15867         (unspec:XF [(match_dup 2) (match_dup 3)]
15868                    UNSPEC_FPREM_U))
15869    (set (reg:CCFP FPSR_REG)
15870         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15871   "TARGET_USE_FANCY_MATH_387"
15872   "fprem"
15873   [(set_attr "type" "fpspc")
15874    (set_attr "mode" "XF")])
15875
15876 (define_expand "fmodxf3"
15877   [(use (match_operand:XF 0 "register_operand" ""))
15878    (use (match_operand:XF 1 "register_operand" ""))
15879    (use (match_operand:XF 2 "register_operand" ""))]
15880   "TARGET_USE_FANCY_MATH_387"
15881 {
15882   rtx label = gen_label_rtx ();
15883
15884   emit_label (label);
15885
15886   emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
15887                                 operands[1], operands[2]));
15888   ix86_emit_fp_unordered_jump (label);
15889
15890   emit_move_insn (operands[0], operands[1]);
15891   DONE;
15892 })
15893
15894 (define_expand "fmod<mode>3"
15895   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15896    (use (match_operand:X87MODEF12 1 "general_operand" ""))
15897    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
15898   "TARGET_USE_FANCY_MATH_387"
15899 {
15900   rtx label = gen_label_rtx ();
15901
15902   rtx op1 = gen_reg_rtx (XFmode);
15903   rtx op2 = gen_reg_rtx (XFmode);
15904
15905   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15906   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15907
15908   emit_label (label);
15909   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15910   ix86_emit_fp_unordered_jump (label);
15911
15912   /* Truncate the result properly for strict SSE math.  */
15913   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15914       && !TARGET_MIX_SSE_I387)
15915     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15916   else
15917     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15918
15919   DONE;
15920 })
15921
15922 (define_insn "fprem1xf4_i387"
15923   [(set (match_operand:XF 0 "register_operand" "=f")
15924         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15925                     (match_operand:XF 3 "register_operand" "1")]
15926                    UNSPEC_FPREM1_F))
15927    (set (match_operand:XF 1 "register_operand" "=u")
15928         (unspec:XF [(match_dup 2) (match_dup 3)]
15929                    UNSPEC_FPREM1_U))
15930    (set (reg:CCFP FPSR_REG)
15931         (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15932   "TARGET_USE_FANCY_MATH_387"
15933   "fprem1"
15934   [(set_attr "type" "fpspc")
15935    (set_attr "mode" "XF")])
15936
15937 (define_expand "remainderxf3"
15938   [(use (match_operand:XF 0 "register_operand" ""))
15939    (use (match_operand:XF 1 "register_operand" ""))
15940    (use (match_operand:XF 2 "register_operand" ""))]
15941   "TARGET_USE_FANCY_MATH_387"
15942 {
15943   rtx label = gen_label_rtx ();
15944
15945   emit_label (label);
15946
15947   emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
15948                                  operands[1], operands[2]));
15949   ix86_emit_fp_unordered_jump (label);
15950
15951   emit_move_insn (operands[0], operands[1]);
15952   DONE;
15953 })
15954
15955 (define_expand "remainder<mode>3"
15956   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15957    (use (match_operand:X87MODEF12 1 "general_operand" ""))
15958    (use (match_operand:X87MODEF12 2 "general_operand" ""))]
15959   "TARGET_USE_FANCY_MATH_387"
15960 {
15961   rtx label = gen_label_rtx ();
15962
15963   rtx op1 = gen_reg_rtx (XFmode);
15964   rtx op2 = gen_reg_rtx (XFmode);
15965
15966   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15967   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15968
15969   emit_label (label);
15970
15971   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15972   ix86_emit_fp_unordered_jump (label);
15973
15974   /* Truncate the result properly for strict SSE math.  */
15975   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15976       && !TARGET_MIX_SSE_I387)
15977     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15978   else
15979     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15980
15981   DONE;
15982 })
15983
15984 (define_insn "*sinxf2_i387"
15985   [(set (match_operand:XF 0 "register_operand" "=f")
15986         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15987   "TARGET_USE_FANCY_MATH_387
15988    && flag_unsafe_math_optimizations"
15989   "fsin"
15990   [(set_attr "type" "fpspc")
15991    (set_attr "mode" "XF")])
15992
15993 (define_insn "*sin_extend<mode>xf2_i387"
15994   [(set (match_operand:XF 0 "register_operand" "=f")
15995         (unspec:XF [(float_extend:XF
15996                       (match_operand:X87MODEF12 1 "register_operand" "0"))]
15997                    UNSPEC_SIN))]
15998   "TARGET_USE_FANCY_MATH_387
15999    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16000        || TARGET_MIX_SSE_I387)
16001    && flag_unsafe_math_optimizations"
16002   "fsin"
16003   [(set_attr "type" "fpspc")
16004    (set_attr "mode" "XF")])
16005
16006 (define_insn "*cosxf2_i387"
16007   [(set (match_operand:XF 0 "register_operand" "=f")
16008         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16009   "TARGET_USE_FANCY_MATH_387
16010    && flag_unsafe_math_optimizations"
16011   "fcos"
16012   [(set_attr "type" "fpspc")
16013    (set_attr "mode" "XF")])
16014
16015 (define_insn "*cos_extend<mode>xf2_i387"
16016   [(set (match_operand:XF 0 "register_operand" "=f")
16017         (unspec:XF [(float_extend:XF
16018                       (match_operand:X87MODEF12 1 "register_operand" "0"))]
16019                    UNSPEC_COS))]
16020   "TARGET_USE_FANCY_MATH_387
16021    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16022        || TARGET_MIX_SSE_I387)
16023    && flag_unsafe_math_optimizations"
16024   "fcos"
16025   [(set_attr "type" "fpspc")
16026    (set_attr "mode" "XF")])
16027
16028 ;; When sincos pattern is defined, sin and cos builtin functions will be
16029 ;; expanded to sincos pattern with one of its outputs left unused.
16030 ;; CSE pass will figure out if two sincos patterns can be combined,
16031 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16032 ;; depending on the unused output.
16033
16034 (define_insn "sincosxf3"
16035   [(set (match_operand:XF 0 "register_operand" "=f")
16036         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16037                    UNSPEC_SINCOS_COS))
16038    (set (match_operand:XF 1 "register_operand" "=u")
16039         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16040   "TARGET_USE_FANCY_MATH_387
16041    && flag_unsafe_math_optimizations"
16042   "fsincos"
16043   [(set_attr "type" "fpspc")
16044    (set_attr "mode" "XF")])
16045
16046 (define_split
16047   [(set (match_operand:XF 0 "register_operand" "")
16048         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16049                    UNSPEC_SINCOS_COS))
16050    (set (match_operand:XF 1 "register_operand" "")
16051         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16052   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16053    && !reload_completed && !reload_in_progress"
16054   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16055   "")
16056
16057 (define_split
16058   [(set (match_operand:XF 0 "register_operand" "")
16059         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16060                    UNSPEC_SINCOS_COS))
16061    (set (match_operand:XF 1 "register_operand" "")
16062         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16063   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16064    && !reload_completed && !reload_in_progress"
16065   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16066   "")
16067
16068 (define_insn "sincos_extend<mode>xf3_i387"
16069   [(set (match_operand:XF 0 "register_operand" "=f")
16070         (unspec:XF [(float_extend:XF
16071                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16072                    UNSPEC_SINCOS_COS))
16073    (set (match_operand:XF 1 "register_operand" "=u")
16074         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16075   "TARGET_USE_FANCY_MATH_387
16076    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16077        || TARGET_MIX_SSE_I387)
16078    && flag_unsafe_math_optimizations"
16079   "fsincos"
16080   [(set_attr "type" "fpspc")
16081    (set_attr "mode" "XF")])
16082
16083 (define_split
16084   [(set (match_operand:XF 0 "register_operand" "")
16085         (unspec:XF [(float_extend:XF
16086                       (match_operand:X87MODEF12 2 "register_operand" ""))]
16087                    UNSPEC_SINCOS_COS))
16088    (set (match_operand:XF 1 "register_operand" "")
16089         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16090   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16091    && !reload_completed && !reload_in_progress"
16092   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16093   "")
16094
16095 (define_split
16096   [(set (match_operand:XF 0 "register_operand" "")
16097         (unspec:XF [(float_extend:XF
16098                       (match_operand:X87MODEF12 2 "register_operand" ""))]
16099                    UNSPEC_SINCOS_COS))
16100    (set (match_operand:XF 1 "register_operand" "")
16101         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16102   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16103    && !reload_completed && !reload_in_progress"
16104   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16105   "")
16106
16107 (define_expand "sincos<mode>3"
16108   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16109    (use (match_operand:X87MODEF12 1 "register_operand" ""))
16110    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16111   "TARGET_USE_FANCY_MATH_387
16112    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16113        || TARGET_MIX_SSE_I387)
16114    && flag_unsafe_math_optimizations"
16115 {
16116   rtx op0 = gen_reg_rtx (XFmode);
16117   rtx op1 = gen_reg_rtx (XFmode);
16118
16119   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16120   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16121   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16122   DONE;
16123 })
16124
16125 (define_insn "fptanxf4_i387"
16126   [(set (match_operand:XF 0 "register_operand" "=f")
16127         (match_operand:XF 3 "const_double_operand" "F"))
16128    (set (match_operand:XF 1 "register_operand" "=u")
16129         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16130                    UNSPEC_TAN))]
16131   "TARGET_USE_FANCY_MATH_387
16132    && flag_unsafe_math_optimizations
16133    && standard_80387_constant_p (operands[3]) == 2"
16134   "fptan"
16135   [(set_attr "type" "fpspc")
16136    (set_attr "mode" "XF")])
16137
16138 (define_insn "fptan_extend<mode>xf4_i387"
16139   [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16140         (match_operand:X87MODEF12 3 "const_double_operand" "F"))
16141    (set (match_operand:XF 1 "register_operand" "=u")
16142         (unspec:XF [(float_extend:XF
16143                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16144                    UNSPEC_TAN))]
16145   "TARGET_USE_FANCY_MATH_387
16146    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16147        || TARGET_MIX_SSE_I387)
16148    && flag_unsafe_math_optimizations
16149    && standard_80387_constant_p (operands[3]) == 2"
16150   "fptan"
16151   [(set_attr "type" "fpspc")
16152    (set_attr "mode" "XF")])
16153
16154 (define_expand "tanxf2"
16155   [(use (match_operand:XF 0 "register_operand" ""))
16156    (use (match_operand:XF 1 "register_operand" ""))]
16157   "TARGET_USE_FANCY_MATH_387
16158    && flag_unsafe_math_optimizations"
16159 {
16160   rtx one = gen_reg_rtx (XFmode);
16161   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16162
16163   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16164   DONE;
16165 })
16166
16167 (define_expand "tan<mode>2"
16168   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16169    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16170   "TARGET_USE_FANCY_MATH_387
16171    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16172        || TARGET_MIX_SSE_I387)
16173    && flag_unsafe_math_optimizations"
16174 {
16175   rtx op0 = gen_reg_rtx (XFmode);
16176
16177   rtx one = gen_reg_rtx (<MODE>mode);
16178   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16179
16180   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16181                                              operands[1], op2));
16182   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16183   DONE;
16184 })
16185
16186 (define_insn "*fpatanxf3_i387"
16187   [(set (match_operand:XF 0 "register_operand" "=f")
16188         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16189                     (match_operand:XF 2 "register_operand" "u")]
16190                    UNSPEC_FPATAN))
16191    (clobber (match_scratch:XF 3 "=2"))]
16192   "TARGET_USE_FANCY_MATH_387
16193    && flag_unsafe_math_optimizations"
16194   "fpatan"
16195   [(set_attr "type" "fpspc")
16196    (set_attr "mode" "XF")])
16197
16198 (define_insn "fpatan_extend<mode>xf3_i387"
16199   [(set (match_operand:XF 0 "register_operand" "=f")
16200         (unspec:XF [(float_extend:XF
16201                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16202                     (float_extend:XF
16203                       (match_operand:X87MODEF12 2 "register_operand" "u"))]
16204                    UNSPEC_FPATAN))
16205    (clobber (match_scratch:XF 3 "=2"))]
16206   "TARGET_USE_FANCY_MATH_387
16207    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16208        || TARGET_MIX_SSE_I387)
16209    && flag_unsafe_math_optimizations"
16210   "fpatan"
16211   [(set_attr "type" "fpspc")
16212    (set_attr "mode" "XF")])
16213
16214 (define_expand "atan2xf3"
16215   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16216                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
16217                                (match_operand:XF 1 "register_operand" "")]
16218                               UNSPEC_FPATAN))
16219               (clobber (match_scratch:XF 3 ""))])]
16220   "TARGET_USE_FANCY_MATH_387
16221    && flag_unsafe_math_optimizations"
16222   "")
16223
16224 (define_expand "atan2<mode>3"
16225   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16226    (use (match_operand:X87MODEF12 1 "register_operand" ""))
16227    (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16228   "TARGET_USE_FANCY_MATH_387
16229    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16230        || TARGET_MIX_SSE_I387)
16231    && flag_unsafe_math_optimizations"
16232 {
16233   rtx op0 = gen_reg_rtx (XFmode);
16234
16235   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16236   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16237   DONE;
16238 })
16239
16240 (define_expand "atanxf2"
16241   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16242                    (unspec:XF [(match_dup 2)
16243                                (match_operand:XF 1 "register_operand" "")]
16244                               UNSPEC_FPATAN))
16245               (clobber (match_scratch:XF 3 ""))])]
16246   "TARGET_USE_FANCY_MATH_387
16247    && flag_unsafe_math_optimizations"
16248 {
16249   operands[2] = gen_reg_rtx (XFmode);
16250   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16251 })
16252
16253 (define_expand "atan<mode>2"
16254   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16255    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16256   "TARGET_USE_FANCY_MATH_387
16257    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16258        || TARGET_MIX_SSE_I387)
16259    && flag_unsafe_math_optimizations"
16260 {
16261   rtx op0 = gen_reg_rtx (XFmode);
16262
16263   rtx op2 = gen_reg_rtx (<MODE>mode);
16264   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
16265
16266   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16267   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16268   DONE;
16269 })
16270
16271 (define_expand "asinxf2"
16272   [(set (match_dup 2)
16273         (mult:XF (match_operand:XF 1 "register_operand" "")
16274                  (match_dup 1)))
16275    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16276    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16277    (parallel [(set (match_operand:XF 0 "register_operand" "")
16278                    (unspec:XF [(match_dup 5) (match_dup 1)]
16279                               UNSPEC_FPATAN))
16280               (clobber (match_scratch:XF 6 ""))])]
16281   "TARGET_USE_FANCY_MATH_387
16282    && flag_unsafe_math_optimizations && !optimize_size"
16283 {
16284   int i;
16285
16286   for (i = 2; i < 6; i++)
16287     operands[i] = gen_reg_rtx (XFmode);
16288
16289   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16290 })
16291
16292 (define_expand "asin<mode>2"
16293   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16294    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16295  "TARGET_USE_FANCY_MATH_387
16296    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16297        || TARGET_MIX_SSE_I387)
16298    && flag_unsafe_math_optimizations && !optimize_size"
16299 {
16300   rtx op0 = gen_reg_rtx (XFmode);
16301   rtx op1 = gen_reg_rtx (XFmode);
16302
16303   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16304   emit_insn (gen_asinxf2 (op0, op1));
16305   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16306   DONE;
16307 })
16308
16309 (define_expand "acosxf2"
16310   [(set (match_dup 2)
16311         (mult:XF (match_operand:XF 1 "register_operand" "")
16312                  (match_dup 1)))
16313    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16314    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16315    (parallel [(set (match_operand:XF 0 "register_operand" "")
16316                    (unspec:XF [(match_dup 1) (match_dup 5)]
16317                               UNSPEC_FPATAN))
16318               (clobber (match_scratch:XF 6 ""))])]
16319   "TARGET_USE_FANCY_MATH_387
16320    && flag_unsafe_math_optimizations && !optimize_size"
16321 {
16322   int i;
16323
16324   for (i = 2; i < 6; i++)
16325     operands[i] = gen_reg_rtx (XFmode);
16326
16327   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16328 })
16329
16330 (define_expand "acos<mode>2"
16331   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16332    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16333  "TARGET_USE_FANCY_MATH_387
16334    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16335        || TARGET_MIX_SSE_I387)
16336    && flag_unsafe_math_optimizations && !optimize_size"
16337 {
16338   rtx op0 = gen_reg_rtx (XFmode);
16339   rtx op1 = gen_reg_rtx (XFmode);
16340
16341   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16342   emit_insn (gen_acosxf2 (op0, op1));
16343   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16344   DONE;
16345 })
16346
16347 (define_insn "fyl2xxf3_i387"
16348   [(set (match_operand:XF 0 "register_operand" "=f")
16349         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16350                     (match_operand:XF 2 "register_operand" "u")]
16351                    UNSPEC_FYL2X))
16352    (clobber (match_scratch:XF 3 "=2"))]
16353   "TARGET_USE_FANCY_MATH_387
16354    && flag_unsafe_math_optimizations"
16355   "fyl2x"
16356   [(set_attr "type" "fpspc")
16357    (set_attr "mode" "XF")])
16358
16359 (define_insn "fyl2x_extend<mode>xf3_i387"
16360   [(set (match_operand:XF 0 "register_operand" "=f")
16361         (unspec:XF [(float_extend:XF
16362                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16363                     (match_operand:XF 2 "register_operand" "u")]
16364                    UNSPEC_FYL2X))
16365    (clobber (match_scratch:XF 3 "=2"))]
16366   "TARGET_USE_FANCY_MATH_387
16367    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16368        || TARGET_MIX_SSE_I387)
16369    && flag_unsafe_math_optimizations"
16370   "fyl2x"
16371   [(set_attr "type" "fpspc")
16372    (set_attr "mode" "XF")])
16373
16374 (define_expand "logxf2"
16375   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16376                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16377                                (match_dup 2)] UNSPEC_FYL2X))
16378               (clobber (match_scratch:XF 3 ""))])]
16379   "TARGET_USE_FANCY_MATH_387
16380    && flag_unsafe_math_optimizations"
16381 {
16382   operands[2] = gen_reg_rtx (XFmode);
16383   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16384 })
16385
16386 (define_expand "log<mode>2"
16387   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16388    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
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 {
16394   rtx op0 = gen_reg_rtx (XFmode);
16395
16396   rtx op2 = gen_reg_rtx (XFmode);
16397   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16398
16399   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16400   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16401   DONE;
16402 })
16403
16404 (define_expand "log10xf2"
16405   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16406                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16407                                (match_dup 2)] UNSPEC_FYL2X))
16408               (clobber (match_scratch:XF 3 ""))])]
16409   "TARGET_USE_FANCY_MATH_387
16410    && flag_unsafe_math_optimizations"
16411 {
16412   operands[2] = gen_reg_rtx (XFmode);
16413   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16414 })
16415
16416 (define_expand "log10<mode>2"
16417   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16418    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16419   "TARGET_USE_FANCY_MATH_387
16420    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16421        || TARGET_MIX_SSE_I387)
16422    && flag_unsafe_math_optimizations"
16423 {
16424   rtx op0 = gen_reg_rtx (XFmode);
16425
16426   rtx op2 = gen_reg_rtx (XFmode);
16427   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16428
16429   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16430   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16431   DONE;
16432 })
16433
16434 (define_expand "log2xf2"
16435   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16436                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16437                                (match_dup 2)] UNSPEC_FYL2X))
16438               (clobber (match_scratch:XF 3 ""))])]
16439   "TARGET_USE_FANCY_MATH_387
16440    && flag_unsafe_math_optimizations"
16441 {
16442   operands[2] = gen_reg_rtx (XFmode);
16443   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16444 })
16445
16446 (define_expand "log2<mode>2"
16447   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16448    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16449   "TARGET_USE_FANCY_MATH_387
16450    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16451        || TARGET_MIX_SSE_I387)
16452    && flag_unsafe_math_optimizations"
16453 {
16454   rtx op0 = gen_reg_rtx (XFmode);
16455
16456   rtx op2 = gen_reg_rtx (XFmode);
16457   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16458
16459   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16460   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16461   DONE;
16462 })
16463
16464 (define_insn "fyl2xp1xf3_i387"
16465   [(set (match_operand:XF 0 "register_operand" "=f")
16466         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16467                     (match_operand:XF 2 "register_operand" "u")]
16468                    UNSPEC_FYL2XP1))
16469    (clobber (match_scratch:XF 3 "=2"))]
16470   "TARGET_USE_FANCY_MATH_387
16471    && flag_unsafe_math_optimizations"
16472   "fyl2xp1"
16473   [(set_attr "type" "fpspc")
16474    (set_attr "mode" "XF")])
16475
16476 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16477   [(set (match_operand:XF 0 "register_operand" "=f")
16478         (unspec:XF [(float_extend:XF
16479                       (match_operand:X87MODEF12 1 "register_operand" "0"))
16480                     (match_operand:XF 2 "register_operand" "u")]
16481                    UNSPEC_FYL2XP1))
16482    (clobber (match_scratch:XF 3 "=2"))]
16483   "TARGET_USE_FANCY_MATH_387
16484    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16485        || TARGET_MIX_SSE_I387)
16486    && flag_unsafe_math_optimizations"
16487   "fyl2xp1"
16488   [(set_attr "type" "fpspc")
16489    (set_attr "mode" "XF")])
16490
16491 (define_expand "log1pxf2"
16492   [(use (match_operand:XF 0 "register_operand" ""))
16493    (use (match_operand:XF 1 "register_operand" ""))]
16494   "TARGET_USE_FANCY_MATH_387
16495    && flag_unsafe_math_optimizations && !optimize_size"
16496 {
16497   ix86_emit_i387_log1p (operands[0], operands[1]);
16498   DONE;
16499 })
16500
16501 (define_expand "log1p<mode>2"
16502   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16503    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16504   "TARGET_USE_FANCY_MATH_387
16505    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16506        || TARGET_MIX_SSE_I387)
16507    && flag_unsafe_math_optimizations && !optimize_size"
16508 {
16509   rtx op0 = gen_reg_rtx (XFmode);
16510
16511   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16512
16513   ix86_emit_i387_log1p (op0, operands[1]);
16514   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16515   DONE;
16516 })
16517
16518 (define_insn "fxtractxf3_i387"
16519   [(set (match_operand:XF 0 "register_operand" "=f")
16520         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16521                    UNSPEC_XTRACT_FRACT))
16522    (set (match_operand:XF 1 "register_operand" "=u")
16523         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16524   "TARGET_USE_FANCY_MATH_387
16525    && flag_unsafe_math_optimizations"
16526   "fxtract"
16527   [(set_attr "type" "fpspc")
16528    (set_attr "mode" "XF")])
16529
16530 (define_insn "fxtract_extend<mode>xf3_i387"
16531   [(set (match_operand:XF 0 "register_operand" "=f")
16532         (unspec:XF [(float_extend:XF
16533                       (match_operand:X87MODEF12 2 "register_operand" "0"))]
16534                    UNSPEC_XTRACT_FRACT))
16535    (set (match_operand:XF 1 "register_operand" "=u")
16536         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16537   "TARGET_USE_FANCY_MATH_387
16538    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16539        || TARGET_MIX_SSE_I387)
16540    && flag_unsafe_math_optimizations"
16541   "fxtract"
16542   [(set_attr "type" "fpspc")
16543    (set_attr "mode" "XF")])
16544
16545 (define_expand "logbxf2"
16546   [(parallel [(set (match_dup 2)
16547                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16548                               UNSPEC_XTRACT_FRACT))
16549               (set (match_operand:XF 0 "register_operand" "")
16550                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16551   "TARGET_USE_FANCY_MATH_387
16552    && flag_unsafe_math_optimizations"
16553 {
16554   operands[2] = gen_reg_rtx (XFmode);
16555 })
16556
16557 (define_expand "logb<mode>2"
16558   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16559    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16560   "TARGET_USE_FANCY_MATH_387
16561    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16562        || TARGET_MIX_SSE_I387)
16563    && flag_unsafe_math_optimizations"
16564 {
16565   rtx op0 = gen_reg_rtx (XFmode);
16566   rtx op1 = gen_reg_rtx (XFmode);
16567
16568   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16569   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16570   DONE;
16571 })
16572
16573 (define_expand "ilogbxf2"
16574   [(use (match_operand:SI 0 "register_operand" ""))
16575    (use (match_operand:XF 1 "register_operand" ""))]
16576   "TARGET_USE_FANCY_MATH_387
16577    && flag_unsafe_math_optimizations && !optimize_size"
16578 {
16579   rtx op0 = gen_reg_rtx (XFmode);
16580   rtx op1 = gen_reg_rtx (XFmode);
16581
16582   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16583   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16584   DONE;
16585 })
16586
16587 (define_expand "ilogb<mode>2"
16588   [(use (match_operand:SI 0 "register_operand" ""))
16589    (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16590   "TARGET_USE_FANCY_MATH_387
16591    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16592        || TARGET_MIX_SSE_I387)
16593    && flag_unsafe_math_optimizations && !optimize_size"
16594 {
16595   rtx op0 = gen_reg_rtx (XFmode);
16596   rtx op1 = gen_reg_rtx (XFmode);
16597
16598   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16599   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16600   DONE;
16601 })
16602
16603 (define_insn "*f2xm1xf2_i387"
16604   [(set (match_operand:XF 0 "register_operand" "=f")
16605         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16606                    UNSPEC_F2XM1))]
16607   "TARGET_USE_FANCY_MATH_387
16608    && flag_unsafe_math_optimizations"
16609   "f2xm1"
16610   [(set_attr "type" "fpspc")
16611    (set_attr "mode" "XF")])
16612
16613 (define_insn "*fscalexf4_i387"
16614   [(set (match_operand:XF 0 "register_operand" "=f")
16615         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16616                     (match_operand:XF 3 "register_operand" "1")]
16617                    UNSPEC_FSCALE_FRACT))
16618    (set (match_operand:XF 1 "register_operand" "=u")
16619         (unspec:XF [(match_dup 2) (match_dup 3)]
16620                    UNSPEC_FSCALE_EXP))]
16621   "TARGET_USE_FANCY_MATH_387
16622    && flag_unsafe_math_optimizations"
16623   "fscale"
16624   [(set_attr "type" "fpspc")
16625    (set_attr "mode" "XF")])
16626
16627 (define_expand "expNcorexf3"
16628   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16629                                (match_operand:XF 2 "register_operand" "")))
16630    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16631    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16632    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16633    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16634    (parallel [(set (match_operand:XF 0 "register_operand" "")
16635                    (unspec:XF [(match_dup 8) (match_dup 4)]
16636                               UNSPEC_FSCALE_FRACT))
16637               (set (match_dup 9)
16638                    (unspec:XF [(match_dup 8) (match_dup 4)]
16639                               UNSPEC_FSCALE_EXP))])]
16640   "TARGET_USE_FANCY_MATH_387
16641    && flag_unsafe_math_optimizations && !optimize_size"
16642 {
16643   int i;
16644
16645   for (i = 3; i < 10; i++)
16646     operands[i] = gen_reg_rtx (XFmode);
16647
16648   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16649 })
16650
16651 (define_expand "expxf2"
16652   [(use (match_operand:XF 0 "register_operand" ""))
16653    (use (match_operand:XF 1 "register_operand" ""))]
16654   "TARGET_USE_FANCY_MATH_387
16655    && flag_unsafe_math_optimizations && !optimize_size"
16656 {
16657   rtx op2 = gen_reg_rtx (XFmode);
16658   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16659
16660   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16661   DONE;
16662 })
16663
16664 (define_expand "exp<mode>2"
16665   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16666    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16667  "TARGET_USE_FANCY_MATH_387
16668    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16669        || TARGET_MIX_SSE_I387)
16670    && flag_unsafe_math_optimizations && !optimize_size"
16671 {
16672   rtx op0 = gen_reg_rtx (XFmode);
16673   rtx op1 = gen_reg_rtx (XFmode);
16674
16675   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16676   emit_insn (gen_expxf2 (op0, op1));
16677   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16678   DONE;
16679 })
16680
16681 (define_expand "exp10xf2"
16682   [(use (match_operand:XF 0 "register_operand" ""))
16683    (use (match_operand:XF 1 "register_operand" ""))]
16684   "TARGET_USE_FANCY_MATH_387
16685    && flag_unsafe_math_optimizations && !optimize_size"
16686 {
16687   rtx op2 = gen_reg_rtx (XFmode);
16688   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16689
16690   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16691   DONE;
16692 })
16693
16694 (define_expand "exp10<mode>2"
16695   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16696    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16697  "TARGET_USE_FANCY_MATH_387
16698    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16699        || TARGET_MIX_SSE_I387)
16700    && flag_unsafe_math_optimizations && !optimize_size"
16701 {
16702   rtx op0 = gen_reg_rtx (XFmode);
16703   rtx op1 = gen_reg_rtx (XFmode);
16704
16705   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16706   emit_insn (gen_exp10xf2 (op0, op1));
16707   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16708   DONE;
16709 })
16710
16711 (define_expand "exp2xf2"
16712   [(use (match_operand:XF 0 "register_operand" ""))
16713    (use (match_operand:XF 1 "register_operand" ""))]
16714   "TARGET_USE_FANCY_MATH_387
16715    && flag_unsafe_math_optimizations && !optimize_size"
16716 {
16717   rtx op2 = gen_reg_rtx (XFmode);
16718   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
16719
16720   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16721   DONE;
16722 })
16723
16724 (define_expand "exp2<mode>2"
16725   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16726    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16727  "TARGET_USE_FANCY_MATH_387
16728    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16729        || TARGET_MIX_SSE_I387)
16730    && flag_unsafe_math_optimizations && !optimize_size"
16731 {
16732   rtx op0 = gen_reg_rtx (XFmode);
16733   rtx op1 = gen_reg_rtx (XFmode);
16734
16735   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16736   emit_insn (gen_exp2xf2 (op0, op1));
16737   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16738   DONE;
16739 })
16740
16741 (define_expand "expm1xf2"
16742   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16743                                (match_dup 2)))
16744    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16745    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16746    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16747    (parallel [(set (match_dup 7)
16748                    (unspec:XF [(match_dup 6) (match_dup 4)]
16749                               UNSPEC_FSCALE_FRACT))
16750                    (set (match_dup 8)
16751                    (unspec:XF [(match_dup 6) (match_dup 4)]
16752                               UNSPEC_FSCALE_EXP))])
16753    (parallel [(set (match_dup 10)
16754                    (unspec:XF [(match_dup 9) (match_dup 8)]
16755                               UNSPEC_FSCALE_FRACT))
16756               (set (match_dup 11)
16757                    (unspec:XF [(match_dup 9) (match_dup 8)]
16758                               UNSPEC_FSCALE_EXP))])
16759    (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16760    (set (match_operand:XF 0 "register_operand" "")
16761         (plus:XF (match_dup 12) (match_dup 7)))]
16762   "TARGET_USE_FANCY_MATH_387
16763    && flag_unsafe_math_optimizations && !optimize_size"
16764 {
16765   int i;
16766
16767   for (i = 2; i < 13; i++)
16768     operands[i] = gen_reg_rtx (XFmode);
16769  
16770   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16771   emit_move_insn (operands[9], CONST1_RTX (XFmode));  /* fld1 */
16772 })
16773
16774 (define_expand "expm1<mode>2"
16775   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16776    (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16777  "TARGET_USE_FANCY_MATH_387
16778    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16779        || TARGET_MIX_SSE_I387)
16780    && flag_unsafe_math_optimizations && !optimize_size"
16781 {
16782   rtx op0 = gen_reg_rtx (XFmode);
16783   rtx op1 = gen_reg_rtx (XFmode);
16784
16785   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16786   emit_insn (gen_expm1xf2 (op0, op1));
16787   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16788   DONE;
16789 })
16790
16791 (define_expand "ldexpxf3"
16792   [(set (match_dup 3)
16793         (float:XF (match_operand:SI 2 "register_operand" "")))
16794    (parallel [(set (match_operand:XF 0 " register_operand" "")
16795                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16796                                (match_dup 3)]
16797                               UNSPEC_FSCALE_FRACT))
16798               (set (match_dup 4)
16799                    (unspec:XF [(match_dup 1) (match_dup 3)]
16800                               UNSPEC_FSCALE_EXP))])]
16801   "TARGET_USE_FANCY_MATH_387
16802    && flag_unsafe_math_optimizations && !optimize_size"
16803 {
16804   operands[3] = gen_reg_rtx (XFmode);
16805   operands[4] = gen_reg_rtx (XFmode);
16806 })
16807
16808 (define_expand "ldexp<mode>3"
16809   [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16810    (use (match_operand:X87MODEF12 1 "general_operand" ""))
16811    (use (match_operand:SI 2 "register_operand" ""))]
16812  "TARGET_USE_FANCY_MATH_387
16813    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16814        || TARGET_MIX_SSE_I387)
16815    && flag_unsafe_math_optimizations && !optimize_size"
16816 {
16817   rtx op0 = gen_reg_rtx (XFmode);
16818   rtx op1 = gen_reg_rtx (XFmode);
16819
16820   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16821   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16822   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16823   DONE;
16824 })
16825 \f
16826
16827 (define_insn "frndintxf2"
16828   [(set (match_operand:XF 0 "register_operand" "=f")
16829         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16830          UNSPEC_FRNDINT))]
16831   "TARGET_USE_FANCY_MATH_387
16832    && flag_unsafe_math_optimizations"
16833   "frndint"
16834   [(set_attr "type" "fpspc")
16835    (set_attr "mode" "XF")])
16836
16837 (define_expand "rintdf2"
16838   [(use (match_operand:DF 0 "register_operand" ""))
16839    (use (match_operand:DF 1 "register_operand" ""))]
16840   "(TARGET_USE_FANCY_MATH_387
16841     && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16842     && flag_unsafe_math_optimizations)
16843    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16844        && !flag_trapping_math
16845        && !optimize_size)"
16846 {
16847   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16848       && !flag_trapping_math
16849       && !optimize_size)
16850     ix86_expand_rint (operand0, operand1);
16851   else
16852     {
16853       rtx op0 = gen_reg_rtx (XFmode);
16854       rtx op1 = gen_reg_rtx (XFmode);
16855
16856       emit_insn (gen_extenddfxf2 (op1, operands[1]));
16857       emit_insn (gen_frndintxf2 (op0, op1));
16858
16859       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16860     }
16861   DONE;
16862 })
16863
16864 (define_expand "rintsf2"
16865   [(use (match_operand:SF 0 "register_operand" ""))
16866    (use (match_operand:SF 1 "register_operand" ""))]
16867   "(TARGET_USE_FANCY_MATH_387
16868     && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16869     && flag_unsafe_math_optimizations)
16870    || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16871        && !flag_trapping_math
16872        && !optimize_size)"
16873 {
16874   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16875       && !flag_trapping_math
16876       && !optimize_size)
16877     ix86_expand_rint (operand0, operand1);
16878   else
16879     {
16880       rtx op0 = gen_reg_rtx (XFmode);
16881       rtx op1 = gen_reg_rtx (XFmode);
16882
16883       emit_insn (gen_extendsfxf2 (op1, operands[1]));
16884       emit_insn (gen_frndintxf2 (op0, op1));
16885
16886       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16887     }
16888   DONE;
16889 })
16890
16891 (define_expand "rintxf2"
16892   [(use (match_operand:XF 0 "register_operand" ""))
16893    (use (match_operand:XF 1 "register_operand" ""))]
16894   "TARGET_USE_FANCY_MATH_387
16895    && flag_unsafe_math_optimizations && !optimize_size"
16896 {
16897   emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16898   DONE;
16899 })
16900
16901 (define_expand "roundsf2"
16902   [(match_operand:SF 0 "register_operand" "")
16903    (match_operand:SF 1 "nonimmediate_operand" "")]
16904   "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16905    && !flag_trapping_math && !flag_rounding_math
16906    && !optimize_size"
16907 {
16908   ix86_expand_round (operand0, operand1);
16909   DONE;
16910 })
16911
16912 (define_expand "rounddf2"
16913   [(match_operand:DF 0 "register_operand" "")
16914    (match_operand:DF 1 "nonimmediate_operand" "")]
16915   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16916    && !flag_trapping_math && !flag_rounding_math
16917    && !optimize_size"
16918 {
16919   if (TARGET_64BIT)
16920     ix86_expand_round (operand0, operand1);
16921   else
16922     ix86_expand_rounddf_32 (operand0, operand1);
16923   DONE;
16924 })
16925
16926 (define_insn_and_split "*fistdi2_1"
16927   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16928         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16929          UNSPEC_FIST))]
16930   "TARGET_USE_FANCY_MATH_387
16931    && !(reload_completed || reload_in_progress)"
16932   "#"
16933   "&& 1"
16934   [(const_int 0)]
16935 {
16936   if (memory_operand (operands[0], VOIDmode))
16937     emit_insn (gen_fistdi2 (operands[0], operands[1]));
16938   else
16939     {
16940       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16941       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16942                                          operands[2]));
16943     }
16944   DONE;
16945 }
16946   [(set_attr "type" "fpspc")
16947    (set_attr "mode" "DI")])
16948
16949 (define_insn "fistdi2"
16950   [(set (match_operand:DI 0 "memory_operand" "=m")
16951         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16952          UNSPEC_FIST))
16953    (clobber (match_scratch:XF 2 "=&1f"))]
16954   "TARGET_USE_FANCY_MATH_387"
16955   "* return output_fix_trunc (insn, operands, 0);"
16956   [(set_attr "type" "fpspc")
16957    (set_attr "mode" "DI")])
16958
16959 (define_insn "fistdi2_with_temp"
16960   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16961         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16962          UNSPEC_FIST))
16963    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16964    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16965   "TARGET_USE_FANCY_MATH_387"
16966   "#"
16967   [(set_attr "type" "fpspc")
16968    (set_attr "mode" "DI")])
16969
16970 (define_split
16971   [(set (match_operand:DI 0 "register_operand" "")
16972         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16973          UNSPEC_FIST))
16974    (clobber (match_operand:DI 2 "memory_operand" ""))
16975    (clobber (match_scratch 3 ""))]
16976   "reload_completed"
16977   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16978               (clobber (match_dup 3))])
16979    (set (match_dup 0) (match_dup 2))]
16980   "")
16981
16982 (define_split
16983   [(set (match_operand:DI 0 "memory_operand" "")
16984         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16985          UNSPEC_FIST))
16986    (clobber (match_operand:DI 2 "memory_operand" ""))
16987    (clobber (match_scratch 3 ""))]
16988   "reload_completed"
16989   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16990               (clobber (match_dup 3))])]
16991   "")
16992
16993 (define_insn_and_split "*fist<mode>2_1"
16994   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16995         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16996          UNSPEC_FIST))]
16997   "TARGET_USE_FANCY_MATH_387
16998    && !(reload_completed || reload_in_progress)"
16999   "#"
17000   "&& 1"
17001   [(const_int 0)]
17002 {
17003   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17004   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17005                                         operands[2]));
17006   DONE;
17007 }
17008   [(set_attr "type" "fpspc")
17009    (set_attr "mode" "<MODE>")])
17010
17011 (define_insn "fist<mode>2"
17012   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17013         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17014          UNSPEC_FIST))]
17015   "TARGET_USE_FANCY_MATH_387"
17016   "* return output_fix_trunc (insn, operands, 0);"
17017   [(set_attr "type" "fpspc")
17018    (set_attr "mode" "<MODE>")])
17019
17020 (define_insn "fist<mode>2_with_temp"
17021   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17022         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17023          UNSPEC_FIST))
17024    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17025   "TARGET_USE_FANCY_MATH_387"
17026   "#"
17027   [(set_attr "type" "fpspc")
17028    (set_attr "mode" "<MODE>")])
17029
17030 (define_split
17031   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17032         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17033          UNSPEC_FIST))
17034    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17035   "reload_completed"
17036   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17037                        UNSPEC_FIST))
17038    (set (match_dup 0) (match_dup 2))]
17039   "")
17040
17041 (define_split
17042   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17043         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17044          UNSPEC_FIST))
17045    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17046   "reload_completed"
17047   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17048                        UNSPEC_FIST))]
17049   "")
17050
17051 (define_expand "lrintxf<mode>2"
17052   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17053      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17054       UNSPEC_FIST))]
17055   "TARGET_USE_FANCY_MATH_387"
17056   "")
17057
17058 (define_expand "lrint<mode>di2"
17059   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17060      (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
17061       UNSPEC_FIX_NOTRUNC))]
17062   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
17063   "")
17064
17065 (define_expand "lrint<mode>si2"
17066   [(set (match_operand:SI 0 "nonimmediate_operand" "")
17067      (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
17068       UNSPEC_FIX_NOTRUNC))]
17069   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17070   "")
17071
17072 (define_expand "lround<mode>di2"
17073   [(match_operand:DI 0 "nonimmediate_operand" "")
17074    (match_operand:SSEMODEF 1 "register_operand" "")]
17075   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17076    && !flag_trapping_math && !flag_rounding_math
17077    && !optimize_size"
17078 {
17079   ix86_expand_lround (operand0, operand1);
17080   DONE;
17081 })
17082
17083 (define_expand "lround<mode>si2"
17084   [(match_operand:SI 0 "nonimmediate_operand" "")
17085    (match_operand:SSEMODEF 1 "register_operand" "")]
17086   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17087    && !flag_trapping_math && !flag_rounding_math
17088    && !optimize_size"
17089 {
17090   ix86_expand_lround (operand0, operand1);
17091   DONE;
17092 })
17093
17094 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17095 (define_insn_and_split "frndintxf2_floor"
17096   [(set (match_operand:XF 0 "register_operand" "=f")
17097         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17098          UNSPEC_FRNDINT_FLOOR))
17099    (clobber (reg:CC FLAGS_REG))]
17100   "TARGET_USE_FANCY_MATH_387
17101    && flag_unsafe_math_optimizations
17102    && !(reload_completed || reload_in_progress)"
17103   "#"
17104   "&& 1"
17105   [(const_int 0)]
17106 {
17107   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17108
17109   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17110   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17111
17112   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17113                                         operands[2], operands[3]));
17114   DONE;
17115 }
17116   [(set_attr "type" "frndint")
17117    (set_attr "i387_cw" "floor")
17118    (set_attr "mode" "XF")])
17119
17120 (define_insn "frndintxf2_floor_i387"
17121   [(set (match_operand:XF 0 "register_operand" "=f")
17122         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17123          UNSPEC_FRNDINT_FLOOR))
17124    (use (match_operand:HI 2 "memory_operand" "m"))
17125    (use (match_operand:HI 3 "memory_operand" "m"))]
17126   "TARGET_USE_FANCY_MATH_387
17127    && flag_unsafe_math_optimizations"
17128   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17129   [(set_attr "type" "frndint")
17130    (set_attr "i387_cw" "floor")
17131    (set_attr "mode" "XF")])
17132
17133 (define_expand "floorxf2"
17134   [(use (match_operand:XF 0 "register_operand" ""))
17135    (use (match_operand:XF 1 "register_operand" ""))]
17136   "TARGET_USE_FANCY_MATH_387
17137    && flag_unsafe_math_optimizations && !optimize_size"
17138 {
17139   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17140   DONE;
17141 })
17142
17143 (define_expand "floordf2"
17144   [(use (match_operand:DF 0 "register_operand" ""))
17145    (use (match_operand:DF 1 "register_operand" ""))]
17146   "((TARGET_USE_FANCY_MATH_387
17147      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17148      && flag_unsafe_math_optimizations)
17149     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17150         && !flag_trapping_math))
17151    && !optimize_size"
17152 {
17153   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17154       && !flag_trapping_math)
17155     {
17156       if (TARGET_64BIT)
17157         ix86_expand_floorceil (operand0, operand1, true);
17158       else
17159         ix86_expand_floorceildf_32 (operand0, operand1, true);
17160     }
17161   else
17162     {
17163       rtx op0 = gen_reg_rtx (XFmode);
17164       rtx op1 = gen_reg_rtx (XFmode);
17165
17166       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17167       emit_insn (gen_frndintxf2_floor (op0, op1));
17168
17169       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17170     }
17171   DONE;
17172 })
17173
17174 (define_expand "floorsf2"
17175   [(use (match_operand:SF 0 "register_operand" ""))
17176    (use (match_operand:SF 1 "register_operand" ""))]
17177   "((TARGET_USE_FANCY_MATH_387
17178      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17179      && flag_unsafe_math_optimizations)
17180     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17181         && !flag_trapping_math))
17182    && !optimize_size"
17183 {
17184   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17185       && !flag_trapping_math)
17186     ix86_expand_floorceil (operand0, operand1, true);
17187   else
17188     {
17189       rtx op0 = gen_reg_rtx (XFmode);
17190       rtx op1 = gen_reg_rtx (XFmode);
17191
17192       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17193       emit_insn (gen_frndintxf2_floor (op0, op1));
17194
17195       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17196     }
17197   DONE;
17198 })
17199
17200 (define_insn_and_split "*fist<mode>2_floor_1"
17201   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17202         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17203          UNSPEC_FIST_FLOOR))
17204    (clobber (reg:CC FLAGS_REG))]
17205   "TARGET_USE_FANCY_MATH_387
17206    && flag_unsafe_math_optimizations
17207    && !(reload_completed || reload_in_progress)"
17208   "#"
17209   "&& 1"
17210   [(const_int 0)]
17211 {
17212   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17213
17214   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17215   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17216   if (memory_operand (operands[0], VOIDmode))
17217     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17218                                       operands[2], operands[3]));
17219   else
17220     {
17221       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17222       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17223                                                   operands[2], operands[3],
17224                                                   operands[4]));
17225     }
17226   DONE;
17227 }
17228   [(set_attr "type" "fistp")
17229    (set_attr "i387_cw" "floor")
17230    (set_attr "mode" "<MODE>")])
17231
17232 (define_insn "fistdi2_floor"
17233   [(set (match_operand:DI 0 "memory_operand" "=m")
17234         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17235          UNSPEC_FIST_FLOOR))
17236    (use (match_operand:HI 2 "memory_operand" "m"))
17237    (use (match_operand:HI 3 "memory_operand" "m"))
17238    (clobber (match_scratch:XF 4 "=&1f"))]
17239   "TARGET_USE_FANCY_MATH_387
17240    && flag_unsafe_math_optimizations"
17241   "* return output_fix_trunc (insn, operands, 0);"
17242   [(set_attr "type" "fistp")
17243    (set_attr "i387_cw" "floor")
17244    (set_attr "mode" "DI")])
17245
17246 (define_insn "fistdi2_floor_with_temp"
17247   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17248         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17249          UNSPEC_FIST_FLOOR))
17250    (use (match_operand:HI 2 "memory_operand" "m,m"))
17251    (use (match_operand:HI 3 "memory_operand" "m,m"))
17252    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17253    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17254   "TARGET_USE_FANCY_MATH_387
17255    && flag_unsafe_math_optimizations"
17256   "#"
17257   [(set_attr "type" "fistp")
17258    (set_attr "i387_cw" "floor")
17259    (set_attr "mode" "DI")])
17260
17261 (define_split
17262   [(set (match_operand:DI 0 "register_operand" "")
17263         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17264          UNSPEC_FIST_FLOOR))
17265    (use (match_operand:HI 2 "memory_operand" ""))
17266    (use (match_operand:HI 3 "memory_operand" ""))
17267    (clobber (match_operand:DI 4 "memory_operand" ""))
17268    (clobber (match_scratch 5 ""))]
17269   "reload_completed"
17270   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17271               (use (match_dup 2))
17272               (use (match_dup 3))
17273               (clobber (match_dup 5))])
17274    (set (match_dup 0) (match_dup 4))]
17275   "")
17276
17277 (define_split
17278   [(set (match_operand:DI 0 "memory_operand" "")
17279         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17280          UNSPEC_FIST_FLOOR))
17281    (use (match_operand:HI 2 "memory_operand" ""))
17282    (use (match_operand:HI 3 "memory_operand" ""))
17283    (clobber (match_operand:DI 4 "memory_operand" ""))
17284    (clobber (match_scratch 5 ""))]
17285   "reload_completed"
17286   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17287               (use (match_dup 2))
17288               (use (match_dup 3))
17289               (clobber (match_dup 5))])]
17290   "")
17291
17292 (define_insn "fist<mode>2_floor"
17293   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17294         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17295          UNSPEC_FIST_FLOOR))
17296    (use (match_operand:HI 2 "memory_operand" "m"))
17297    (use (match_operand:HI 3 "memory_operand" "m"))]
17298   "TARGET_USE_FANCY_MATH_387
17299    && flag_unsafe_math_optimizations"
17300   "* return output_fix_trunc (insn, operands, 0);"
17301   [(set_attr "type" "fistp")
17302    (set_attr "i387_cw" "floor")
17303    (set_attr "mode" "<MODE>")])
17304
17305 (define_insn "fist<mode>2_floor_with_temp"
17306   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17307         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17308          UNSPEC_FIST_FLOOR))
17309    (use (match_operand:HI 2 "memory_operand" "m,m"))
17310    (use (match_operand:HI 3 "memory_operand" "m,m"))
17311    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17312   "TARGET_USE_FANCY_MATH_387
17313    && flag_unsafe_math_optimizations"
17314   "#"
17315   [(set_attr "type" "fistp")
17316    (set_attr "i387_cw" "floor")
17317    (set_attr "mode" "<MODE>")])
17318
17319 (define_split
17320   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17321         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17322          UNSPEC_FIST_FLOOR))
17323    (use (match_operand:HI 2 "memory_operand" ""))
17324    (use (match_operand:HI 3 "memory_operand" ""))
17325    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17326   "reload_completed"
17327   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17328                                   UNSPEC_FIST_FLOOR))
17329               (use (match_dup 2))
17330               (use (match_dup 3))])
17331    (set (match_dup 0) (match_dup 4))]
17332   "")
17333
17334 (define_split
17335   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17336         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17337          UNSPEC_FIST_FLOOR))
17338    (use (match_operand:HI 2 "memory_operand" ""))
17339    (use (match_operand:HI 3 "memory_operand" ""))
17340    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17341   "reload_completed"
17342   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17343                                   UNSPEC_FIST_FLOOR))
17344               (use (match_dup 2))
17345               (use (match_dup 3))])]
17346   "")
17347
17348 (define_expand "lfloorxf<mode>2"
17349   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17350                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17351                     UNSPEC_FIST_FLOOR))
17352               (clobber (reg:CC FLAGS_REG))])]
17353   "TARGET_USE_FANCY_MATH_387
17354    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17355    && flag_unsafe_math_optimizations"
17356   "")
17357
17358 (define_expand "lfloor<mode>di2"
17359   [(match_operand:DI 0 "nonimmediate_operand" "")
17360    (match_operand:SSEMODEF 1 "register_operand" "")]
17361   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17362    && !flag_trapping_math
17363    && !optimize_size"
17364 {
17365   ix86_expand_lfloorceil (operand0, operand1, true);
17366   DONE;
17367 })
17368
17369 (define_expand "lfloor<mode>si2"
17370   [(match_operand:SI 0 "nonimmediate_operand" "")
17371    (match_operand:SSEMODEF 1 "register_operand" "")]
17372   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17373    && !flag_trapping_math
17374    && (!optimize_size || !TARGET_64BIT)"
17375 {
17376   ix86_expand_lfloorceil (operand0, operand1, true);
17377   DONE;
17378 })
17379
17380 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17381 (define_insn_and_split "frndintxf2_ceil"
17382   [(set (match_operand:XF 0 "register_operand" "=f")
17383         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17384          UNSPEC_FRNDINT_CEIL))
17385    (clobber (reg:CC FLAGS_REG))]
17386   "TARGET_USE_FANCY_MATH_387
17387    && flag_unsafe_math_optimizations
17388    && !(reload_completed || reload_in_progress)"
17389   "#"
17390   "&& 1"
17391   [(const_int 0)]
17392 {
17393   ix86_optimize_mode_switching[I387_CEIL] = 1;
17394
17395   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17396   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17397
17398   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17399                                        operands[2], operands[3]));
17400   DONE;
17401 }
17402   [(set_attr "type" "frndint")
17403    (set_attr "i387_cw" "ceil")
17404    (set_attr "mode" "XF")])
17405
17406 (define_insn "frndintxf2_ceil_i387"
17407   [(set (match_operand:XF 0 "register_operand" "=f")
17408         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17409          UNSPEC_FRNDINT_CEIL))
17410    (use (match_operand:HI 2 "memory_operand" "m"))
17411    (use (match_operand:HI 3 "memory_operand" "m"))]
17412   "TARGET_USE_FANCY_MATH_387
17413    && flag_unsafe_math_optimizations"
17414   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17415   [(set_attr "type" "frndint")
17416    (set_attr "i387_cw" "ceil")
17417    (set_attr "mode" "XF")])
17418
17419 (define_expand "ceilxf2"
17420   [(use (match_operand:XF 0 "register_operand" ""))
17421    (use (match_operand:XF 1 "register_operand" ""))]
17422   "TARGET_USE_FANCY_MATH_387
17423    && flag_unsafe_math_optimizations && !optimize_size"
17424 {
17425   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17426   DONE;
17427 })
17428
17429 (define_expand "ceildf2"
17430   [(use (match_operand:DF 0 "register_operand" ""))
17431    (use (match_operand:DF 1 "register_operand" ""))]
17432   "((TARGET_USE_FANCY_MATH_387
17433      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17434      && flag_unsafe_math_optimizations)
17435     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17436         && !flag_trapping_math))
17437    && !optimize_size"
17438 {
17439   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17440       && !flag_trapping_math)
17441     {
17442       if (TARGET_64BIT)
17443         ix86_expand_floorceil (operand0, operand1, false);
17444       else
17445         ix86_expand_floorceildf_32 (operand0, operand1, false);
17446     }
17447   else
17448     {
17449       rtx op0 = gen_reg_rtx (XFmode);
17450       rtx op1 = gen_reg_rtx (XFmode);
17451
17452       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17453       emit_insn (gen_frndintxf2_ceil (op0, op1));
17454
17455       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17456     }
17457   DONE;
17458 })
17459
17460 (define_expand "ceilsf2"
17461   [(use (match_operand:SF 0 "register_operand" ""))
17462    (use (match_operand:SF 1 "register_operand" ""))]
17463   "((TARGET_USE_FANCY_MATH_387
17464      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17465      && flag_unsafe_math_optimizations)
17466     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17467         && !flag_trapping_math))
17468    && !optimize_size"
17469 {
17470   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17471       && !flag_trapping_math)
17472     ix86_expand_floorceil (operand0, operand1, false);
17473   else
17474     {
17475       rtx op0 = gen_reg_rtx (XFmode);
17476       rtx op1 = gen_reg_rtx (XFmode);
17477
17478       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17479       emit_insn (gen_frndintxf2_ceil (op0, op1));
17480
17481       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17482     }
17483   DONE;
17484 })
17485
17486 (define_insn_and_split "*fist<mode>2_ceil_1"
17487   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17488         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17489          UNSPEC_FIST_CEIL))
17490    (clobber (reg:CC FLAGS_REG))]
17491   "TARGET_USE_FANCY_MATH_387
17492    && flag_unsafe_math_optimizations
17493    && !(reload_completed || reload_in_progress)"
17494   "#"
17495   "&& 1"
17496   [(const_int 0)]
17497 {
17498   ix86_optimize_mode_switching[I387_CEIL] = 1;
17499
17500   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17501   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17502   if (memory_operand (operands[0], VOIDmode))
17503     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17504                                      operands[2], operands[3]));
17505   else
17506     {
17507       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17508       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17509                                                  operands[2], operands[3],
17510                                                  operands[4]));
17511     }
17512   DONE;
17513 }
17514   [(set_attr "type" "fistp")
17515    (set_attr "i387_cw" "ceil")
17516    (set_attr "mode" "<MODE>")])
17517
17518 (define_insn "fistdi2_ceil"
17519   [(set (match_operand:DI 0 "memory_operand" "=m")
17520         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17521          UNSPEC_FIST_CEIL))
17522    (use (match_operand:HI 2 "memory_operand" "m"))
17523    (use (match_operand:HI 3 "memory_operand" "m"))
17524    (clobber (match_scratch:XF 4 "=&1f"))]
17525   "TARGET_USE_FANCY_MATH_387
17526    && flag_unsafe_math_optimizations"
17527   "* return output_fix_trunc (insn, operands, 0);"
17528   [(set_attr "type" "fistp")
17529    (set_attr "i387_cw" "ceil")
17530    (set_attr "mode" "DI")])
17531
17532 (define_insn "fistdi2_ceil_with_temp"
17533   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17534         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17535          UNSPEC_FIST_CEIL))
17536    (use (match_operand:HI 2 "memory_operand" "m,m"))
17537    (use (match_operand:HI 3 "memory_operand" "m,m"))
17538    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17539    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17540   "TARGET_USE_FANCY_MATH_387
17541    && flag_unsafe_math_optimizations"
17542   "#"
17543   [(set_attr "type" "fistp")
17544    (set_attr "i387_cw" "ceil")
17545    (set_attr "mode" "DI")])
17546
17547 (define_split
17548   [(set (match_operand:DI 0 "register_operand" "")
17549         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17550          UNSPEC_FIST_CEIL))
17551    (use (match_operand:HI 2 "memory_operand" ""))
17552    (use (match_operand:HI 3 "memory_operand" ""))
17553    (clobber (match_operand:DI 4 "memory_operand" ""))
17554    (clobber (match_scratch 5 ""))]
17555   "reload_completed"
17556   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17557               (use (match_dup 2))
17558               (use (match_dup 3))
17559               (clobber (match_dup 5))])
17560    (set (match_dup 0) (match_dup 4))]
17561   "")
17562
17563 (define_split
17564   [(set (match_operand:DI 0 "memory_operand" "")
17565         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17566          UNSPEC_FIST_CEIL))
17567    (use (match_operand:HI 2 "memory_operand" ""))
17568    (use (match_operand:HI 3 "memory_operand" ""))
17569    (clobber (match_operand:DI 4 "memory_operand" ""))
17570    (clobber (match_scratch 5 ""))]
17571   "reload_completed"
17572   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17573               (use (match_dup 2))
17574               (use (match_dup 3))
17575               (clobber (match_dup 5))])]
17576   "")
17577
17578 (define_insn "fist<mode>2_ceil"
17579   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17580         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17581          UNSPEC_FIST_CEIL))
17582    (use (match_operand:HI 2 "memory_operand" "m"))
17583    (use (match_operand:HI 3 "memory_operand" "m"))]
17584   "TARGET_USE_FANCY_MATH_387
17585    && flag_unsafe_math_optimizations"
17586   "* return output_fix_trunc (insn, operands, 0);"
17587   [(set_attr "type" "fistp")
17588    (set_attr "i387_cw" "ceil")
17589    (set_attr "mode" "<MODE>")])
17590
17591 (define_insn "fist<mode>2_ceil_with_temp"
17592   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17593         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17594          UNSPEC_FIST_CEIL))
17595    (use (match_operand:HI 2 "memory_operand" "m,m"))
17596    (use (match_operand:HI 3 "memory_operand" "m,m"))
17597    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17598   "TARGET_USE_FANCY_MATH_387
17599    && flag_unsafe_math_optimizations"
17600   "#"
17601   [(set_attr "type" "fistp")
17602    (set_attr "i387_cw" "ceil")
17603    (set_attr "mode" "<MODE>")])
17604
17605 (define_split
17606   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17607         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17608          UNSPEC_FIST_CEIL))
17609    (use (match_operand:HI 2 "memory_operand" ""))
17610    (use (match_operand:HI 3 "memory_operand" ""))
17611    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17612   "reload_completed"
17613   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17614                                   UNSPEC_FIST_CEIL))
17615               (use (match_dup 2))
17616               (use (match_dup 3))])
17617    (set (match_dup 0) (match_dup 4))]
17618   "")
17619
17620 (define_split
17621   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17622         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17623          UNSPEC_FIST_CEIL))
17624    (use (match_operand:HI 2 "memory_operand" ""))
17625    (use (match_operand:HI 3 "memory_operand" ""))
17626    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17627   "reload_completed"
17628   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17629                                   UNSPEC_FIST_CEIL))
17630               (use (match_dup 2))
17631               (use (match_dup 3))])]
17632   "")
17633
17634 (define_expand "lceilxf<mode>2"
17635   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17636                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17637                     UNSPEC_FIST_CEIL))
17638               (clobber (reg:CC FLAGS_REG))])]
17639   "TARGET_USE_FANCY_MATH_387
17640    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17641    && flag_unsafe_math_optimizations"
17642   "")
17643
17644 (define_expand "lceil<mode>di2"
17645   [(match_operand:DI 0 "nonimmediate_operand" "")
17646    (match_operand:SSEMODEF 1 "register_operand" "")]
17647   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17648    && !flag_trapping_math"
17649 {
17650   ix86_expand_lfloorceil (operand0, operand1, false);
17651   DONE;
17652 })
17653
17654 (define_expand "lceil<mode>si2"
17655   [(match_operand:SI 0 "nonimmediate_operand" "")
17656    (match_operand:SSEMODEF 1 "register_operand" "")]
17657   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17658    && !flag_trapping_math"
17659 {
17660   ix86_expand_lfloorceil (operand0, operand1, false);
17661   DONE;
17662 })
17663
17664 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17665 (define_insn_and_split "frndintxf2_trunc"
17666   [(set (match_operand:XF 0 "register_operand" "=f")
17667         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17668          UNSPEC_FRNDINT_TRUNC))
17669    (clobber (reg:CC FLAGS_REG))]
17670   "TARGET_USE_FANCY_MATH_387
17671    && flag_unsafe_math_optimizations
17672    && !(reload_completed || reload_in_progress)"
17673   "#"
17674   "&& 1"
17675   [(const_int 0)]
17676 {
17677   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17678
17679   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17680   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17681
17682   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17683                                         operands[2], operands[3]));
17684   DONE;
17685 }
17686   [(set_attr "type" "frndint")
17687    (set_attr "i387_cw" "trunc")
17688    (set_attr "mode" "XF")])
17689
17690 (define_insn "frndintxf2_trunc_i387"
17691   [(set (match_operand:XF 0 "register_operand" "=f")
17692         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17693          UNSPEC_FRNDINT_TRUNC))
17694    (use (match_operand:HI 2 "memory_operand" "m"))
17695    (use (match_operand:HI 3 "memory_operand" "m"))]
17696   "TARGET_USE_FANCY_MATH_387
17697    && flag_unsafe_math_optimizations"
17698   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17699   [(set_attr "type" "frndint")
17700    (set_attr "i387_cw" "trunc")
17701    (set_attr "mode" "XF")])
17702
17703 (define_expand "btruncxf2"
17704   [(use (match_operand:XF 0 "register_operand" ""))
17705    (use (match_operand:XF 1 "register_operand" ""))]
17706   "TARGET_USE_FANCY_MATH_387
17707    && flag_unsafe_math_optimizations && !optimize_size"
17708 {
17709   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17710   DONE;
17711 })
17712
17713 (define_expand "btruncdf2"
17714   [(use (match_operand:DF 0 "register_operand" ""))
17715    (use (match_operand:DF 1 "register_operand" ""))]
17716   "((TARGET_USE_FANCY_MATH_387
17717      && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17718      && flag_unsafe_math_optimizations)
17719     || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17720         && !flag_trapping_math))
17721    && !optimize_size"
17722 {
17723   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17724       && !flag_trapping_math)
17725     {
17726       if (TARGET_64BIT)
17727         ix86_expand_trunc (operand0, operand1);
17728       else
17729         ix86_expand_truncdf_32 (operand0, operand1);
17730     }
17731   else
17732     {
17733       rtx op0 = gen_reg_rtx (XFmode);
17734       rtx op1 = gen_reg_rtx (XFmode);
17735
17736       emit_insn (gen_extenddfxf2 (op1, operands[1]));
17737       emit_insn (gen_frndintxf2_trunc (op0, op1));
17738
17739       emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17740     }
17741   DONE;
17742 })
17743
17744 (define_expand "btruncsf2"
17745   [(use (match_operand:SF 0 "register_operand" ""))
17746    (use (match_operand:SF 1 "register_operand" ""))]
17747   "((TARGET_USE_FANCY_MATH_387
17748      && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17749      && flag_unsafe_math_optimizations)
17750     || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17751         && !flag_trapping_math))
17752    && !optimize_size"
17753 {
17754   if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17755       && !flag_trapping_math)
17756     ix86_expand_trunc (operand0, operand1);
17757   else
17758     {
17759       rtx op0 = gen_reg_rtx (XFmode);
17760       rtx op1 = gen_reg_rtx (XFmode);
17761
17762       emit_insn (gen_extendsfxf2 (op1, operands[1]));
17763       emit_insn (gen_frndintxf2_trunc (op0, op1));
17764
17765       emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17766     }
17767   DONE;
17768 })
17769
17770 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17771 (define_insn_and_split "frndintxf2_mask_pm"
17772   [(set (match_operand:XF 0 "register_operand" "=f")
17773         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17774          UNSPEC_FRNDINT_MASK_PM))
17775    (clobber (reg:CC FLAGS_REG))]
17776   "TARGET_USE_FANCY_MATH_387
17777    && flag_unsafe_math_optimizations
17778    && !(reload_completed || reload_in_progress)"
17779   "#"
17780   "&& 1"
17781   [(const_int 0)]
17782 {
17783   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17784
17785   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17786   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17787
17788   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17789                                           operands[2], operands[3]));
17790   DONE;
17791 }
17792   [(set_attr "type" "frndint")
17793    (set_attr "i387_cw" "mask_pm")
17794    (set_attr "mode" "XF")])
17795
17796 (define_insn "frndintxf2_mask_pm_i387"
17797   [(set (match_operand:XF 0 "register_operand" "=f")
17798         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17799          UNSPEC_FRNDINT_MASK_PM))
17800    (use (match_operand:HI 2 "memory_operand" "m"))
17801    (use (match_operand:HI 3 "memory_operand" "m"))]
17802   "TARGET_USE_FANCY_MATH_387
17803    && flag_unsafe_math_optimizations"
17804   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17805   [(set_attr "type" "frndint")
17806    (set_attr "i387_cw" "mask_pm")
17807    (set_attr "mode" "XF")])
17808
17809 (define_expand "nearbyintxf2"
17810   [(use (match_operand:XF 0 "register_operand" ""))
17811    (use (match_operand:XF 1 "register_operand" ""))]
17812   "TARGET_USE_FANCY_MATH_387
17813    && flag_unsafe_math_optimizations"
17814 {
17815   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17816
17817   DONE;
17818 })
17819
17820 (define_expand "nearbyintdf2"
17821   [(use (match_operand:DF 0 "register_operand" ""))
17822    (use (match_operand:DF 1 "register_operand" ""))]
17823   "TARGET_USE_FANCY_MATH_387
17824    && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17825    && flag_unsafe_math_optimizations"
17826 {
17827   rtx op0 = gen_reg_rtx (XFmode);
17828   rtx op1 = gen_reg_rtx (XFmode);
17829
17830   emit_insn (gen_extenddfxf2 (op1, operands[1]));
17831   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17832
17833   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17834   DONE;
17835 })
17836
17837 (define_expand "nearbyintsf2"
17838   [(use (match_operand:SF 0 "register_operand" ""))
17839    (use (match_operand:SF 1 "register_operand" ""))]
17840   "TARGET_USE_FANCY_MATH_387
17841    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17842    && flag_unsafe_math_optimizations"
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_mask_pm (op0, op1));
17849
17850   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17851   DONE;
17852 })
17853
17854 (define_insn "fxam<mode>2_i387"
17855   [(set (match_operand:HI 0 "register_operand" "=a")
17856         (unspec:HI
17857           [(match_operand:X87MODEF 1 "register_operand" "f")]
17858           UNSPEC_FXAM))]
17859   "TARGET_USE_FANCY_MATH_387"
17860   "fxam\n\tfnstsw\t%0"
17861   [(set_attr "type" "multi")
17862    (set_attr "unit" "i387")
17863    (set_attr "mode" "<MODE>")])
17864
17865 (define_expand "isinf<mode>2"
17866   [(use (match_operand:SI 0 "register_operand" ""))
17867    (use (match_operand:X87MODEF 1 "register_operand" ""))]
17868   "TARGET_USE_FANCY_MATH_387
17869   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17870       || TARGET_MIX_SSE_I387)"
17871 {
17872   rtx mask = GEN_INT (0x45);
17873   rtx val = GEN_INT (0x05);
17874
17875   rtx cond;
17876
17877   rtx scratch = gen_reg_rtx (HImode);
17878   rtx res = gen_reg_rtx (QImode);
17879
17880   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
17881   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
17882   emit_insn (gen_cmpqi_ext_3 (scratch, val));
17883   cond = gen_rtx_fmt_ee (EQ, QImode,
17884                          gen_rtx_REG (CCmode, FLAGS_REG),
17885                          const0_rtx);
17886   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
17887   emit_insn (gen_zero_extendqisi2 (operands[0], res));
17888   DONE;
17889 })
17890
17891 \f
17892 ;; Block operation instructions
17893
17894 (define_expand "movmemsi"
17895   [(use (match_operand:BLK 0 "memory_operand" ""))
17896    (use (match_operand:BLK 1 "memory_operand" ""))
17897    (use (match_operand:SI 2 "nonmemory_operand" ""))
17898    (use (match_operand:SI 3 "const_int_operand" ""))
17899    (use (match_operand:SI 4 "const_int_operand" ""))
17900    (use (match_operand:SI 5 "const_int_operand" ""))]
17901   ""
17902 {
17903  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17904                          operands[4], operands[5]))
17905    DONE;
17906  else
17907    FAIL;
17908 })
17909
17910 (define_expand "movmemdi"
17911   [(use (match_operand:BLK 0 "memory_operand" ""))
17912    (use (match_operand:BLK 1 "memory_operand" ""))
17913    (use (match_operand:DI 2 "nonmemory_operand" ""))
17914    (use (match_operand:DI 3 "const_int_operand" ""))
17915    (use (match_operand:SI 4 "const_int_operand" ""))
17916    (use (match_operand:SI 5 "const_int_operand" ""))]
17917   "TARGET_64BIT"
17918 {
17919  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17920                          operands[4], operands[5]))
17921    DONE;
17922  else
17923    FAIL;
17924 })
17925
17926 ;; Most CPUs don't like single string operations
17927 ;; Handle this case here to simplify previous expander.
17928
17929 (define_expand "strmov"
17930   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17931    (set (match_operand 1 "memory_operand" "") (match_dup 4))
17932    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17933               (clobber (reg:CC FLAGS_REG))])
17934    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17935               (clobber (reg:CC FLAGS_REG))])]
17936   ""
17937 {
17938   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17939
17940   /* If .md ever supports :P for Pmode, these can be directly
17941      in the pattern above.  */
17942   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17943   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17944
17945   if (TARGET_SINGLE_STRINGOP || optimize_size)
17946     {
17947       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17948                                       operands[2], operands[3],
17949                                       operands[5], operands[6]));
17950       DONE;
17951     }
17952
17953   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17954 })
17955
17956 (define_expand "strmov_singleop"
17957   [(parallel [(set (match_operand 1 "memory_operand" "")
17958                    (match_operand 3 "memory_operand" ""))
17959               (set (match_operand 0 "register_operand" "")
17960                    (match_operand 4 "" ""))
17961               (set (match_operand 2 "register_operand" "")
17962                    (match_operand 5 "" ""))])]
17963   "TARGET_SINGLE_STRINGOP || optimize_size"
17964   "")
17965
17966 (define_insn "*strmovdi_rex_1"
17967   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17968         (mem:DI (match_operand:DI 3 "register_operand" "1")))
17969    (set (match_operand:DI 0 "register_operand" "=D")
17970         (plus:DI (match_dup 2)
17971                  (const_int 8)))
17972    (set (match_operand:DI 1 "register_operand" "=S")
17973         (plus:DI (match_dup 3)
17974                  (const_int 8)))]
17975   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17976   "movsq"
17977   [(set_attr "type" "str")
17978    (set_attr "mode" "DI")
17979    (set_attr "memory" "both")])
17980
17981 (define_insn "*strmovsi_1"
17982   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17983         (mem:SI (match_operand:SI 3 "register_operand" "1")))
17984    (set (match_operand:SI 0 "register_operand" "=D")
17985         (plus:SI (match_dup 2)
17986                  (const_int 4)))
17987    (set (match_operand:SI 1 "register_operand" "=S")
17988         (plus:SI (match_dup 3)
17989                  (const_int 4)))]
17990   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17991   "{movsl|movsd}"
17992   [(set_attr "type" "str")
17993    (set_attr "mode" "SI")
17994    (set_attr "memory" "both")])
17995
17996 (define_insn "*strmovsi_rex_1"
17997   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17998         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17999    (set (match_operand:DI 0 "register_operand" "=D")
18000         (plus:DI (match_dup 2)
18001                  (const_int 4)))
18002    (set (match_operand:DI 1 "register_operand" "=S")
18003         (plus:DI (match_dup 3)
18004                  (const_int 4)))]
18005   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18006   "{movsl|movsd}"
18007   [(set_attr "type" "str")
18008    (set_attr "mode" "SI")
18009    (set_attr "memory" "both")])
18010
18011 (define_insn "*strmovhi_1"
18012   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18013         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18014    (set (match_operand:SI 0 "register_operand" "=D")
18015         (plus:SI (match_dup 2)
18016                  (const_int 2)))
18017    (set (match_operand:SI 1 "register_operand" "=S")
18018         (plus:SI (match_dup 3)
18019                  (const_int 2)))]
18020   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18021   "movsw"
18022   [(set_attr "type" "str")
18023    (set_attr "memory" "both")
18024    (set_attr "mode" "HI")])
18025
18026 (define_insn "*strmovhi_rex_1"
18027   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18028         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18029    (set (match_operand:DI 0 "register_operand" "=D")
18030         (plus:DI (match_dup 2)
18031                  (const_int 2)))
18032    (set (match_operand:DI 1 "register_operand" "=S")
18033         (plus:DI (match_dup 3)
18034                  (const_int 2)))]
18035   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18036   "movsw"
18037   [(set_attr "type" "str")
18038    (set_attr "memory" "both")
18039    (set_attr "mode" "HI")])
18040
18041 (define_insn "*strmovqi_1"
18042   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18043         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18044    (set (match_operand:SI 0 "register_operand" "=D")
18045         (plus:SI (match_dup 2)
18046                  (const_int 1)))
18047    (set (match_operand:SI 1 "register_operand" "=S")
18048         (plus:SI (match_dup 3)
18049                  (const_int 1)))]
18050   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18051   "movsb"
18052   [(set_attr "type" "str")
18053    (set_attr "memory" "both")
18054    (set_attr "mode" "QI")])
18055
18056 (define_insn "*strmovqi_rex_1"
18057   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18058         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18059    (set (match_operand:DI 0 "register_operand" "=D")
18060         (plus:DI (match_dup 2)
18061                  (const_int 1)))
18062    (set (match_operand:DI 1 "register_operand" "=S")
18063         (plus:DI (match_dup 3)
18064                  (const_int 1)))]
18065   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18066   "movsb"
18067   [(set_attr "type" "str")
18068    (set_attr "memory" "both")
18069    (set_attr "mode" "QI")])
18070
18071 (define_expand "rep_mov"
18072   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18073               (set (match_operand 0 "register_operand" "")
18074                    (match_operand 5 "" ""))
18075               (set (match_operand 2 "register_operand" "")
18076                    (match_operand 6 "" ""))
18077               (set (match_operand 1 "memory_operand" "")
18078                    (match_operand 3 "memory_operand" ""))
18079               (use (match_dup 4))])]
18080   ""
18081   "")
18082
18083 (define_insn "*rep_movdi_rex64"
18084   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18085    (set (match_operand:DI 0 "register_operand" "=D")
18086         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18087                             (const_int 3))
18088                  (match_operand:DI 3 "register_operand" "0")))
18089    (set (match_operand:DI 1 "register_operand" "=S")
18090         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18091                  (match_operand:DI 4 "register_operand" "1")))
18092    (set (mem:BLK (match_dup 3))
18093         (mem:BLK (match_dup 4)))
18094    (use (match_dup 5))]
18095   "TARGET_64BIT"
18096   "{rep\;movsq|rep movsq}"
18097   [(set_attr "type" "str")
18098    (set_attr "prefix_rep" "1")
18099    (set_attr "memory" "both")
18100    (set_attr "mode" "DI")])
18101
18102 (define_insn "*rep_movsi"
18103   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18104    (set (match_operand:SI 0 "register_operand" "=D")
18105         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18106                             (const_int 2))
18107                  (match_operand:SI 3 "register_operand" "0")))
18108    (set (match_operand:SI 1 "register_operand" "=S")
18109         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18110                  (match_operand:SI 4 "register_operand" "1")))
18111    (set (mem:BLK (match_dup 3))
18112         (mem:BLK (match_dup 4)))
18113    (use (match_dup 5))]
18114   "!TARGET_64BIT"
18115   "{rep\;movsl|rep movsd}"
18116   [(set_attr "type" "str")
18117    (set_attr "prefix_rep" "1")
18118    (set_attr "memory" "both")
18119    (set_attr "mode" "SI")])
18120
18121 (define_insn "*rep_movsi_rex64"
18122   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18123    (set (match_operand:DI 0 "register_operand" "=D")
18124         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18125                             (const_int 2))
18126                  (match_operand:DI 3 "register_operand" "0")))
18127    (set (match_operand:DI 1 "register_operand" "=S")
18128         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18129                  (match_operand:DI 4 "register_operand" "1")))
18130    (set (mem:BLK (match_dup 3))
18131         (mem:BLK (match_dup 4)))
18132    (use (match_dup 5))]
18133   "TARGET_64BIT"
18134   "{rep\;movsl|rep movsd}"
18135   [(set_attr "type" "str")
18136    (set_attr "prefix_rep" "1")
18137    (set_attr "memory" "both")
18138    (set_attr "mode" "SI")])
18139
18140 (define_insn "*rep_movqi"
18141   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18142    (set (match_operand:SI 0 "register_operand" "=D")
18143         (plus:SI (match_operand:SI 3 "register_operand" "0")
18144                  (match_operand:SI 5 "register_operand" "2")))
18145    (set (match_operand:SI 1 "register_operand" "=S")
18146         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18147    (set (mem:BLK (match_dup 3))
18148         (mem:BLK (match_dup 4)))
18149    (use (match_dup 5))]
18150   "!TARGET_64BIT"
18151   "{rep\;movsb|rep movsb}"
18152   [(set_attr "type" "str")
18153    (set_attr "prefix_rep" "1")
18154    (set_attr "memory" "both")
18155    (set_attr "mode" "SI")])
18156
18157 (define_insn "*rep_movqi_rex64"
18158   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18159    (set (match_operand:DI 0 "register_operand" "=D")
18160         (plus:DI (match_operand:DI 3 "register_operand" "0")
18161                  (match_operand:DI 5 "register_operand" "2")))
18162    (set (match_operand:DI 1 "register_operand" "=S")
18163         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18164    (set (mem:BLK (match_dup 3))
18165         (mem:BLK (match_dup 4)))
18166    (use (match_dup 5))]
18167   "TARGET_64BIT"
18168   "{rep\;movsb|rep movsb}"
18169   [(set_attr "type" "str")
18170    (set_attr "prefix_rep" "1")
18171    (set_attr "memory" "both")
18172    (set_attr "mode" "SI")])
18173
18174 (define_expand "setmemsi"
18175    [(use (match_operand:BLK 0 "memory_operand" ""))
18176     (use (match_operand:SI 1 "nonmemory_operand" ""))
18177     (use (match_operand 2 "const_int_operand" ""))
18178     (use (match_operand 3 "const_int_operand" ""))
18179     (use (match_operand:SI 4 "const_int_operand" ""))
18180     (use (match_operand:SI 5 "const_int_operand" ""))]
18181   ""
18182 {
18183  if (ix86_expand_setmem (operands[0], operands[1],
18184                          operands[2], operands[3],
18185                          operands[4], operands[5]))
18186    DONE;
18187  else
18188    FAIL;
18189 })
18190
18191 (define_expand "setmemdi"
18192    [(use (match_operand:BLK 0 "memory_operand" ""))
18193     (use (match_operand:DI 1 "nonmemory_operand" ""))
18194     (use (match_operand 2 "const_int_operand" ""))
18195     (use (match_operand 3 "const_int_operand" ""))
18196     (use (match_operand 4 "const_int_operand" ""))
18197     (use (match_operand 5 "const_int_operand" ""))]
18198   "TARGET_64BIT"
18199 {
18200  if (ix86_expand_setmem (operands[0], operands[1],
18201                          operands[2], operands[3],
18202                          operands[4], operands[5]))
18203    DONE;
18204  else
18205    FAIL;
18206 })
18207
18208 ;; Most CPUs don't like single string operations
18209 ;; Handle this case here to simplify previous expander.
18210
18211 (define_expand "strset"
18212   [(set (match_operand 1 "memory_operand" "")
18213         (match_operand 2 "register_operand" ""))
18214    (parallel [(set (match_operand 0 "register_operand" "")
18215                    (match_dup 3))
18216               (clobber (reg:CC FLAGS_REG))])]
18217   ""
18218 {
18219   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18220     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18221
18222   /* If .md ever supports :P for Pmode, this can be directly
18223      in the pattern above.  */
18224   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18225                               GEN_INT (GET_MODE_SIZE (GET_MODE
18226                                                       (operands[2]))));
18227   if (TARGET_SINGLE_STRINGOP || optimize_size)
18228     {
18229       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18230                                       operands[3]));
18231       DONE;
18232     }
18233 })
18234
18235 (define_expand "strset_singleop"
18236   [(parallel [(set (match_operand 1 "memory_operand" "")
18237                    (match_operand 2 "register_operand" ""))
18238               (set (match_operand 0 "register_operand" "")
18239                    (match_operand 3 "" ""))])]
18240   "TARGET_SINGLE_STRINGOP || optimize_size"
18241   "")
18242
18243 (define_insn "*strsetdi_rex_1"
18244   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18245         (match_operand:DI 2 "register_operand" "a"))
18246    (set (match_operand:DI 0 "register_operand" "=D")
18247         (plus:DI (match_dup 1)
18248                  (const_int 8)))]
18249   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18250   "stosq"
18251   [(set_attr "type" "str")
18252    (set_attr "memory" "store")
18253    (set_attr "mode" "DI")])
18254
18255 (define_insn "*strsetsi_1"
18256   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18257         (match_operand:SI 2 "register_operand" "a"))
18258    (set (match_operand:SI 0 "register_operand" "=D")
18259         (plus:SI (match_dup 1)
18260                  (const_int 4)))]
18261   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18262   "{stosl|stosd}"
18263   [(set_attr "type" "str")
18264    (set_attr "memory" "store")
18265    (set_attr "mode" "SI")])
18266
18267 (define_insn "*strsetsi_rex_1"
18268   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18269         (match_operand:SI 2 "register_operand" "a"))
18270    (set (match_operand:DI 0 "register_operand" "=D")
18271         (plus:DI (match_dup 1)
18272                  (const_int 4)))]
18273   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18274   "{stosl|stosd}"
18275   [(set_attr "type" "str")
18276    (set_attr "memory" "store")
18277    (set_attr "mode" "SI")])
18278
18279 (define_insn "*strsethi_1"
18280   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18281         (match_operand:HI 2 "register_operand" "a"))
18282    (set (match_operand:SI 0 "register_operand" "=D")
18283         (plus:SI (match_dup 1)
18284                  (const_int 2)))]
18285   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18286   "stosw"
18287   [(set_attr "type" "str")
18288    (set_attr "memory" "store")
18289    (set_attr "mode" "HI")])
18290
18291 (define_insn "*strsethi_rex_1"
18292   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18293         (match_operand:HI 2 "register_operand" "a"))
18294    (set (match_operand:DI 0 "register_operand" "=D")
18295         (plus:DI (match_dup 1)
18296                  (const_int 2)))]
18297   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18298   "stosw"
18299   [(set_attr "type" "str")
18300    (set_attr "memory" "store")
18301    (set_attr "mode" "HI")])
18302
18303 (define_insn "*strsetqi_1"
18304   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18305         (match_operand:QI 2 "register_operand" "a"))
18306    (set (match_operand:SI 0 "register_operand" "=D")
18307         (plus:SI (match_dup 1)
18308                  (const_int 1)))]
18309   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18310   "stosb"
18311   [(set_attr "type" "str")
18312    (set_attr "memory" "store")
18313    (set_attr "mode" "QI")])
18314
18315 (define_insn "*strsetqi_rex_1"
18316   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18317         (match_operand:QI 2 "register_operand" "a"))
18318    (set (match_operand:DI 0 "register_operand" "=D")
18319         (plus:DI (match_dup 1)
18320                  (const_int 1)))]
18321   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18322   "stosb"
18323   [(set_attr "type" "str")
18324    (set_attr "memory" "store")
18325    (set_attr "mode" "QI")])
18326
18327 (define_expand "rep_stos"
18328   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18329               (set (match_operand 0 "register_operand" "")
18330                    (match_operand 4 "" ""))
18331               (set (match_operand 2 "memory_operand" "") (const_int 0))
18332               (use (match_operand 3 "register_operand" ""))
18333               (use (match_dup 1))])]
18334   ""
18335   "")
18336
18337 (define_insn "*rep_stosdi_rex64"
18338   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18339    (set (match_operand:DI 0 "register_operand" "=D")
18340         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18341                             (const_int 3))
18342                  (match_operand:DI 3 "register_operand" "0")))
18343    (set (mem:BLK (match_dup 3))
18344         (const_int 0))
18345    (use (match_operand:DI 2 "register_operand" "a"))
18346    (use (match_dup 4))]
18347   "TARGET_64BIT"
18348   "{rep\;stosq|rep stosq}"
18349   [(set_attr "type" "str")
18350    (set_attr "prefix_rep" "1")
18351    (set_attr "memory" "store")
18352    (set_attr "mode" "DI")])
18353
18354 (define_insn "*rep_stossi"
18355   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18356    (set (match_operand:SI 0 "register_operand" "=D")
18357         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18358                             (const_int 2))
18359                  (match_operand:SI 3 "register_operand" "0")))
18360    (set (mem:BLK (match_dup 3))
18361         (const_int 0))
18362    (use (match_operand:SI 2 "register_operand" "a"))
18363    (use (match_dup 4))]
18364   "!TARGET_64BIT"
18365   "{rep\;stosl|rep stosd}"
18366   [(set_attr "type" "str")
18367    (set_attr "prefix_rep" "1")
18368    (set_attr "memory" "store")
18369    (set_attr "mode" "SI")])
18370
18371 (define_insn "*rep_stossi_rex64"
18372   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18373    (set (match_operand:DI 0 "register_operand" "=D")
18374         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18375                             (const_int 2))
18376                  (match_operand:DI 3 "register_operand" "0")))
18377    (set (mem:BLK (match_dup 3))
18378         (const_int 0))
18379    (use (match_operand:SI 2 "register_operand" "a"))
18380    (use (match_dup 4))]
18381   "TARGET_64BIT"
18382   "{rep\;stosl|rep stosd}"
18383   [(set_attr "type" "str")
18384    (set_attr "prefix_rep" "1")
18385    (set_attr "memory" "store")
18386    (set_attr "mode" "SI")])
18387
18388 (define_insn "*rep_stosqi"
18389   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18390    (set (match_operand:SI 0 "register_operand" "=D")
18391         (plus:SI (match_operand:SI 3 "register_operand" "0")
18392                  (match_operand:SI 4 "register_operand" "1")))
18393    (set (mem:BLK (match_dup 3))
18394         (const_int 0))
18395    (use (match_operand:QI 2 "register_operand" "a"))
18396    (use (match_dup 4))]
18397   "!TARGET_64BIT"
18398   "{rep\;stosb|rep stosb}"
18399   [(set_attr "type" "str")
18400    (set_attr "prefix_rep" "1")
18401    (set_attr "memory" "store")
18402    (set_attr "mode" "QI")])
18403
18404 (define_insn "*rep_stosqi_rex64"
18405   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18406    (set (match_operand:DI 0 "register_operand" "=D")
18407         (plus:DI (match_operand:DI 3 "register_operand" "0")
18408                  (match_operand:DI 4 "register_operand" "1")))
18409    (set (mem:BLK (match_dup 3))
18410         (const_int 0))
18411    (use (match_operand:QI 2 "register_operand" "a"))
18412    (use (match_dup 4))]
18413   "TARGET_64BIT"
18414   "{rep\;stosb|rep stosb}"
18415   [(set_attr "type" "str")
18416    (set_attr "prefix_rep" "1")
18417    (set_attr "memory" "store")
18418    (set_attr "mode" "QI")])
18419
18420 (define_expand "cmpstrnsi"
18421   [(set (match_operand:SI 0 "register_operand" "")
18422         (compare:SI (match_operand:BLK 1 "general_operand" "")
18423                     (match_operand:BLK 2 "general_operand" "")))
18424    (use (match_operand 3 "general_operand" ""))
18425    (use (match_operand 4 "immediate_operand" ""))]
18426   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18427 {
18428   rtx addr1, addr2, out, outlow, count, countreg, align;
18429
18430   /* Can't use this if the user has appropriated esi or edi.  */
18431   if (global_regs[4] || global_regs[5])
18432     FAIL;
18433
18434   out = operands[0];
18435   if (!REG_P (out))
18436     out = gen_reg_rtx (SImode);
18437
18438   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18439   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18440   if (addr1 != XEXP (operands[1], 0))
18441     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18442   if (addr2 != XEXP (operands[2], 0))
18443     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18444
18445   count = operands[3];
18446   countreg = ix86_zero_extend_to_Pmode (count);
18447
18448   /* %%% Iff we are testing strict equality, we can use known alignment
18449      to good advantage.  This may be possible with combine, particularly
18450      once cc0 is dead.  */
18451   align = operands[4];
18452
18453   if (CONST_INT_P (count))
18454     {
18455       if (INTVAL (count) == 0)
18456         {
18457           emit_move_insn (operands[0], const0_rtx);
18458           DONE;
18459         }
18460       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18461                                      operands[1], operands[2]));
18462     }
18463   else
18464     {
18465       if (TARGET_64BIT)
18466         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18467       else
18468         emit_insn (gen_cmpsi_1 (countreg, countreg));
18469       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18470                                   operands[1], operands[2]));
18471     }
18472
18473   outlow = gen_lowpart (QImode, out);
18474   emit_insn (gen_cmpintqi (outlow));
18475   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18476
18477   if (operands[0] != out)
18478     emit_move_insn (operands[0], out);
18479
18480   DONE;
18481 })
18482
18483 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18484
18485 (define_expand "cmpintqi"
18486   [(set (match_dup 1)
18487         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18488    (set (match_dup 2)
18489         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18490    (parallel [(set (match_operand:QI 0 "register_operand" "")
18491                    (minus:QI (match_dup 1)
18492                              (match_dup 2)))
18493               (clobber (reg:CC FLAGS_REG))])]
18494   ""
18495   "operands[1] = gen_reg_rtx (QImode);
18496    operands[2] = gen_reg_rtx (QImode);")
18497
18498 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18499 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18500
18501 (define_expand "cmpstrnqi_nz_1"
18502   [(parallel [(set (reg:CC FLAGS_REG)
18503                    (compare:CC (match_operand 4 "memory_operand" "")
18504                                (match_operand 5 "memory_operand" "")))
18505               (use (match_operand 2 "register_operand" ""))
18506               (use (match_operand:SI 3 "immediate_operand" ""))
18507               (clobber (match_operand 0 "register_operand" ""))
18508               (clobber (match_operand 1 "register_operand" ""))
18509               (clobber (match_dup 2))])]
18510   ""
18511   "")
18512
18513 (define_insn "*cmpstrnqi_nz_1"
18514   [(set (reg:CC FLAGS_REG)
18515         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18516                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18517    (use (match_operand:SI 6 "register_operand" "2"))
18518    (use (match_operand:SI 3 "immediate_operand" "i"))
18519    (clobber (match_operand:SI 0 "register_operand" "=S"))
18520    (clobber (match_operand:SI 1 "register_operand" "=D"))
18521    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18522   "!TARGET_64BIT"
18523   "repz{\;| }cmpsb"
18524   [(set_attr "type" "str")
18525    (set_attr "mode" "QI")
18526    (set_attr "prefix_rep" "1")])
18527
18528 (define_insn "*cmpstrnqi_nz_rex_1"
18529   [(set (reg:CC FLAGS_REG)
18530         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18531                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18532    (use (match_operand:DI 6 "register_operand" "2"))
18533    (use (match_operand:SI 3 "immediate_operand" "i"))
18534    (clobber (match_operand:DI 0 "register_operand" "=S"))
18535    (clobber (match_operand:DI 1 "register_operand" "=D"))
18536    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18537   "TARGET_64BIT"
18538   "repz{\;| }cmpsb"
18539   [(set_attr "type" "str")
18540    (set_attr "mode" "QI")
18541    (set_attr "prefix_rep" "1")])
18542
18543 ;; The same, but the count is not known to not be zero.
18544
18545 (define_expand "cmpstrnqi_1"
18546   [(parallel [(set (reg:CC FLAGS_REG)
18547                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18548                                      (const_int 0))
18549                   (compare:CC (match_operand 4 "memory_operand" "")
18550                               (match_operand 5 "memory_operand" ""))
18551                   (const_int 0)))
18552               (use (match_operand:SI 3 "immediate_operand" ""))
18553               (use (reg:CC FLAGS_REG))
18554               (clobber (match_operand 0 "register_operand" ""))
18555               (clobber (match_operand 1 "register_operand" ""))
18556               (clobber (match_dup 2))])]
18557   ""
18558   "")
18559
18560 (define_insn "*cmpstrnqi_1"
18561   [(set (reg:CC FLAGS_REG)
18562         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18563                              (const_int 0))
18564           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18565                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18566           (const_int 0)))
18567    (use (match_operand:SI 3 "immediate_operand" "i"))
18568    (use (reg:CC FLAGS_REG))
18569    (clobber (match_operand:SI 0 "register_operand" "=S"))
18570    (clobber (match_operand:SI 1 "register_operand" "=D"))
18571    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18572   "!TARGET_64BIT"
18573   "repz{\;| }cmpsb"
18574   [(set_attr "type" "str")
18575    (set_attr "mode" "QI")
18576    (set_attr "prefix_rep" "1")])
18577
18578 (define_insn "*cmpstrnqi_rex_1"
18579   [(set (reg:CC FLAGS_REG)
18580         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18581                              (const_int 0))
18582           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18583                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18584           (const_int 0)))
18585    (use (match_operand:SI 3 "immediate_operand" "i"))
18586    (use (reg:CC FLAGS_REG))
18587    (clobber (match_operand:DI 0 "register_operand" "=S"))
18588    (clobber (match_operand:DI 1 "register_operand" "=D"))
18589    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18590   "TARGET_64BIT"
18591   "repz{\;| }cmpsb"
18592   [(set_attr "type" "str")
18593    (set_attr "mode" "QI")
18594    (set_attr "prefix_rep" "1")])
18595
18596 (define_expand "strlensi"
18597   [(set (match_operand:SI 0 "register_operand" "")
18598         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18599                     (match_operand:QI 2 "immediate_operand" "")
18600                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18601   ""
18602 {
18603  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18604    DONE;
18605  else
18606    FAIL;
18607 })
18608
18609 (define_expand "strlendi"
18610   [(set (match_operand:DI 0 "register_operand" "")
18611         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18612                     (match_operand:QI 2 "immediate_operand" "")
18613                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18614   ""
18615 {
18616  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18617    DONE;
18618  else
18619    FAIL;
18620 })
18621
18622 (define_expand "strlenqi_1"
18623   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18624               (clobber (match_operand 1 "register_operand" ""))
18625               (clobber (reg:CC FLAGS_REG))])]
18626   ""
18627   "")
18628
18629 (define_insn "*strlenqi_1"
18630   [(set (match_operand:SI 0 "register_operand" "=&c")
18631         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18632                     (match_operand:QI 2 "register_operand" "a")
18633                     (match_operand:SI 3 "immediate_operand" "i")
18634                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18635    (clobber (match_operand:SI 1 "register_operand" "=D"))
18636    (clobber (reg:CC FLAGS_REG))]
18637   "!TARGET_64BIT"
18638   "repnz{\;| }scasb"
18639   [(set_attr "type" "str")
18640    (set_attr "mode" "QI")
18641    (set_attr "prefix_rep" "1")])
18642
18643 (define_insn "*strlenqi_rex_1"
18644   [(set (match_operand:DI 0 "register_operand" "=&c")
18645         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18646                     (match_operand:QI 2 "register_operand" "a")
18647                     (match_operand:DI 3 "immediate_operand" "i")
18648                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18649    (clobber (match_operand:DI 1 "register_operand" "=D"))
18650    (clobber (reg:CC FLAGS_REG))]
18651   "TARGET_64BIT"
18652   "repnz{\;| }scasb"
18653   [(set_attr "type" "str")
18654    (set_attr "mode" "QI")
18655    (set_attr "prefix_rep" "1")])
18656
18657 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18658 ;; handled in combine, but it is not currently up to the task.
18659 ;; When used for their truth value, the cmpstrn* expanders generate
18660 ;; code like this:
18661 ;;
18662 ;;   repz cmpsb
18663 ;;   seta       %al
18664 ;;   setb       %dl
18665 ;;   cmpb       %al, %dl
18666 ;;   jcc        label
18667 ;;
18668 ;; The intermediate three instructions are unnecessary.
18669
18670 ;; This one handles cmpstrn*_nz_1...
18671 (define_peephole2
18672   [(parallel[
18673      (set (reg:CC FLAGS_REG)
18674           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18675                       (mem:BLK (match_operand 5 "register_operand" ""))))
18676      (use (match_operand 6 "register_operand" ""))
18677      (use (match_operand:SI 3 "immediate_operand" ""))
18678      (clobber (match_operand 0 "register_operand" ""))
18679      (clobber (match_operand 1 "register_operand" ""))
18680      (clobber (match_operand 2 "register_operand" ""))])
18681    (set (match_operand:QI 7 "register_operand" "")
18682         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18683    (set (match_operand:QI 8 "register_operand" "")
18684         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18685    (set (reg FLAGS_REG)
18686         (compare (match_dup 7) (match_dup 8)))
18687   ]
18688   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18689   [(parallel[
18690      (set (reg:CC FLAGS_REG)
18691           (compare:CC (mem:BLK (match_dup 4))
18692                       (mem:BLK (match_dup 5))))
18693      (use (match_dup 6))
18694      (use (match_dup 3))
18695      (clobber (match_dup 0))
18696      (clobber (match_dup 1))
18697      (clobber (match_dup 2))])]
18698   "")
18699
18700 ;; ...and this one handles cmpstrn*_1.
18701 (define_peephole2
18702   [(parallel[
18703      (set (reg:CC FLAGS_REG)
18704           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18705                                (const_int 0))
18706             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18707                         (mem:BLK (match_operand 5 "register_operand" "")))
18708             (const_int 0)))
18709      (use (match_operand:SI 3 "immediate_operand" ""))
18710      (use (reg:CC FLAGS_REG))
18711      (clobber (match_operand 0 "register_operand" ""))
18712      (clobber (match_operand 1 "register_operand" ""))
18713      (clobber (match_operand 2 "register_operand" ""))])
18714    (set (match_operand:QI 7 "register_operand" "")
18715         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18716    (set (match_operand:QI 8 "register_operand" "")
18717         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18718    (set (reg FLAGS_REG)
18719         (compare (match_dup 7) (match_dup 8)))
18720   ]
18721   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18722   [(parallel[
18723      (set (reg:CC FLAGS_REG)
18724           (if_then_else:CC (ne (match_dup 6)
18725                                (const_int 0))
18726             (compare:CC (mem:BLK (match_dup 4))
18727                         (mem:BLK (match_dup 5)))
18728             (const_int 0)))
18729      (use (match_dup 3))
18730      (use (reg:CC FLAGS_REG))
18731      (clobber (match_dup 0))
18732      (clobber (match_dup 1))
18733      (clobber (match_dup 2))])]
18734   "")
18735
18736
18737 \f
18738 ;; Conditional move instructions.
18739
18740 (define_expand "movdicc"
18741   [(set (match_operand:DI 0 "register_operand" "")
18742         (if_then_else:DI (match_operand 1 "comparison_operator" "")
18743                          (match_operand:DI 2 "general_operand" "")
18744                          (match_operand:DI 3 "general_operand" "")))]
18745   "TARGET_64BIT"
18746   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18747
18748 (define_insn "x86_movdicc_0_m1_rex64"
18749   [(set (match_operand:DI 0 "register_operand" "=r")
18750         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18751           (const_int -1)
18752           (const_int 0)))
18753    (clobber (reg:CC FLAGS_REG))]
18754   "TARGET_64BIT"
18755   "sbb{q}\t%0, %0"
18756   ; Since we don't have the proper number of operands for an alu insn,
18757   ; fill in all the blanks.
18758   [(set_attr "type" "alu")
18759    (set_attr "pent_pair" "pu")
18760    (set_attr "memory" "none")
18761    (set_attr "imm_disp" "false")
18762    (set_attr "mode" "DI")
18763    (set_attr "length_immediate" "0")])
18764
18765 (define_insn "*movdicc_c_rex64"
18766   [(set (match_operand:DI 0 "register_operand" "=r,r")
18767         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18768                                 [(reg FLAGS_REG) (const_int 0)])
18769                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18770                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18771   "TARGET_64BIT && TARGET_CMOVE
18772    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18773   "@
18774    cmov%O2%C1\t{%2, %0|%0, %2}
18775    cmov%O2%c1\t{%3, %0|%0, %3}"
18776   [(set_attr "type" "icmov")
18777    (set_attr "mode" "DI")])
18778
18779 (define_expand "movsicc"
18780   [(set (match_operand:SI 0 "register_operand" "")
18781         (if_then_else:SI (match_operand 1 "comparison_operator" "")
18782                          (match_operand:SI 2 "general_operand" "")
18783                          (match_operand:SI 3 "general_operand" "")))]
18784   ""
18785   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18786
18787 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18788 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18789 ;; So just document what we're doing explicitly.
18790
18791 (define_insn "x86_movsicc_0_m1"
18792   [(set (match_operand:SI 0 "register_operand" "=r")
18793         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18794           (const_int -1)
18795           (const_int 0)))
18796    (clobber (reg:CC FLAGS_REG))]
18797   ""
18798   "sbb{l}\t%0, %0"
18799   ; Since we don't have the proper number of operands for an alu insn,
18800   ; fill in all the blanks.
18801   [(set_attr "type" "alu")
18802    (set_attr "pent_pair" "pu")
18803    (set_attr "memory" "none")
18804    (set_attr "imm_disp" "false")
18805    (set_attr "mode" "SI")
18806    (set_attr "length_immediate" "0")])
18807
18808 (define_insn "*movsicc_noc"
18809   [(set (match_operand:SI 0 "register_operand" "=r,r")
18810         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18811                                 [(reg FLAGS_REG) (const_int 0)])
18812                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18813                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18814   "TARGET_CMOVE
18815    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18816   "@
18817    cmov%O2%C1\t{%2, %0|%0, %2}
18818    cmov%O2%c1\t{%3, %0|%0, %3}"
18819   [(set_attr "type" "icmov")
18820    (set_attr "mode" "SI")])
18821
18822 (define_expand "movhicc"
18823   [(set (match_operand:HI 0 "register_operand" "")
18824         (if_then_else:HI (match_operand 1 "comparison_operator" "")
18825                          (match_operand:HI 2 "general_operand" "")
18826                          (match_operand:HI 3 "general_operand" "")))]
18827   "TARGET_HIMODE_MATH"
18828   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18829
18830 (define_insn "*movhicc_noc"
18831   [(set (match_operand:HI 0 "register_operand" "=r,r")
18832         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18833                                 [(reg FLAGS_REG) (const_int 0)])
18834                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18835                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18836   "TARGET_CMOVE
18837    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18838   "@
18839    cmov%O2%C1\t{%2, %0|%0, %2}
18840    cmov%O2%c1\t{%3, %0|%0, %3}"
18841   [(set_attr "type" "icmov")
18842    (set_attr "mode" "HI")])
18843
18844 (define_expand "movqicc"
18845   [(set (match_operand:QI 0 "register_operand" "")
18846         (if_then_else:QI (match_operand 1 "comparison_operator" "")
18847                          (match_operand:QI 2 "general_operand" "")
18848                          (match_operand:QI 3 "general_operand" "")))]
18849   "TARGET_QIMODE_MATH"
18850   "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18851
18852 (define_insn_and_split "*movqicc_noc"
18853   [(set (match_operand:QI 0 "register_operand" "=r,r")
18854         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18855                                 [(match_operand 4 "flags_reg_operand" "")
18856                                  (const_int 0)])
18857                       (match_operand:QI 2 "register_operand" "r,0")
18858                       (match_operand:QI 3 "register_operand" "0,r")))]
18859   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18860   "#"
18861   "&& reload_completed"
18862   [(set (match_dup 0)
18863         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18864                       (match_dup 2)
18865                       (match_dup 3)))]
18866   "operands[0] = gen_lowpart (SImode, operands[0]);
18867    operands[2] = gen_lowpart (SImode, operands[2]);
18868    operands[3] = gen_lowpart (SImode, operands[3]);"
18869   [(set_attr "type" "icmov")
18870    (set_attr "mode" "SI")])
18871
18872 (define_expand "movsfcc"
18873   [(set (match_operand:SF 0 "register_operand" "")
18874         (if_then_else:SF (match_operand 1 "comparison_operator" "")
18875                          (match_operand:SF 2 "register_operand" "")
18876                          (match_operand:SF 3 "register_operand" "")))]
18877   "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18878   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18879
18880 (define_insn "*movsfcc_1_387"
18881   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18882         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18883                                 [(reg FLAGS_REG) (const_int 0)])
18884                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18885                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18886   "TARGET_80387 && TARGET_CMOVE
18887    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18888   "@
18889    fcmov%F1\t{%2, %0|%0, %2}
18890    fcmov%f1\t{%3, %0|%0, %3}
18891    cmov%O2%C1\t{%2, %0|%0, %2}
18892    cmov%O2%c1\t{%3, %0|%0, %3}"
18893   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18894    (set_attr "mode" "SF,SF,SI,SI")])
18895
18896 (define_expand "movdfcc"
18897   [(set (match_operand:DF 0 "register_operand" "")
18898         (if_then_else:DF (match_operand 1 "comparison_operator" "")
18899                          (match_operand:DF 2 "register_operand" "")
18900                          (match_operand:DF 3 "register_operand" "")))]
18901   "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18902   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18903
18904 (define_insn "*movdfcc_1"
18905   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
18906         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18907                                 [(reg FLAGS_REG) (const_int 0)])
18908                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18909                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18910   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18911    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18912   "@
18913    fcmov%F1\t{%2, %0|%0, %2}
18914    fcmov%f1\t{%3, %0|%0, %3}
18915    #
18916    #"
18917   [(set_attr "type" "fcmov,fcmov,multi,multi")
18918    (set_attr "mode" "DF")])
18919
18920 (define_insn "*movdfcc_1_rex64"
18921   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
18922         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18923                                 [(reg FLAGS_REG) (const_int 0)])
18924                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18925                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18926   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18927    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18928   "@
18929    fcmov%F1\t{%2, %0|%0, %2}
18930    fcmov%f1\t{%3, %0|%0, %3}
18931    cmov%O2%C1\t{%2, %0|%0, %2}
18932    cmov%O2%c1\t{%3, %0|%0, %3}"
18933   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18934    (set_attr "mode" "DF")])
18935
18936 (define_split
18937   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18938         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18939                                 [(match_operand 4 "flags_reg_operand" "")
18940                                  (const_int 0)])
18941                       (match_operand:DF 2 "nonimmediate_operand" "")
18942                       (match_operand:DF 3 "nonimmediate_operand" "")))]
18943   "!TARGET_64BIT && reload_completed"
18944   [(set (match_dup 2)
18945         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18946                       (match_dup 5)
18947                       (match_dup 7)))
18948    (set (match_dup 3)
18949         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18950                       (match_dup 6)
18951                       (match_dup 8)))]
18952   "split_di (operands+2, 1, operands+5, operands+6);
18953    split_di (operands+3, 1, operands+7, operands+8);
18954    split_di (operands, 1, operands+2, operands+3);")
18955
18956 (define_expand "movxfcc"
18957   [(set (match_operand:XF 0 "register_operand" "")
18958         (if_then_else:XF (match_operand 1 "comparison_operator" "")
18959                          (match_operand:XF 2 "register_operand" "")
18960                          (match_operand:XF 3 "register_operand" "")))]
18961   "TARGET_80387 && TARGET_CMOVE"
18962   "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18963
18964 (define_insn "*movxfcc_1"
18965   [(set (match_operand:XF 0 "register_operand" "=f,f")
18966         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18967                                 [(reg FLAGS_REG) (const_int 0)])
18968                       (match_operand:XF 2 "register_operand" "f,0")
18969                       (match_operand:XF 3 "register_operand" "0,f")))]
18970   "TARGET_80387 && TARGET_CMOVE"
18971   "@
18972    fcmov%F1\t{%2, %0|%0, %2}
18973    fcmov%f1\t{%3, %0|%0, %3}"
18974   [(set_attr "type" "fcmov")
18975    (set_attr "mode" "XF")])
18976
18977 ;; These versions of the min/max patterns are intentionally ignorant of
18978 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18979 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18980 ;; are undefined in this condition, we're certain this is correct.
18981
18982 (define_insn "sminsf3"
18983   [(set (match_operand:SF 0 "register_operand" "=x")
18984         (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18985                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18986   "TARGET_SSE_MATH"
18987   "minss\t{%2, %0|%0, %2}"
18988   [(set_attr "type" "sseadd")
18989    (set_attr "mode" "SF")])
18990
18991 (define_insn "smaxsf3"
18992   [(set (match_operand:SF 0 "register_operand" "=x")
18993         (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18994                  (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18995   "TARGET_SSE_MATH"
18996   "maxss\t{%2, %0|%0, %2}"
18997   [(set_attr "type" "sseadd")
18998    (set_attr "mode" "SF")])
18999
19000 (define_insn "smindf3"
19001   [(set (match_operand:DF 0 "register_operand" "=x")
19002         (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19003                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19004   "TARGET_SSE2 && TARGET_SSE_MATH"
19005   "minsd\t{%2, %0|%0, %2}"
19006   [(set_attr "type" "sseadd")
19007    (set_attr "mode" "DF")])
19008
19009 (define_insn "smaxdf3"
19010   [(set (match_operand:DF 0 "register_operand" "=x")
19011         (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19012                  (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19013   "TARGET_SSE2 && TARGET_SSE_MATH"
19014   "maxsd\t{%2, %0|%0, %2}"
19015   [(set_attr "type" "sseadd")
19016    (set_attr "mode" "DF")])
19017
19018 ;; These versions of the min/max patterns implement exactly the operations
19019 ;;   min = (op1 < op2 ? op1 : op2)
19020 ;;   max = (!(op1 < op2) ? op1 : op2)
19021 ;; Their operands are not commutative, and thus they may be used in the
19022 ;; presence of -0.0 and NaN.
19023
19024 (define_insn "*ieee_sminsf3"
19025   [(set (match_operand:SF 0 "register_operand" "=x")
19026         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19027                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19028                    UNSPEC_IEEE_MIN))]
19029   "TARGET_SSE_MATH"
19030   "minss\t{%2, %0|%0, %2}"
19031   [(set_attr "type" "sseadd")
19032    (set_attr "mode" "SF")])
19033
19034 (define_insn "*ieee_smaxsf3"
19035   [(set (match_operand:SF 0 "register_operand" "=x")
19036         (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19037                     (match_operand:SF 2 "nonimmediate_operand" "xm")]
19038                    UNSPEC_IEEE_MAX))]
19039   "TARGET_SSE_MATH"
19040   "maxss\t{%2, %0|%0, %2}"
19041   [(set_attr "type" "sseadd")
19042    (set_attr "mode" "SF")])
19043
19044 (define_insn "*ieee_smindf3"
19045   [(set (match_operand:DF 0 "register_operand" "=x")
19046         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19047                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19048                    UNSPEC_IEEE_MIN))]
19049   "TARGET_SSE2 && TARGET_SSE_MATH"
19050   "minsd\t{%2, %0|%0, %2}"
19051   [(set_attr "type" "sseadd")
19052    (set_attr "mode" "DF")])
19053
19054 (define_insn "*ieee_smaxdf3"
19055   [(set (match_operand:DF 0 "register_operand" "=x")
19056         (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19057                     (match_operand:DF 2 "nonimmediate_operand" "xm")]
19058                    UNSPEC_IEEE_MAX))]
19059   "TARGET_SSE2 && TARGET_SSE_MATH"
19060   "maxsd\t{%2, %0|%0, %2}"
19061   [(set_attr "type" "sseadd")
19062    (set_attr "mode" "DF")])
19063
19064 ;; Make two stack loads independent:
19065 ;;   fld aa              fld aa
19066 ;;   fld %st(0)     ->   fld bb
19067 ;;   fmul bb             fmul %st(1), %st
19068 ;;
19069 ;; Actually we only match the last two instructions for simplicity.
19070 (define_peephole2
19071   [(set (match_operand 0 "fp_register_operand" "")
19072         (match_operand 1 "fp_register_operand" ""))
19073    (set (match_dup 0)
19074         (match_operator 2 "binary_fp_operator"
19075            [(match_dup 0)
19076             (match_operand 3 "memory_operand" "")]))]
19077   "REGNO (operands[0]) != REGNO (operands[1])"
19078   [(set (match_dup 0) (match_dup 3))
19079    (set (match_dup 0) (match_dup 4))]
19080
19081   ;; The % modifier is not operational anymore in peephole2's, so we have to
19082   ;; swap the operands manually in the case of addition and multiplication.
19083   "if (COMMUTATIVE_ARITH_P (operands[2]))
19084      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19085                                  operands[0], operands[1]);
19086    else
19087      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19088                                  operands[1], operands[0]);")
19089
19090 ;; Conditional addition patterns
19091 (define_expand "addqicc"
19092   [(match_operand:QI 0 "register_operand" "")
19093    (match_operand 1 "comparison_operator" "")
19094    (match_operand:QI 2 "register_operand" "")
19095    (match_operand:QI 3 "const_int_operand" "")]
19096   ""
19097   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19098
19099 (define_expand "addhicc"
19100   [(match_operand:HI 0 "register_operand" "")
19101    (match_operand 1 "comparison_operator" "")
19102    (match_operand:HI 2 "register_operand" "")
19103    (match_operand:HI 3 "const_int_operand" "")]
19104   ""
19105   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19106
19107 (define_expand "addsicc"
19108   [(match_operand:SI 0 "register_operand" "")
19109    (match_operand 1 "comparison_operator" "")
19110    (match_operand:SI 2 "register_operand" "")
19111    (match_operand:SI 3 "const_int_operand" "")]
19112   ""
19113   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19114
19115 (define_expand "adddicc"
19116   [(match_operand:DI 0 "register_operand" "")
19117    (match_operand 1 "comparison_operator" "")
19118    (match_operand:DI 2 "register_operand" "")
19119    (match_operand:DI 3 "const_int_operand" "")]
19120   "TARGET_64BIT"
19121   "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19122
19123 \f
19124 ;; Misc patterns (?)
19125
19126 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19127 ;; Otherwise there will be nothing to keep
19128 ;;
19129 ;; [(set (reg ebp) (reg esp))]
19130 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19131 ;;  (clobber (eflags)]
19132 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19133 ;;
19134 ;; in proper program order.
19135 (define_insn "pro_epilogue_adjust_stack_1"
19136   [(set (match_operand:SI 0 "register_operand" "=r,r")
19137         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19138                  (match_operand:SI 2 "immediate_operand" "i,i")))
19139    (clobber (reg:CC FLAGS_REG))
19140    (clobber (mem:BLK (scratch)))]
19141   "!TARGET_64BIT"
19142 {
19143   switch (get_attr_type (insn))
19144     {
19145     case TYPE_IMOV:
19146       return "mov{l}\t{%1, %0|%0, %1}";
19147
19148     case TYPE_ALU:
19149       if (CONST_INT_P (operands[2])
19150           && (INTVAL (operands[2]) == 128
19151               || (INTVAL (operands[2]) < 0
19152                   && INTVAL (operands[2]) != -128)))
19153         {
19154           operands[2] = GEN_INT (-INTVAL (operands[2]));
19155           return "sub{l}\t{%2, %0|%0, %2}";
19156         }
19157       return "add{l}\t{%2, %0|%0, %2}";
19158
19159     case TYPE_LEA:
19160       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19161       return "lea{l}\t{%a2, %0|%0, %a2}";
19162
19163     default:
19164       gcc_unreachable ();
19165     }
19166 }
19167   [(set (attr "type")
19168         (cond [(eq_attr "alternative" "0")
19169                  (const_string "alu")
19170                (match_operand:SI 2 "const0_operand" "")
19171                  (const_string "imov")
19172               ]
19173               (const_string "lea")))
19174    (set_attr "mode" "SI")])
19175
19176 (define_insn "pro_epilogue_adjust_stack_rex64"
19177   [(set (match_operand:DI 0 "register_operand" "=r,r")
19178         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19179                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19180    (clobber (reg:CC FLAGS_REG))
19181    (clobber (mem:BLK (scratch)))]
19182   "TARGET_64BIT"
19183 {
19184   switch (get_attr_type (insn))
19185     {
19186     case TYPE_IMOV:
19187       return "mov{q}\t{%1, %0|%0, %1}";
19188
19189     case TYPE_ALU:
19190       if (CONST_INT_P (operands[2])
19191           /* Avoid overflows.  */
19192           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19193           && (INTVAL (operands[2]) == 128
19194               || (INTVAL (operands[2]) < 0
19195                   && INTVAL (operands[2]) != -128)))
19196         {
19197           operands[2] = GEN_INT (-INTVAL (operands[2]));
19198           return "sub{q}\t{%2, %0|%0, %2}";
19199         }
19200       return "add{q}\t{%2, %0|%0, %2}";
19201
19202     case TYPE_LEA:
19203       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19204       return "lea{q}\t{%a2, %0|%0, %a2}";
19205
19206     default:
19207       gcc_unreachable ();
19208     }
19209 }
19210   [(set (attr "type")
19211         (cond [(eq_attr "alternative" "0")
19212                  (const_string "alu")
19213                (match_operand:DI 2 "const0_operand" "")
19214                  (const_string "imov")
19215               ]
19216               (const_string "lea")))
19217    (set_attr "mode" "DI")])
19218
19219 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19220   [(set (match_operand:DI 0 "register_operand" "=r,r")
19221         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19222                  (match_operand:DI 3 "immediate_operand" "i,i")))
19223    (use (match_operand:DI 2 "register_operand" "r,r"))
19224    (clobber (reg:CC FLAGS_REG))
19225    (clobber (mem:BLK (scratch)))]
19226   "TARGET_64BIT"
19227 {
19228   switch (get_attr_type (insn))
19229     {
19230     case TYPE_ALU:
19231       return "add{q}\t{%2, %0|%0, %2}";
19232
19233     case TYPE_LEA:
19234       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19235       return "lea{q}\t{%a2, %0|%0, %a2}";
19236
19237     default:
19238       gcc_unreachable ();
19239     }
19240 }
19241   [(set_attr "type" "alu,lea")
19242    (set_attr "mode" "DI")])
19243
19244 (define_expand "allocate_stack_worker"
19245   [(match_operand:SI 0 "register_operand" "")]
19246   "TARGET_STACK_PROBE"
19247 {
19248   if (reload_completed)
19249     {
19250       if (TARGET_64BIT)
19251         emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19252       else
19253         emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19254     }
19255   else
19256     {
19257       if (TARGET_64BIT)
19258         emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19259       else
19260         emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19261     }
19262   DONE;
19263 })
19264
19265 (define_insn "allocate_stack_worker_1"
19266   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19267     UNSPECV_STACK_PROBE)
19268    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19269    (clobber (match_scratch:SI 1 "=0"))
19270    (clobber (reg:CC FLAGS_REG))]
19271   "!TARGET_64BIT && TARGET_STACK_PROBE"
19272   "call\t__alloca"
19273   [(set_attr "type" "multi")
19274    (set_attr "length" "5")])
19275
19276 (define_expand "allocate_stack_worker_postreload"
19277   [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19278                                     UNSPECV_STACK_PROBE)
19279               (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19280               (clobber (match_dup 0))
19281               (clobber (reg:CC FLAGS_REG))])]
19282   ""
19283   "")
19284
19285 (define_insn "allocate_stack_worker_rex64"
19286   [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19287     UNSPECV_STACK_PROBE)
19288    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19289    (clobber (match_scratch:DI 1 "=0"))
19290    (clobber (reg:CC FLAGS_REG))]
19291   "TARGET_64BIT && TARGET_STACK_PROBE"
19292   "call\t__alloca"
19293   [(set_attr "type" "multi")
19294    (set_attr "length" "5")])
19295
19296 (define_expand "allocate_stack_worker_rex64_postreload"
19297   [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19298                                     UNSPECV_STACK_PROBE)
19299               (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19300               (clobber (match_dup 0))
19301               (clobber (reg:CC FLAGS_REG))])]
19302   ""
19303   "")
19304
19305 (define_expand "allocate_stack"
19306   [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19307                    (minus:SI (reg:SI SP_REG)
19308                              (match_operand:SI 1 "general_operand" "")))
19309               (clobber (reg:CC FLAGS_REG))])
19310    (parallel [(set (reg:SI SP_REG)
19311                    (minus:SI (reg:SI SP_REG) (match_dup 1)))
19312               (clobber (reg:CC FLAGS_REG))])]
19313   "TARGET_STACK_PROBE"
19314 {
19315 #ifdef CHECK_STACK_LIMIT
19316   if (CONST_INT_P (operands[1])
19317       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19318     emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19319                            operands[1]));
19320   else
19321 #endif
19322     emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19323                                                             operands[1])));
19324
19325   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19326   DONE;
19327 })
19328
19329 (define_expand "builtin_setjmp_receiver"
19330   [(label_ref (match_operand 0 "" ""))]
19331   "!TARGET_64BIT && flag_pic"
19332 {
19333   if (TARGET_MACHO)
19334     {
19335       rtx xops[3];
19336       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19337       rtx label_rtx = gen_label_rtx ();
19338       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19339       xops[0] = xops[1] = picreg;
19340       xops[2] = gen_rtx_CONST (SImode,
19341                   gen_rtx_MINUS (SImode,
19342                     gen_rtx_LABEL_REF (SImode, label_rtx),
19343                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19344       ix86_expand_binary_operator (MINUS, SImode, xops);
19345     }
19346   else
19347     emit_insn (gen_set_got (pic_offset_table_rtx));
19348   DONE;
19349 })
19350 \f
19351 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19352
19353 (define_split
19354   [(set (match_operand 0 "register_operand" "")
19355         (match_operator 3 "promotable_binary_operator"
19356            [(match_operand 1 "register_operand" "")
19357             (match_operand 2 "aligned_operand" "")]))
19358    (clobber (reg:CC FLAGS_REG))]
19359   "! TARGET_PARTIAL_REG_STALL && reload_completed
19360    && ((GET_MODE (operands[0]) == HImode
19361         && ((!optimize_size && !TARGET_FAST_PREFIX)
19362             /* ??? next two lines just !satisfies_constraint_K (...) */
19363             || !CONST_INT_P (operands[2])
19364             || satisfies_constraint_K (operands[2])))
19365        || (GET_MODE (operands[0]) == QImode
19366            && (TARGET_PROMOTE_QImode || optimize_size)))"
19367   [(parallel [(set (match_dup 0)
19368                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19369               (clobber (reg:CC FLAGS_REG))])]
19370   "operands[0] = gen_lowpart (SImode, operands[0]);
19371    operands[1] = gen_lowpart (SImode, operands[1]);
19372    if (GET_CODE (operands[3]) != ASHIFT)
19373      operands[2] = gen_lowpart (SImode, operands[2]);
19374    PUT_MODE (operands[3], SImode);")
19375
19376 ; Promote the QImode tests, as i386 has encoding of the AND
19377 ; instruction with 32-bit sign-extended immediate and thus the
19378 ; instruction size is unchanged, except in the %eax case for
19379 ; which it is increased by one byte, hence the ! optimize_size.
19380 (define_split
19381   [(set (match_operand 0 "flags_reg_operand" "")
19382         (match_operator 2 "compare_operator"
19383           [(and (match_operand 3 "aligned_operand" "")
19384                 (match_operand 4 "const_int_operand" ""))
19385            (const_int 0)]))
19386    (set (match_operand 1 "register_operand" "")
19387         (and (match_dup 3) (match_dup 4)))]
19388   "! TARGET_PARTIAL_REG_STALL && reload_completed
19389    /* Ensure that the operand will remain sign-extended immediate.  */
19390    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19391    && ! optimize_size
19392    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19393        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19394   [(parallel [(set (match_dup 0)
19395                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19396                                     (const_int 0)]))
19397               (set (match_dup 1)
19398                    (and:SI (match_dup 3) (match_dup 4)))])]
19399 {
19400   operands[4]
19401     = gen_int_mode (INTVAL (operands[4])
19402                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19403   operands[1] = gen_lowpart (SImode, operands[1]);
19404   operands[3] = gen_lowpart (SImode, operands[3]);
19405 })
19406
19407 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19408 ; the TEST instruction with 32-bit sign-extended immediate and thus
19409 ; the instruction size would at least double, which is not what we
19410 ; want even with ! optimize_size.
19411 (define_split
19412   [(set (match_operand 0 "flags_reg_operand" "")
19413         (match_operator 1 "compare_operator"
19414           [(and (match_operand:HI 2 "aligned_operand" "")
19415                 (match_operand:HI 3 "const_int_operand" ""))
19416            (const_int 0)]))]
19417   "! TARGET_PARTIAL_REG_STALL && reload_completed
19418    /* Ensure that the operand will remain sign-extended immediate.  */
19419    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19420    && ! TARGET_FAST_PREFIX
19421    && ! optimize_size"
19422   [(set (match_dup 0)
19423         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19424                          (const_int 0)]))]
19425 {
19426   operands[3]
19427     = gen_int_mode (INTVAL (operands[3])
19428                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19429   operands[2] = gen_lowpart (SImode, operands[2]);
19430 })
19431
19432 (define_split
19433   [(set (match_operand 0 "register_operand" "")
19434         (neg (match_operand 1 "register_operand" "")))
19435    (clobber (reg:CC FLAGS_REG))]
19436   "! TARGET_PARTIAL_REG_STALL && reload_completed
19437    && (GET_MODE (operands[0]) == HImode
19438        || (GET_MODE (operands[0]) == QImode
19439            && (TARGET_PROMOTE_QImode || optimize_size)))"
19440   [(parallel [(set (match_dup 0)
19441                    (neg:SI (match_dup 1)))
19442               (clobber (reg:CC FLAGS_REG))])]
19443   "operands[0] = gen_lowpart (SImode, operands[0]);
19444    operands[1] = gen_lowpart (SImode, operands[1]);")
19445
19446 (define_split
19447   [(set (match_operand 0 "register_operand" "")
19448         (not (match_operand 1 "register_operand" "")))]
19449   "! TARGET_PARTIAL_REG_STALL && reload_completed
19450    && (GET_MODE (operands[0]) == HImode
19451        || (GET_MODE (operands[0]) == QImode
19452            && (TARGET_PROMOTE_QImode || optimize_size)))"
19453   [(set (match_dup 0)
19454         (not:SI (match_dup 1)))]
19455   "operands[0] = gen_lowpart (SImode, operands[0]);
19456    operands[1] = gen_lowpart (SImode, operands[1]);")
19457
19458 (define_split
19459   [(set (match_operand 0 "register_operand" "")
19460         (if_then_else (match_operator 1 "comparison_operator"
19461                                 [(reg FLAGS_REG) (const_int 0)])
19462                       (match_operand 2 "register_operand" "")
19463                       (match_operand 3 "register_operand" "")))]
19464   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19465    && (GET_MODE (operands[0]) == HImode
19466        || (GET_MODE (operands[0]) == QImode
19467            && (TARGET_PROMOTE_QImode || optimize_size)))"
19468   [(set (match_dup 0)
19469         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19470   "operands[0] = gen_lowpart (SImode, operands[0]);
19471    operands[2] = gen_lowpart (SImode, operands[2]);
19472    operands[3] = gen_lowpart (SImode, operands[3]);")
19473
19474 \f
19475 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19476 ;; transform a complex memory operation into two memory to register operations.
19477
19478 ;; Don't push memory operands
19479 (define_peephole2
19480   [(set (match_operand:SI 0 "push_operand" "")
19481         (match_operand:SI 1 "memory_operand" ""))
19482    (match_scratch:SI 2 "r")]
19483   "!optimize_size && !TARGET_PUSH_MEMORY
19484    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19485   [(set (match_dup 2) (match_dup 1))
19486    (set (match_dup 0) (match_dup 2))]
19487   "")
19488
19489 (define_peephole2
19490   [(set (match_operand:DI 0 "push_operand" "")
19491         (match_operand:DI 1 "memory_operand" ""))
19492    (match_scratch:DI 2 "r")]
19493   "!optimize_size && !TARGET_PUSH_MEMORY
19494    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19495   [(set (match_dup 2) (match_dup 1))
19496    (set (match_dup 0) (match_dup 2))]
19497   "")
19498
19499 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19500 ;; SImode pushes.
19501 (define_peephole2
19502   [(set (match_operand:SF 0 "push_operand" "")
19503         (match_operand:SF 1 "memory_operand" ""))
19504    (match_scratch:SF 2 "r")]
19505   "!optimize_size && !TARGET_PUSH_MEMORY
19506    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19507   [(set (match_dup 2) (match_dup 1))
19508    (set (match_dup 0) (match_dup 2))]
19509   "")
19510
19511 (define_peephole2
19512   [(set (match_operand:HI 0 "push_operand" "")
19513         (match_operand:HI 1 "memory_operand" ""))
19514    (match_scratch:HI 2 "r")]
19515   "!optimize_size && !TARGET_PUSH_MEMORY
19516    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19517   [(set (match_dup 2) (match_dup 1))
19518    (set (match_dup 0) (match_dup 2))]
19519   "")
19520
19521 (define_peephole2
19522   [(set (match_operand:QI 0 "push_operand" "")
19523         (match_operand:QI 1 "memory_operand" ""))
19524    (match_scratch:QI 2 "q")]
19525   "!optimize_size && !TARGET_PUSH_MEMORY
19526    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19527   [(set (match_dup 2) (match_dup 1))
19528    (set (match_dup 0) (match_dup 2))]
19529   "")
19530
19531 ;; Don't move an immediate directly to memory when the instruction
19532 ;; gets too big.
19533 (define_peephole2
19534   [(match_scratch:SI 1 "r")
19535    (set (match_operand:SI 0 "memory_operand" "")
19536         (const_int 0))]
19537   "! optimize_size
19538    && ! TARGET_USE_MOV0
19539    && TARGET_SPLIT_LONG_MOVES
19540    && get_attr_length (insn) >= ix86_cost->large_insn
19541    && peep2_regno_dead_p (0, FLAGS_REG)"
19542   [(parallel [(set (match_dup 1) (const_int 0))
19543               (clobber (reg:CC FLAGS_REG))])
19544    (set (match_dup 0) (match_dup 1))]
19545   "")
19546
19547 (define_peephole2
19548   [(match_scratch:HI 1 "r")
19549    (set (match_operand:HI 0 "memory_operand" "")
19550         (const_int 0))]
19551   "! optimize_size
19552    && ! TARGET_USE_MOV0
19553    && TARGET_SPLIT_LONG_MOVES
19554    && get_attr_length (insn) >= ix86_cost->large_insn
19555    && peep2_regno_dead_p (0, FLAGS_REG)"
19556   [(parallel [(set (match_dup 2) (const_int 0))
19557               (clobber (reg:CC FLAGS_REG))])
19558    (set (match_dup 0) (match_dup 1))]
19559   "operands[2] = gen_lowpart (SImode, operands[1]);")
19560
19561 (define_peephole2
19562   [(match_scratch:QI 1 "q")
19563    (set (match_operand:QI 0 "memory_operand" "")
19564         (const_int 0))]
19565   "! optimize_size
19566    && ! TARGET_USE_MOV0
19567    && TARGET_SPLIT_LONG_MOVES
19568    && get_attr_length (insn) >= ix86_cost->large_insn
19569    && peep2_regno_dead_p (0, FLAGS_REG)"
19570   [(parallel [(set (match_dup 2) (const_int 0))
19571               (clobber (reg:CC FLAGS_REG))])
19572    (set (match_dup 0) (match_dup 1))]
19573   "operands[2] = gen_lowpart (SImode, operands[1]);")
19574
19575 (define_peephole2
19576   [(match_scratch:SI 2 "r")
19577    (set (match_operand:SI 0 "memory_operand" "")
19578         (match_operand:SI 1 "immediate_operand" ""))]
19579   "! optimize_size
19580    && get_attr_length (insn) >= ix86_cost->large_insn
19581    && TARGET_SPLIT_LONG_MOVES"
19582   [(set (match_dup 2) (match_dup 1))
19583    (set (match_dup 0) (match_dup 2))]
19584   "")
19585
19586 (define_peephole2
19587   [(match_scratch:HI 2 "r")
19588    (set (match_operand:HI 0 "memory_operand" "")
19589         (match_operand:HI 1 "immediate_operand" ""))]
19590   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19591   && TARGET_SPLIT_LONG_MOVES"
19592   [(set (match_dup 2) (match_dup 1))
19593    (set (match_dup 0) (match_dup 2))]
19594   "")
19595
19596 (define_peephole2
19597   [(match_scratch:QI 2 "q")
19598    (set (match_operand:QI 0 "memory_operand" "")
19599         (match_operand:QI 1 "immediate_operand" ""))]
19600   "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19601   && TARGET_SPLIT_LONG_MOVES"
19602   [(set (match_dup 2) (match_dup 1))
19603    (set (match_dup 0) (match_dup 2))]
19604   "")
19605
19606 ;; Don't compare memory with zero, load and use a test instead.
19607 (define_peephole2
19608   [(set (match_operand 0 "flags_reg_operand" "")
19609         (match_operator 1 "compare_operator"
19610           [(match_operand:SI 2 "memory_operand" "")
19611            (const_int 0)]))
19612    (match_scratch:SI 3 "r")]
19613   "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19614   [(set (match_dup 3) (match_dup 2))
19615    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19616   "")
19617
19618 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19619 ;; Don't split NOTs with a displacement operand, because resulting XOR
19620 ;; will not be pairable anyway.
19621 ;;
19622 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19623 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19624 ;; so this split helps here as well.
19625 ;;
19626 ;; Note: Can't do this as a regular split because we can't get proper
19627 ;; lifetime information then.
19628
19629 (define_peephole2
19630   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19631         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19632   "!optimize_size
19633    && peep2_regno_dead_p (0, FLAGS_REG)
19634    && ((TARGET_PENTIUM
19635         && (!MEM_P (operands[0])
19636             || !memory_displacement_operand (operands[0], SImode)))
19637        || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19638   [(parallel [(set (match_dup 0)
19639                    (xor:SI (match_dup 1) (const_int -1)))
19640               (clobber (reg:CC FLAGS_REG))])]
19641   "")
19642
19643 (define_peephole2
19644   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19645         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19646   "!optimize_size
19647    && peep2_regno_dead_p (0, FLAGS_REG)
19648    && ((TARGET_PENTIUM
19649         && (!MEM_P (operands[0])
19650             || !memory_displacement_operand (operands[0], HImode)))
19651        || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19652   [(parallel [(set (match_dup 0)
19653                    (xor:HI (match_dup 1) (const_int -1)))
19654               (clobber (reg:CC FLAGS_REG))])]
19655   "")
19656
19657 (define_peephole2
19658   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19659         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19660   "!optimize_size
19661    && peep2_regno_dead_p (0, FLAGS_REG)
19662    && ((TARGET_PENTIUM
19663         && (!MEM_P (operands[0])
19664             || !memory_displacement_operand (operands[0], QImode)))
19665        || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19666   [(parallel [(set (match_dup 0)
19667                    (xor:QI (match_dup 1) (const_int -1)))
19668               (clobber (reg:CC FLAGS_REG))])]
19669   "")
19670
19671 ;; Non pairable "test imm, reg" instructions can be translated to
19672 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19673 ;; byte opcode instead of two, have a short form for byte operands),
19674 ;; so do it for other CPUs as well.  Given that the value was dead,
19675 ;; this should not create any new dependencies.  Pass on the sub-word
19676 ;; versions if we're concerned about partial register stalls.
19677
19678 (define_peephole2
19679   [(set (match_operand 0 "flags_reg_operand" "")
19680         (match_operator 1 "compare_operator"
19681           [(and:SI (match_operand:SI 2 "register_operand" "")
19682                    (match_operand:SI 3 "immediate_operand" ""))
19683            (const_int 0)]))]
19684   "ix86_match_ccmode (insn, CCNOmode)
19685    && (true_regnum (operands[2]) != 0
19686        || satisfies_constraint_K (operands[3]))
19687    && peep2_reg_dead_p (1, operands[2])"
19688   [(parallel
19689      [(set (match_dup 0)
19690            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19691                             (const_int 0)]))
19692       (set (match_dup 2)
19693            (and:SI (match_dup 2) (match_dup 3)))])]
19694   "")
19695
19696 ;; We don't need to handle HImode case, because it will be promoted to SImode
19697 ;; on ! TARGET_PARTIAL_REG_STALL
19698
19699 (define_peephole2
19700   [(set (match_operand 0 "flags_reg_operand" "")
19701         (match_operator 1 "compare_operator"
19702           [(and:QI (match_operand:QI 2 "register_operand" "")
19703                    (match_operand:QI 3 "immediate_operand" ""))
19704            (const_int 0)]))]
19705   "! TARGET_PARTIAL_REG_STALL
19706    && ix86_match_ccmode (insn, CCNOmode)
19707    && true_regnum (operands[2]) != 0
19708    && peep2_reg_dead_p (1, operands[2])"
19709   [(parallel
19710      [(set (match_dup 0)
19711            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19712                             (const_int 0)]))
19713       (set (match_dup 2)
19714            (and:QI (match_dup 2) (match_dup 3)))])]
19715   "")
19716
19717 (define_peephole2
19718   [(set (match_operand 0 "flags_reg_operand" "")
19719         (match_operator 1 "compare_operator"
19720           [(and:SI
19721              (zero_extract:SI
19722                (match_operand 2 "ext_register_operand" "")
19723                (const_int 8)
19724                (const_int 8))
19725              (match_operand 3 "const_int_operand" ""))
19726            (const_int 0)]))]
19727   "! TARGET_PARTIAL_REG_STALL
19728    && ix86_match_ccmode (insn, CCNOmode)
19729    && true_regnum (operands[2]) != 0
19730    && peep2_reg_dead_p (1, operands[2])"
19731   [(parallel [(set (match_dup 0)
19732                    (match_op_dup 1
19733                      [(and:SI
19734                         (zero_extract:SI
19735                           (match_dup 2)
19736                           (const_int 8)
19737                           (const_int 8))
19738                         (match_dup 3))
19739                       (const_int 0)]))
19740               (set (zero_extract:SI (match_dup 2)
19741                                     (const_int 8)
19742                                     (const_int 8))
19743                    (and:SI
19744                      (zero_extract:SI
19745                        (match_dup 2)
19746                        (const_int 8)
19747                        (const_int 8))
19748                      (match_dup 3)))])]
19749   "")
19750
19751 ;; Don't do logical operations with memory inputs.
19752 (define_peephole2
19753   [(match_scratch:SI 2 "r")
19754    (parallel [(set (match_operand:SI 0 "register_operand" "")
19755                    (match_operator:SI 3 "arith_or_logical_operator"
19756                      [(match_dup 0)
19757                       (match_operand:SI 1 "memory_operand" "")]))
19758               (clobber (reg:CC FLAGS_REG))])]
19759   "! optimize_size && ! TARGET_READ_MODIFY"
19760   [(set (match_dup 2) (match_dup 1))
19761    (parallel [(set (match_dup 0)
19762                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19763               (clobber (reg:CC FLAGS_REG))])]
19764   "")
19765
19766 (define_peephole2
19767   [(match_scratch:SI 2 "r")
19768    (parallel [(set (match_operand:SI 0 "register_operand" "")
19769                    (match_operator:SI 3 "arith_or_logical_operator"
19770                      [(match_operand:SI 1 "memory_operand" "")
19771                       (match_dup 0)]))
19772               (clobber (reg:CC FLAGS_REG))])]
19773   "! optimize_size && ! TARGET_READ_MODIFY"
19774   [(set (match_dup 2) (match_dup 1))
19775    (parallel [(set (match_dup 0)
19776                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19777               (clobber (reg:CC FLAGS_REG))])]
19778   "")
19779
19780 ; Don't do logical operations with memory outputs
19781 ;
19782 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19783 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19784 ; the same decoder scheduling characteristics as the original.
19785
19786 (define_peephole2
19787   [(match_scratch:SI 2 "r")
19788    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19789                    (match_operator:SI 3 "arith_or_logical_operator"
19790                      [(match_dup 0)
19791                       (match_operand:SI 1 "nonmemory_operand" "")]))
19792               (clobber (reg:CC FLAGS_REG))])]
19793   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19794   [(set (match_dup 2) (match_dup 0))
19795    (parallel [(set (match_dup 2)
19796                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19797               (clobber (reg:CC FLAGS_REG))])
19798    (set (match_dup 0) (match_dup 2))]
19799   "")
19800
19801 (define_peephole2
19802   [(match_scratch:SI 2 "r")
19803    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19804                    (match_operator:SI 3 "arith_or_logical_operator"
19805                      [(match_operand:SI 1 "nonmemory_operand" "")
19806                       (match_dup 0)]))
19807               (clobber (reg:CC FLAGS_REG))])]
19808   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19809   [(set (match_dup 2) (match_dup 0))
19810    (parallel [(set (match_dup 2)
19811                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19812               (clobber (reg:CC FLAGS_REG))])
19813    (set (match_dup 0) (match_dup 2))]
19814   "")
19815
19816 ;; Attempt to always use XOR for zeroing registers.
19817 (define_peephole2
19818   [(set (match_operand 0 "register_operand" "")
19819         (match_operand 1 "const0_operand" ""))]
19820   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19821    && (! TARGET_USE_MOV0 || optimize_size)
19822    && GENERAL_REG_P (operands[0])
19823    && peep2_regno_dead_p (0, FLAGS_REG)"
19824   [(parallel [(set (match_dup 0) (const_int 0))
19825               (clobber (reg:CC FLAGS_REG))])]
19826 {
19827   operands[0] = gen_lowpart (word_mode, operands[0]);
19828 })
19829
19830 (define_peephole2
19831   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19832         (const_int 0))]
19833   "(GET_MODE (operands[0]) == QImode
19834     || GET_MODE (operands[0]) == HImode)
19835    && (! TARGET_USE_MOV0 || optimize_size)
19836    && peep2_regno_dead_p (0, FLAGS_REG)"
19837   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19838               (clobber (reg:CC FLAGS_REG))])])
19839
19840 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19841 (define_peephole2
19842   [(set (match_operand 0 "register_operand" "")
19843         (const_int -1))]
19844   "(GET_MODE (operands[0]) == HImode
19845     || GET_MODE (operands[0]) == SImode
19846     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19847    && (optimize_size || TARGET_PENTIUM)
19848    && peep2_regno_dead_p (0, FLAGS_REG)"
19849   [(parallel [(set (match_dup 0) (const_int -1))
19850               (clobber (reg:CC FLAGS_REG))])]
19851   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19852                               operands[0]);")
19853
19854 ;; Attempt to convert simple leas to adds. These can be created by
19855 ;; move expanders.
19856 (define_peephole2
19857   [(set (match_operand:SI 0 "register_operand" "")
19858         (plus:SI (match_dup 0)
19859                  (match_operand:SI 1 "nonmemory_operand" "")))]
19860   "peep2_regno_dead_p (0, FLAGS_REG)"
19861   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19862               (clobber (reg:CC FLAGS_REG))])]
19863   "")
19864
19865 (define_peephole2
19866   [(set (match_operand:SI 0 "register_operand" "")
19867         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19868                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19869   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19870   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19871               (clobber (reg:CC FLAGS_REG))])]
19872   "operands[2] = gen_lowpart (SImode, operands[2]);")
19873
19874 (define_peephole2
19875   [(set (match_operand:DI 0 "register_operand" "")
19876         (plus:DI (match_dup 0)
19877                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19878   "peep2_regno_dead_p (0, FLAGS_REG)"
19879   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19880               (clobber (reg:CC FLAGS_REG))])]
19881   "")
19882
19883 (define_peephole2
19884   [(set (match_operand:SI 0 "register_operand" "")
19885         (mult:SI (match_dup 0)
19886                  (match_operand:SI 1 "const_int_operand" "")))]
19887   "exact_log2 (INTVAL (operands[1])) >= 0
19888    && peep2_regno_dead_p (0, FLAGS_REG)"
19889   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19890               (clobber (reg:CC FLAGS_REG))])]
19891   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19892
19893 (define_peephole2
19894   [(set (match_operand:DI 0 "register_operand" "")
19895         (mult:DI (match_dup 0)
19896                  (match_operand:DI 1 "const_int_operand" "")))]
19897   "exact_log2 (INTVAL (operands[1])) >= 0
19898    && peep2_regno_dead_p (0, FLAGS_REG)"
19899   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19900               (clobber (reg:CC FLAGS_REG))])]
19901   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19902
19903 (define_peephole2
19904   [(set (match_operand:SI 0 "register_operand" "")
19905         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19906                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19907   "exact_log2 (INTVAL (operands[2])) >= 0
19908    && REGNO (operands[0]) == REGNO (operands[1])
19909    && peep2_regno_dead_p (0, FLAGS_REG)"
19910   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19911               (clobber (reg:CC FLAGS_REG))])]
19912   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19913
19914 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19915 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19916 ;; many CPUs it is also faster, since special hardware to avoid esp
19917 ;; dependencies is present.
19918
19919 ;; While some of these conversions may be done using splitters, we use peepholes
19920 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19921
19922 ;; Convert prologue esp subtractions to push.
19923 ;; We need register to push.  In order to keep verify_flow_info happy we have
19924 ;; two choices
19925 ;; - use scratch and clobber it in order to avoid dependencies
19926 ;; - use already live register
19927 ;; We can't use the second way right now, since there is no reliable way how to
19928 ;; verify that given register is live.  First choice will also most likely in
19929 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19930 ;; call clobbered registers are dead.  We may want to use base pointer as an
19931 ;; alternative when no register is available later.
19932
19933 (define_peephole2
19934   [(match_scratch:SI 0 "r")
19935    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19936               (clobber (reg:CC FLAGS_REG))
19937               (clobber (mem:BLK (scratch)))])]
19938   "optimize_size || !TARGET_SUB_ESP_4"
19939   [(clobber (match_dup 0))
19940    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19941               (clobber (mem:BLK (scratch)))])])
19942
19943 (define_peephole2
19944   [(match_scratch:SI 0 "r")
19945    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19946               (clobber (reg:CC FLAGS_REG))
19947               (clobber (mem:BLK (scratch)))])]
19948   "optimize_size || !TARGET_SUB_ESP_8"
19949   [(clobber (match_dup 0))
19950    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19951    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19952               (clobber (mem:BLK (scratch)))])])
19953
19954 ;; Convert esp subtractions to push.
19955 (define_peephole2
19956   [(match_scratch:SI 0 "r")
19957    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19958               (clobber (reg:CC FLAGS_REG))])]
19959   "optimize_size || !TARGET_SUB_ESP_4"
19960   [(clobber (match_dup 0))
19961    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19962
19963 (define_peephole2
19964   [(match_scratch:SI 0 "r")
19965    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19966               (clobber (reg:CC FLAGS_REG))])]
19967   "optimize_size || !TARGET_SUB_ESP_8"
19968   [(clobber (match_dup 0))
19969    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19970    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19971
19972 ;; Convert epilogue deallocator to pop.
19973 (define_peephole2
19974   [(match_scratch:SI 0 "r")
19975    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19976               (clobber (reg:CC FLAGS_REG))
19977               (clobber (mem:BLK (scratch)))])]
19978   "optimize_size || !TARGET_ADD_ESP_4"
19979   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19980               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19981               (clobber (mem:BLK (scratch)))])]
19982   "")
19983
19984 ;; Two pops case is tricky, since pop causes dependency on destination register.
19985 ;; We use two registers if available.
19986 (define_peephole2
19987   [(match_scratch:SI 0 "r")
19988    (match_scratch:SI 1 "r")
19989    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19990               (clobber (reg:CC FLAGS_REG))
19991               (clobber (mem:BLK (scratch)))])]
19992   "optimize_size || !TARGET_ADD_ESP_8"
19993   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19994               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19995               (clobber (mem:BLK (scratch)))])
19996    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19997               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19998   "")
19999
20000 (define_peephole2
20001   [(match_scratch:SI 0 "r")
20002    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20003               (clobber (reg:CC FLAGS_REG))
20004               (clobber (mem:BLK (scratch)))])]
20005   "optimize_size"
20006   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20007               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20008               (clobber (mem:BLK (scratch)))])
20009    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20010               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20011   "")
20012
20013 ;; Convert esp additions to pop.
20014 (define_peephole2
20015   [(match_scratch:SI 0 "r")
20016    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20017               (clobber (reg:CC FLAGS_REG))])]
20018   ""
20019   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20020               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20021   "")
20022
20023 ;; Two pops case is tricky, since pop causes dependency on destination register.
20024 ;; We use two registers if available.
20025 (define_peephole2
20026   [(match_scratch:SI 0 "r")
20027    (match_scratch:SI 1 "r")
20028    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20029               (clobber (reg:CC FLAGS_REG))])]
20030   ""
20031   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20032               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20033    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20034               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20035   "")
20036
20037 (define_peephole2
20038   [(match_scratch:SI 0 "r")
20039    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20040               (clobber (reg:CC FLAGS_REG))])]
20041   "optimize_size"
20042   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20043               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20044    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20045               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20046   "")
20047 \f
20048 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20049 ;; required and register dies.  Similarly for 128 to plus -128.
20050 (define_peephole2
20051   [(set (match_operand 0 "flags_reg_operand" "")
20052         (match_operator 1 "compare_operator"
20053           [(match_operand 2 "register_operand" "")
20054            (match_operand 3 "const_int_operand" "")]))]
20055   "(INTVAL (operands[3]) == -1
20056     || INTVAL (operands[3]) == 1
20057     || INTVAL (operands[3]) == 128)
20058    && ix86_match_ccmode (insn, CCGCmode)
20059    && peep2_reg_dead_p (1, operands[2])"
20060   [(parallel [(set (match_dup 0)
20061                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20062               (clobber (match_dup 2))])]
20063   "")
20064 \f
20065 (define_peephole2
20066   [(match_scratch:DI 0 "r")
20067    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20068               (clobber (reg:CC FLAGS_REG))
20069               (clobber (mem:BLK (scratch)))])]
20070   "optimize_size || !TARGET_SUB_ESP_4"
20071   [(clobber (match_dup 0))
20072    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20073               (clobber (mem:BLK (scratch)))])])
20074
20075 (define_peephole2
20076   [(match_scratch:DI 0 "r")
20077    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20078               (clobber (reg:CC FLAGS_REG))
20079               (clobber (mem:BLK (scratch)))])]
20080   "optimize_size || !TARGET_SUB_ESP_8"
20081   [(clobber (match_dup 0))
20082    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20083    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20084               (clobber (mem:BLK (scratch)))])])
20085
20086 ;; Convert esp subtractions to push.
20087 (define_peephole2
20088   [(match_scratch:DI 0 "r")
20089    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20090               (clobber (reg:CC FLAGS_REG))])]
20091   "optimize_size || !TARGET_SUB_ESP_4"
20092   [(clobber (match_dup 0))
20093    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20094
20095 (define_peephole2
20096   [(match_scratch:DI 0 "r")
20097    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20098               (clobber (reg:CC FLAGS_REG))])]
20099   "optimize_size || !TARGET_SUB_ESP_8"
20100   [(clobber (match_dup 0))
20101    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20102    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20103
20104 ;; Convert epilogue deallocator to pop.
20105 (define_peephole2
20106   [(match_scratch:DI 0 "r")
20107    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20108               (clobber (reg:CC FLAGS_REG))
20109               (clobber (mem:BLK (scratch)))])]
20110   "optimize_size || !TARGET_ADD_ESP_4"
20111   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20112               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20113               (clobber (mem:BLK (scratch)))])]
20114   "")
20115
20116 ;; Two pops case is tricky, since pop causes dependency on destination register.
20117 ;; We use two registers if available.
20118 (define_peephole2
20119   [(match_scratch:DI 0 "r")
20120    (match_scratch:DI 1 "r")
20121    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20122               (clobber (reg:CC FLAGS_REG))
20123               (clobber (mem:BLK (scratch)))])]
20124   "optimize_size || !TARGET_ADD_ESP_8"
20125   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20126               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20127               (clobber (mem:BLK (scratch)))])
20128    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20129               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20130   "")
20131
20132 (define_peephole2
20133   [(match_scratch:DI 0 "r")
20134    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20135               (clobber (reg:CC FLAGS_REG))
20136               (clobber (mem:BLK (scratch)))])]
20137   "optimize_size"
20138   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20139               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20140               (clobber (mem:BLK (scratch)))])
20141    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20142               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20143   "")
20144
20145 ;; Convert esp additions to pop.
20146 (define_peephole2
20147   [(match_scratch:DI 0 "r")
20148    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20149               (clobber (reg:CC FLAGS_REG))])]
20150   ""
20151   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20152               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20153   "")
20154
20155 ;; Two pops case is tricky, since pop causes dependency on destination register.
20156 ;; We use two registers if available.
20157 (define_peephole2
20158   [(match_scratch:DI 0 "r")
20159    (match_scratch:DI 1 "r")
20160    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20161               (clobber (reg:CC FLAGS_REG))])]
20162   ""
20163   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20164               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20165    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20166               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20167   "")
20168
20169 (define_peephole2
20170   [(match_scratch:DI 0 "r")
20171    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20172               (clobber (reg:CC FLAGS_REG))])]
20173   "optimize_size"
20174   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20175               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20176    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20177               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20178   "")
20179 \f
20180 ;; Convert imul by three, five and nine into lea
20181 (define_peephole2
20182   [(parallel
20183     [(set (match_operand:SI 0 "register_operand" "")
20184           (mult:SI (match_operand:SI 1 "register_operand" "")
20185                    (match_operand:SI 2 "const_int_operand" "")))
20186      (clobber (reg:CC FLAGS_REG))])]
20187   "INTVAL (operands[2]) == 3
20188    || INTVAL (operands[2]) == 5
20189    || INTVAL (operands[2]) == 9"
20190   [(set (match_dup 0)
20191         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20192                  (match_dup 1)))]
20193   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20194
20195 (define_peephole2
20196   [(parallel
20197     [(set (match_operand:SI 0 "register_operand" "")
20198           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20199                    (match_operand:SI 2 "const_int_operand" "")))
20200      (clobber (reg:CC FLAGS_REG))])]
20201   "!optimize_size
20202    && (INTVAL (operands[2]) == 3
20203        || INTVAL (operands[2]) == 5
20204        || INTVAL (operands[2]) == 9)"
20205   [(set (match_dup 0) (match_dup 1))
20206    (set (match_dup 0)
20207         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20208                  (match_dup 0)))]
20209   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20210
20211 (define_peephole2
20212   [(parallel
20213     [(set (match_operand:DI 0 "register_operand" "")
20214           (mult:DI (match_operand:DI 1 "register_operand" "")
20215                    (match_operand:DI 2 "const_int_operand" "")))
20216      (clobber (reg:CC FLAGS_REG))])]
20217   "TARGET_64BIT
20218    && (INTVAL (operands[2]) == 3
20219        || INTVAL (operands[2]) == 5
20220        || INTVAL (operands[2]) == 9)"
20221   [(set (match_dup 0)
20222         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20223                  (match_dup 1)))]
20224   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20225
20226 (define_peephole2
20227   [(parallel
20228     [(set (match_operand:DI 0 "register_operand" "")
20229           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20230                    (match_operand:DI 2 "const_int_operand" "")))
20231      (clobber (reg:CC FLAGS_REG))])]
20232   "TARGET_64BIT
20233    && !optimize_size
20234    && (INTVAL (operands[2]) == 3
20235        || INTVAL (operands[2]) == 5
20236        || INTVAL (operands[2]) == 9)"
20237   [(set (match_dup 0) (match_dup 1))
20238    (set (match_dup 0)
20239         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20240                  (match_dup 0)))]
20241   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20242
20243 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20244 ;; imul $32bit_imm, reg, reg is direct decoded.
20245 (define_peephole2
20246   [(match_scratch:DI 3 "r")
20247    (parallel [(set (match_operand:DI 0 "register_operand" "")
20248                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20249                             (match_operand:DI 2 "immediate_operand" "")))
20250               (clobber (reg:CC FLAGS_REG))])]
20251   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20252    && !satisfies_constraint_K (operands[2])"
20253   [(set (match_dup 3) (match_dup 1))
20254    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20255               (clobber (reg:CC FLAGS_REG))])]
20256 "")
20257
20258 (define_peephole2
20259   [(match_scratch:SI 3 "r")
20260    (parallel [(set (match_operand:SI 0 "register_operand" "")
20261                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20262                             (match_operand:SI 2 "immediate_operand" "")))
20263               (clobber (reg:CC FLAGS_REG))])]
20264   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20265    && !satisfies_constraint_K (operands[2])"
20266   [(set (match_dup 3) (match_dup 1))
20267    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20268               (clobber (reg:CC FLAGS_REG))])]
20269 "")
20270
20271 (define_peephole2
20272   [(match_scratch:SI 3 "r")
20273    (parallel [(set (match_operand:DI 0 "register_operand" "")
20274                    (zero_extend:DI
20275                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20276                               (match_operand:SI 2 "immediate_operand" ""))))
20277               (clobber (reg:CC FLAGS_REG))])]
20278   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20279    && !satisfies_constraint_K (operands[2])"
20280   [(set (match_dup 3) (match_dup 1))
20281    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20282               (clobber (reg:CC FLAGS_REG))])]
20283 "")
20284
20285 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20286 ;; Convert it into imul reg, reg
20287 ;; It would be better to force assembler to encode instruction using long
20288 ;; immediate, but there is apparently no way to do so.
20289 (define_peephole2
20290   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20291                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20292                             (match_operand:DI 2 "const_int_operand" "")))
20293               (clobber (reg:CC FLAGS_REG))])
20294    (match_scratch:DI 3 "r")]
20295   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20296    && satisfies_constraint_K (operands[2])"
20297   [(set (match_dup 3) (match_dup 2))
20298    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20299               (clobber (reg:CC FLAGS_REG))])]
20300 {
20301   if (!rtx_equal_p (operands[0], operands[1]))
20302     emit_move_insn (operands[0], operands[1]);
20303 })
20304
20305 (define_peephole2
20306   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20307                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20308                             (match_operand:SI 2 "const_int_operand" "")))
20309               (clobber (reg:CC FLAGS_REG))])
20310    (match_scratch:SI 3 "r")]
20311   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20312    && satisfies_constraint_K (operands[2])"
20313   [(set (match_dup 3) (match_dup 2))
20314    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20315               (clobber (reg:CC FLAGS_REG))])]
20316 {
20317   if (!rtx_equal_p (operands[0], operands[1]))
20318     emit_move_insn (operands[0], operands[1]);
20319 })
20320
20321 (define_peephole2
20322   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20323                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20324                             (match_operand:HI 2 "immediate_operand" "")))
20325               (clobber (reg:CC FLAGS_REG))])
20326    (match_scratch:HI 3 "r")]
20327   "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size"
20328   [(set (match_dup 3) (match_dup 2))
20329    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20330               (clobber (reg:CC FLAGS_REG))])]
20331 {
20332   if (!rtx_equal_p (operands[0], operands[1]))
20333     emit_move_insn (operands[0], operands[1]);
20334 })
20335
20336 ;; After splitting up read-modify operations, array accesses with memory
20337 ;; operands might end up in form:
20338 ;;  sall    $2, %eax
20339 ;;  movl    4(%esp), %edx
20340 ;;  addl    %edx, %eax
20341 ;; instead of pre-splitting:
20342 ;;  sall    $2, %eax
20343 ;;  addl    4(%esp), %eax
20344 ;; Turn it into:
20345 ;;  movl    4(%esp), %edx
20346 ;;  leal    (%edx,%eax,4), %eax
20347
20348 (define_peephole2
20349   [(parallel [(set (match_operand 0 "register_operand" "")
20350                    (ashift (match_operand 1 "register_operand" "")
20351                            (match_operand 2 "const_int_operand" "")))
20352                (clobber (reg:CC FLAGS_REG))])
20353    (set (match_operand 3 "register_operand")
20354         (match_operand 4 "x86_64_general_operand" ""))
20355    (parallel [(set (match_operand 5 "register_operand" "")
20356                    (plus (match_operand 6 "register_operand" "")
20357                          (match_operand 7 "register_operand" "")))
20358                    (clobber (reg:CC FLAGS_REG))])]
20359   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20360    /* Validate MODE for lea.  */
20361    && ((!TARGET_PARTIAL_REG_STALL
20362         && (GET_MODE (operands[0]) == QImode
20363             || GET_MODE (operands[0]) == HImode))
20364        || GET_MODE (operands[0]) == SImode
20365        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20366    /* We reorder load and the shift.  */
20367    && !rtx_equal_p (operands[1], operands[3])
20368    && !reg_overlap_mentioned_p (operands[0], operands[4])
20369    /* Last PLUS must consist of operand 0 and 3.  */
20370    && !rtx_equal_p (operands[0], operands[3])
20371    && (rtx_equal_p (operands[3], operands[6])
20372        || rtx_equal_p (operands[3], operands[7]))
20373    && (rtx_equal_p (operands[0], operands[6])
20374        || rtx_equal_p (operands[0], operands[7]))
20375    /* The intermediate operand 0 must die or be same as output.  */
20376    && (rtx_equal_p (operands[0], operands[5])
20377        || peep2_reg_dead_p (3, operands[0]))"
20378   [(set (match_dup 3) (match_dup 4))
20379    (set (match_dup 0) (match_dup 1))]
20380 {
20381   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20382   int scale = 1 << INTVAL (operands[2]);
20383   rtx index = gen_lowpart (Pmode, operands[1]);
20384   rtx base = gen_lowpart (Pmode, operands[3]);
20385   rtx dest = gen_lowpart (mode, operands[5]);
20386
20387   operands[1] = gen_rtx_PLUS (Pmode, base,
20388                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20389   if (mode != Pmode)
20390     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20391   operands[0] = dest;
20392 })
20393 \f
20394 ;; Call-value patterns last so that the wildcard operand does not
20395 ;; disrupt insn-recog's switch tables.
20396
20397 (define_insn "*call_value_pop_0"
20398   [(set (match_operand 0 "" "")
20399         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20400               (match_operand:SI 2 "" "")))
20401    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20402                             (match_operand:SI 3 "immediate_operand" "")))]
20403   "!TARGET_64BIT"
20404 {
20405   if (SIBLING_CALL_P (insn))
20406     return "jmp\t%P1";
20407   else
20408     return "call\t%P1";
20409 }
20410   [(set_attr "type" "callv")])
20411
20412 (define_insn "*call_value_pop_1"
20413   [(set (match_operand 0 "" "")
20414         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20415               (match_operand:SI 2 "" "")))
20416    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20417                             (match_operand:SI 3 "immediate_operand" "i")))]
20418   "!TARGET_64BIT"
20419 {
20420   if (constant_call_address_operand (operands[1], Pmode))
20421     {
20422       if (SIBLING_CALL_P (insn))
20423         return "jmp\t%P1";
20424       else
20425         return "call\t%P1";
20426     }
20427   if (SIBLING_CALL_P (insn))
20428     return "jmp\t%A1";
20429   else
20430     return "call\t%A1";
20431 }
20432   [(set_attr "type" "callv")])
20433
20434 (define_insn "*call_value_0"
20435   [(set (match_operand 0 "" "")
20436         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20437               (match_operand:SI 2 "" "")))]
20438   "!TARGET_64BIT"
20439 {
20440   if (SIBLING_CALL_P (insn))
20441     return "jmp\t%P1";
20442   else
20443     return "call\t%P1";
20444 }
20445   [(set_attr "type" "callv")])
20446
20447 (define_insn "*call_value_0_rex64"
20448   [(set (match_operand 0 "" "")
20449         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20450               (match_operand:DI 2 "const_int_operand" "")))]
20451   "TARGET_64BIT"
20452 {
20453   if (SIBLING_CALL_P (insn))
20454     return "jmp\t%P1";
20455   else
20456     return "call\t%P1";
20457 }
20458   [(set_attr "type" "callv")])
20459
20460 (define_insn "*call_value_1"
20461   [(set (match_operand 0 "" "")
20462         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20463               (match_operand:SI 2 "" "")))]
20464   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20465 {
20466   if (constant_call_address_operand (operands[1], Pmode))
20467     return "call\t%P1";
20468   return "call\t%A1";
20469 }
20470   [(set_attr "type" "callv")])
20471
20472 (define_insn "*sibcall_value_1"
20473   [(set (match_operand 0 "" "")
20474         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20475               (match_operand:SI 2 "" "")))]
20476   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20477 {
20478   if (constant_call_address_operand (operands[1], Pmode))
20479     return "jmp\t%P1";
20480   return "jmp\t%A1";
20481 }
20482   [(set_attr "type" "callv")])
20483
20484 (define_insn "*call_value_1_rex64"
20485   [(set (match_operand 0 "" "")
20486         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20487               (match_operand:DI 2 "" "")))]
20488   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20489 {
20490   if (constant_call_address_operand (operands[1], Pmode))
20491     return "call\t%P1";
20492   return "call\t%A1";
20493 }
20494   [(set_attr "type" "callv")])
20495
20496 (define_insn "*sibcall_value_1_rex64"
20497   [(set (match_operand 0 "" "")
20498         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20499               (match_operand:DI 2 "" "")))]
20500   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20501   "jmp\t%P1"
20502   [(set_attr "type" "callv")])
20503
20504 (define_insn "*sibcall_value_1_rex64_v"
20505   [(set (match_operand 0 "" "")
20506         (call (mem:QI (reg:DI R11_REG))
20507               (match_operand:DI 1 "" "")))]
20508   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20509   "jmp\t*%%r11"
20510   [(set_attr "type" "callv")])
20511 \f
20512 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20513 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20514 ;; caught for use by garbage collectors and the like.  Using an insn that
20515 ;; maps to SIGILL makes it more likely the program will rightfully die.
20516 ;; Keeping with tradition, "6" is in honor of #UD.
20517 (define_insn "trap"
20518   [(trap_if (const_int 1) (const_int 6))]
20519   ""
20520   { return ASM_SHORT "0x0b0f"; }
20521   [(set_attr "length" "2")])
20522
20523 (define_expand "sse_prologue_save"
20524   [(parallel [(set (match_operand:BLK 0 "" "")
20525                    (unspec:BLK [(reg:DI 21)
20526                                 (reg:DI 22)
20527                                 (reg:DI 23)
20528                                 (reg:DI 24)
20529                                 (reg:DI 25)
20530                                 (reg:DI 26)
20531                                 (reg:DI 27)
20532                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20533               (use (match_operand:DI 1 "register_operand" ""))
20534               (use (match_operand:DI 2 "immediate_operand" ""))
20535               (use (label_ref:DI (match_operand 3 "" "")))])]
20536   "TARGET_64BIT"
20537   "")
20538
20539 (define_insn "*sse_prologue_save_insn"
20540   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20541                           (match_operand:DI 4 "const_int_operand" "n")))
20542         (unspec:BLK [(reg:DI 21)
20543                      (reg:DI 22)
20544                      (reg:DI 23)
20545                      (reg:DI 24)
20546                      (reg:DI 25)
20547                      (reg:DI 26)
20548                      (reg:DI 27)
20549                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20550    (use (match_operand:DI 1 "register_operand" "r"))
20551    (use (match_operand:DI 2 "const_int_operand" "i"))
20552    (use (label_ref:DI (match_operand 3 "" "X")))]
20553   "TARGET_64BIT
20554    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20555    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20556   "*
20557 {
20558   int i;
20559   operands[0] = gen_rtx_MEM (Pmode,
20560                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20561   output_asm_insn (\"jmp\\t%A1\", operands);
20562   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20563     {
20564       operands[4] = adjust_address (operands[0], DImode, i*16);
20565       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20566       PUT_MODE (operands[4], TImode);
20567       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20568         output_asm_insn (\"rex\", operands);
20569       output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20570     }
20571   (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20572                              CODE_LABEL_NUMBER (operands[3]));
20573   return \"\";
20574 }
20575   "
20576   [(set_attr "type" "other")
20577    (set_attr "length_immediate" "0")
20578    (set_attr "length_address" "0")
20579    (set_attr "length" "135")
20580    (set_attr "memory" "store")
20581    (set_attr "modrm" "0")
20582    (set_attr "mode" "DI")])
20583
20584 (define_expand "prefetch"
20585   [(prefetch (match_operand 0 "address_operand" "")
20586              (match_operand:SI 1 "const_int_operand" "")
20587              (match_operand:SI 2 "const_int_operand" ""))]
20588   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20589 {
20590   int rw = INTVAL (operands[1]);
20591   int locality = INTVAL (operands[2]);
20592
20593   gcc_assert (rw == 0 || rw == 1);
20594   gcc_assert (locality >= 0 && locality <= 3);
20595   gcc_assert (GET_MODE (operands[0]) == Pmode
20596               || GET_MODE (operands[0]) == VOIDmode);
20597
20598   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20599      supported by SSE counterpart or the SSE prefetch is not available
20600      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20601      of locality.  */
20602   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20603     operands[2] = GEN_INT (3);
20604   else
20605     operands[1] = const0_rtx;
20606 })
20607
20608 (define_insn "*prefetch_sse"
20609   [(prefetch (match_operand:SI 0 "address_operand" "p")
20610              (const_int 0)
20611              (match_operand:SI 1 "const_int_operand" ""))]
20612   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20613 {
20614   static const char * const patterns[4] = {
20615    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20616   };
20617
20618   int locality = INTVAL (operands[1]);
20619   gcc_assert (locality >= 0 && locality <= 3);
20620
20621   return patterns[locality];
20622 }
20623   [(set_attr "type" "sse")
20624    (set_attr "memory" "none")])
20625
20626 (define_insn "*prefetch_sse_rex"
20627   [(prefetch (match_operand:DI 0 "address_operand" "p")
20628              (const_int 0)
20629              (match_operand:SI 1 "const_int_operand" ""))]
20630   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20631 {
20632   static const char * const patterns[4] = {
20633    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20634   };
20635
20636   int locality = INTVAL (operands[1]);
20637   gcc_assert (locality >= 0 && locality <= 3);
20638
20639   return patterns[locality];
20640 }
20641   [(set_attr "type" "sse")
20642    (set_attr "memory" "none")])
20643
20644 (define_insn "*prefetch_3dnow"
20645   [(prefetch (match_operand:SI 0 "address_operand" "p")
20646              (match_operand:SI 1 "const_int_operand" "n")
20647              (const_int 3))]
20648   "TARGET_3DNOW && !TARGET_64BIT"
20649 {
20650   if (INTVAL (operands[1]) == 0)
20651     return "prefetch\t%a0";
20652   else
20653     return "prefetchw\t%a0";
20654 }
20655   [(set_attr "type" "mmx")
20656    (set_attr "memory" "none")])
20657
20658 (define_insn "*prefetch_3dnow_rex"
20659   [(prefetch (match_operand:DI 0 "address_operand" "p")
20660              (match_operand:SI 1 "const_int_operand" "n")
20661              (const_int 3))]
20662   "TARGET_3DNOW && TARGET_64BIT"
20663 {
20664   if (INTVAL (operands[1]) == 0)
20665     return "prefetch\t%a0";
20666   else
20667     return "prefetchw\t%a0";
20668 }
20669   [(set_attr "type" "mmx")
20670    (set_attr "memory" "none")])
20671
20672 (define_expand "stack_protect_set"
20673   [(match_operand 0 "memory_operand" "")
20674    (match_operand 1 "memory_operand" "")]
20675   ""
20676 {
20677 #ifdef TARGET_THREAD_SSP_OFFSET
20678   if (TARGET_64BIT)
20679     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20680                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20681   else
20682     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20683                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20684 #else
20685   if (TARGET_64BIT)
20686     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20687   else
20688     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20689 #endif
20690   DONE;
20691 })
20692
20693 (define_insn "stack_protect_set_si"
20694   [(set (match_operand:SI 0 "memory_operand" "=m")
20695         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20696    (set (match_scratch:SI 2 "=&r") (const_int 0))
20697    (clobber (reg:CC FLAGS_REG))]
20698   ""
20699   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20700   [(set_attr "type" "multi")])
20701
20702 (define_insn "stack_protect_set_di"
20703   [(set (match_operand:DI 0 "memory_operand" "=m")
20704         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20705    (set (match_scratch:DI 2 "=&r") (const_int 0))
20706    (clobber (reg:CC FLAGS_REG))]
20707   "TARGET_64BIT"
20708   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20709   [(set_attr "type" "multi")])
20710
20711 (define_insn "stack_tls_protect_set_si"
20712   [(set (match_operand:SI 0 "memory_operand" "=m")
20713         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20714    (set (match_scratch:SI 2 "=&r") (const_int 0))
20715    (clobber (reg:CC FLAGS_REG))]
20716   ""
20717   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20718   [(set_attr "type" "multi")])
20719
20720 (define_insn "stack_tls_protect_set_di"
20721   [(set (match_operand:DI 0 "memory_operand" "=m")
20722         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20723    (set (match_scratch:DI 2 "=&r") (const_int 0))
20724    (clobber (reg:CC FLAGS_REG))]
20725   "TARGET_64BIT"
20726   {
20727      /* The kernel uses a different segment register for performance reasons; a
20728         system call would not have to trash the userspace segment register,
20729         which would be expensive */
20730      if (ix86_cmodel != CM_KERNEL)
20731         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20732      else
20733         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20734   }
20735   [(set_attr "type" "multi")])
20736
20737 (define_expand "stack_protect_test"
20738   [(match_operand 0 "memory_operand" "")
20739    (match_operand 1 "memory_operand" "")
20740    (match_operand 2 "" "")]
20741   ""
20742 {
20743   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20744   ix86_compare_op0 = operands[0];
20745   ix86_compare_op1 = operands[1];
20746   ix86_compare_emitted = flags;
20747
20748 #ifdef TARGET_THREAD_SSP_OFFSET
20749   if (TARGET_64BIT)
20750     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20751                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20752   else
20753     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20754                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20755 #else
20756   if (TARGET_64BIT)
20757     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20758   else
20759     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20760 #endif
20761   emit_jump_insn (gen_beq (operands[2]));
20762   DONE;
20763 })
20764
20765 (define_insn "stack_protect_test_si"
20766   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20767         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20768                      (match_operand:SI 2 "memory_operand" "m")]
20769                     UNSPEC_SP_TEST))
20770    (clobber (match_scratch:SI 3 "=&r"))]
20771   ""
20772   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20773   [(set_attr "type" "multi")])
20774
20775 (define_insn "stack_protect_test_di"
20776   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20777         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20778                      (match_operand:DI 2 "memory_operand" "m")]
20779                     UNSPEC_SP_TEST))
20780    (clobber (match_scratch:DI 3 "=&r"))]
20781   "TARGET_64BIT"
20782   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20783   [(set_attr "type" "multi")])
20784
20785 (define_insn "stack_tls_protect_test_si"
20786   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20787         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20788                      (match_operand:SI 2 "const_int_operand" "i")]
20789                     UNSPEC_SP_TLS_TEST))
20790    (clobber (match_scratch:SI 3 "=r"))]
20791   ""
20792   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20793   [(set_attr "type" "multi")])
20794
20795 (define_insn "stack_tls_protect_test_di"
20796   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20797         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20798                      (match_operand:DI 2 "const_int_operand" "i")]
20799                     UNSPEC_SP_TLS_TEST))
20800    (clobber (match_scratch:DI 3 "=r"))]
20801   "TARGET_64BIT"
20802   {
20803      /* The kernel uses a different segment register for performance reasons; a
20804         system call would not have to trash the userspace segment register,
20805         which would be expensive */
20806      if (ix86_cmodel != CM_KERNEL)
20807         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20808      else
20809         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20810   }
20811   [(set_attr "type" "multi")])
20812
20813 (include "mmx.md")
20814 (include "sse.md")
20815 (include "sync.md")